Langues

Ceci est une traduction. Elle peut avoir des erreurs ou être dépassée par rapport à la version anglaise. Traducteur(-trice): Anne-Marie Luigi

Conseils & astuces CSS pour Web Style Sheets

Voir aussi l'index de tous les conseils.

Menu déroulant

La page 'Menus fixes' montre comment faire un menu qui reste au même endroit au bord de la fenêtre, même si le reste de la page défile. Nous pouvons rendre ce menu plus intéressant en le faisant se replier lorsqu'il n'est pas utilisé.

Le menu à droite de cette page ne s'affiche que sous la forme d'un petit onglet vert, jusqu'à ce que vous déplaciez le pointeur de la souris (ou cliquiez dessus avec un écran tactile), puis il s'ouvre pour afficher le texte qu'il contient.

Pour rendre le déroulement plus agréable, une courte transition de seulement 0,2 secondes permet au menu de glisser doucement à partir de la droite.

Lorsque l'espace est limité, comme sur le petit écran d'un téléphone portable, il peut être particulièrement utile de masquer partiellement un menu. (D'un autre côté, cela ralentit aussi les gens : ils ne peuvent pas voir tout de suite quelles sont les options disponibles, mais ils doivent d'abord déplacer leur souris ou leur doigt vers un endroit spécifique assez petit sur l'écran.)

Détails

Notre menu est juste une liste UL et ressemble à ceci :

<ul id=menu>
<li><a href="#sliding">A sliding menu</a>
<li><a href="#details">Details</a>
<li><a href="#a11n">Accessibility</a>
<li><a href="#misc">Menus of unknown size</a>
</ul>

Voici ci-dessous la partie essentielle de la feuille de style. Voir la page 'Menus fixes' pour des explications. Par souci de concision, nous avons omis la bordure, l'ombre et les coins arrondis. Vous pouvez voir les règles de style manquantes en regardant la source de cette page.

#menu {
  position: fixed;
  right: -8.5em;
  top: 50%;
  width: 8em;
  background: hsla(80, 90%, 40%, 0.7);
  color: white;
  margin: -3em 0 0 0;
  padding: 0.5em 0.5em 0.5em 2.5em;
}

La différence avec le menu fixe précédent est que la propriété 'right' n'est pas 0, mais -8.5em. De ce fait, la plupart des menus sont à l'extérieur de la fenêtre et donc invisibles. Notez que le menu, padding compris, est large de 11em (8em + 0.5em + 2.5em), il reste donc 2.5em visible.

La seule chose que nous devons ajouter maintenant est une règle pour réinitialiser la 'droite' à 0 ​​quand le menu est survolé :

#menu:hover { right: 0 }

Avec ces règles, le menu se déplace d'avant en arrière lorsque la souris entre et quitte le menu. Nous aurions voulu que cela glisse sans heurts vers l'intérieur et vers l'extérieur. Cela nécessite une règle de plus : une propriété 'transition' pour ralentir la transition, dans notre cas à 0,2 seconde :

#menu {transition: 0.2s}

Par défaut, une transition démarre lentement, accélère un peu puis ralentit progressivement. De nombreuses autres possibilités peuvent être sélectionnées en ajoutant des mots-clés supplémentaires à la propriété 'transition' mais pour cet exemple, la valeur par défaut est suffisante.

Accessibilité

Malheureusement, il y a un problème d'accessibilité avec notre menu déroulant : lorsque quelqu'un essaie de naviguer sur la page avec le clavier, sans souris ni écran tactile, il n'y a aucun moyen de rendre le menu visible.

Nous aimerions que le menu glisse lorsque l'un de ses éléments reçoit le focus du clavier, mais c'est impossible. Il n'y a actuellement (en 2017) aucun sélecteur CSS capable de sélectionner un élément lorsque l'un de ses enfants obtient le focus. (Il y aura peut-être de tels sélecteurs dans le futur.) Nous pouvons, cependant, faire glisser les éléments du menu eux-mêmes.

Ce n'est pas aussi élégant, mais ça marche. Essayez ! Appuyez plusieurs fois sur la touche de tabulation (ou ctrl+↓ ou ⌘+↓ sur Opera jusqu'à la version 12) pour sélectionner tour à tour chaque lien sur cette page et observez comment les éléments du menu glissent un par un.

Pour ce faire, il faut relativement bien positionner les liens et ajouter une propriété 'gauche' pour les déplacer vers la gauche, lorsqu'ils ont le focus. Il faut également leur donner la couleur de fond du menu :

#menu a {
  position: relative;
  left: 0;
}
#menu a:focus {
  left: -7em;
  background: hsla(80, 90%, 40%, 0.7);
}

Pour le faire glisser en douceur, au lieu de simplement surgir, nous utilisons à nouveau une transition :

#menu a { transition: 0.2s }

C'est grâce à cette transition douce que nous mettons explicitement la 'gauche' à 0 : La valeur par défaut est 'auto', mais la propriété 'left' ne peut animer qu'entre les nombres.

Et enfin, comme il est possible qu'un élément de menu ait le focus en même temps que la souris survole le menu, nous nous assurons que l'élément menu ne puisse pas glisser dans cette situation :

#menu:hover a:focus {
  left: 0;
  background: none;
}

Menus de taille inconnue

Notre menu contient quatre éléments et un peu de padding, il est donc facile de le centrer verticalement : chaque ligne est à environ 1.3em (nous aurions pu définir la 'line-height' explicitement, si nous voulions être sûrs) et le padding est 1em, ce qui fait environ 6.2em total, donc une marge supérieure de -3em déplace le menu d'environ la moitié de sa hauteur. Mais que faire si nous ne savons pas combien il y a de lignes dans le menu ?

La section ‘Centering vertically in CSS level 3’ sur la page ‘Centering things’ indique comment centrer l'élément verticalement. L'exemple ici utilise le positionnement absolu, mais la même idée peut être appliquée au positionnement fixe.

Nous allons devoir supprimer la marge supérieure négative (-3em) et la mettre à 0 à la place. Et nous utilisons la propriété 'transform' avec une translation qui déplace l'élément de la moitié (50 %) de sa propre hauteur :

#menu {
  margin: 0;
  transform: translate(0, -50%);
}

Par contre assurez-vous de ne l'utiliser que pour des menus assez courts. Le menu sera aussi haut qu'il doit l'être et s'il est plus haut que la fenêtre, le haut et le bas seront tronqués sans possibilité de les faire défiler.

Les anciens navigateurs peuvent ne pas connaître la propriété 'transform', il est donc judicieux de conserver également la marge supérieure négative avec la moitié de la hauteur estimée du menu. Ici, la règle '@support' est pratique. Elle permet de s'assurer que 'margin-top : 0' est seulement appliqué par les navigateurs qui comprennent 'transform' :

#menu { margin: -3em 0 0 0 }
@supports (transform: translate(0, -50%)) {
  #menu {
    margin-top: 0;
    transform: translate(0, -50%);
  }
}

Et voilà ! Bien sûr, vous pouvez aussi faire des menus qui glissent par le haut ou le bas de la fenêtre, ou bien de n'importe où (derrière un autre élément, par exemple), mais nous laissons cela de côté pour en faire un exercice.

Bert Bos, coordinateur de l'activité style
Copyright © 1994–2018 W3C®

Created 24 February 2017;
Last updated mer. 23 mai 2018 14:18:33 UTC

Langues

À propos des traductions