Les listes sont très souvent utilisées pour réaliser des menus de tous types : verticaux, horizontaux, dynamiques, à un ou plusieurs niveaux, etc.

### Menus à un seul niveau

Les menus les plus simples à réaliser sont les menus à un seul niveau car ils nécessitent l'utilisation d'une seule liste.

#### Menu vertical

Un menu vertical est réalisé dans problème en gardant la disposition normale d'une liste.

Exemple : menu vertical
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Les CSS</title> <link href="styles.css" rel="stylesheet"> </head> <body> <ul class="menu-vertical"> <li><a href="p1.html">Yoda</a></li> <li><a href="p2.html">Luke</a></li> <li><a href="p3.html">Palpatine</a></li> <li><a href="p4.html">Vador</a></li> </ul> </body> </html>
Fichier CSS : styles.css
.menu-vertical { margin: 0; padding: 5px 0 5px 30px; list-style: url(../exemples/img/star.png); width: 100px; border-radius: 5px; border: 1px solid; } .menu-vertical a { text-decoration: none; color: black; }

#### Toute la ligne cliquable

Le menu de l'exemple précédent peut être amélioré en rendant toute la ligne de la liste cliquable, et pas seulement le lien.
L'astuce consiste à forcer l'affichage des liens a comme si c'était des éléments de type bloc. On utilise la propriété display avec la valeur `block`.
Pour que les puces de la liste soient aussi cliquables, il faut les enlever des lignes et les mettre par exemple comme image de fond non répétée des liens. En procédant ainsi plutôt que d'ajouter les images dans le code HTML, on rend les modifications bien plus faciles à faire car il suffira de changer une ligne de la feuille de style si on veut changer la pluce, plutôt que reprendre toutes les pages du site qui utiliseraient le menu.

Exemple : menu vertical ligne cliquable
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Les CSS</title> <link href="styles.css" rel="stylesheet"> </head> <body> <ul class="menu-vertical"> <li><a href="p1.html">Yoda</a></li> <li><a href="p2.html">Luke</a></li> <li><a href="p3.html">Palpatine</a></li> <li><a href="p4.html">Vador</a></li> </ul> </body> </html>
Fichier CSS : styles.css
.menu-vertical { margin: 0; padding: 5px; width: 100px; list-style: none; border-radius: 5px; border: 1px solid; } .menu-vertical a { display: block; background: url(../exemples/img/star.png) no-repeat; padding-left: 20px; text-decoration: none; color: black; } .menu-vertical a:hover { background-color: lightcyan; }

#### Réaliser un menu vertical

menu à réaliser
ligne au survol de la souris

Complétez le code CSS pour obtenir le menu ci-contre.

La couleur de fond du menu est `#0A0D0A` et il est entouré par une ombre de 2 pixels avec 2 pixels de renfort, jaune avec une transparence de 0.7. La couleur des liens est `#6d6d00`. Au survol de la souris, les liens deviennent `yellow` et sont entourés avec la même ombre que le menu.

Toutes les images se trouvent dans le répertoire `../exemple/img/`
L'image de fond de page s'appelle `etoiles.jpg`, la puce du menu s'appelle `starv.png` et quand elle est survolée par la souris `starj.png`.

Code à compléter

Une solution possible

#### Menu horizontal

Pour réaliser un menu horizontal, la solution qui offre le plus de liberté est de faire flotter les lignes de la liste avec la propriété float, valeur `left` (généralement) ou `right` (plus rarement).

Comme les lignes sont flottantes, elles sortent du flux normal et ne sont pas prises en compte pour le calcul de la hauteur de leur conteneur (l'élément ul) qui se retrouve donc avec une valeur de 0 et ne peut pas être éventuellement stylé. Pour résoudre ce problème il y a 2 solutions :

- on peut utiliser la propriété overflow avec la valeur `auto` sur l'élément ul. Cette solution est adéquate pour un menu à un seul niveau.
- dans le cas d'un menu à plusieurs niveaux, il faut plutôt donner une hauteur à l'élément ul avec la propriété height. On évitera ainsi des effets non désirés lors de l'affichage dynamique des sous-niveaux.

Exemple : menu horizontal
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Les CSS</title> <link href="styles.css" rel="stylesheet"> </head> <body> <ul class="menu-horizontal"> <li><a href="p1.html">Yoda</a></li> <li><a href="p2.html">Luke</a></li> <li><a href="p3.html">Palpatine</a></li> <li><a href="p4.html">Vador</a></li> </ul> </body> </html>
Fichier CSS : styles.css
.menu-horizontal { margin: 0; padding: 5px; list-style: none; border-radius: 10px; border: 1px solid; overflow: auto; background: #808080; } .menu-horizontal li { float: left; /* ligne flottante pour avoir un menu horizontal */ width: 90px; } /* Le lien a l'apparence d'un bouton */ .menu-horizontal a { display: block; text-decoration: none; color: white; text-align: center; padding: 4px; margin-right: 10px; border: 1px solid #555; border-radius: 5px; background: linear-gradient(#b0b0b0, #808080); } .menu-horizontal a:hover { background: linear-gradient(#f2ebd2, #fbdb6d); color: black; }

#### Réaliser un menu horizontal

Complétez le code CSS pour obtenir le menu ci-dessous.

menu à réaliser

La page a une image de fond : `../exemple/img/etoiles.jpg`.

La barre de menu a une hauteur de 60 pixels et la police est Verdana ou Geneva ou sans-serif, à la taille de 15 pixels.
Le fond est un dégradé linéaire qui commence par la couleur `#AEBCBF` et se termine par `#0A0809`. Il y a 2 autres points d'arrêt : `#6E7774` à 45% et `#0A0E0A` à 65%.

Les lignes ont une largeur de 130 pixels et sont séparées par un espace de 10 pixels.

Les liens ont une hauteur de 40 pixels avec une marge intérieure de 4 pixels et sont blancs.
Au survol de la souris ils deviennent `yellow` et sont entourés par une ombre de 2 pixels avec 2 pixels de renfort, jaune avec une transparence de 0.7. Le fond du lien est noir avec une transparence de 0.2.

ligne au survol de la souris

Code à compléter

Une solution possible

### Menus à plusieurs niveaux

#### Principes de fonctionnement

Pour réaliser la structure d'un menu à plusieurs niveaux, une solution simple est d'utiliser des listes imbriquées. Généralement le 1er niveau est fait avec une liste horizontale et les niveaux suivants (sous-niveaux) aves des listes verticales.

un menu à 2 niveaux

Les listes des sous-niveaux sont cachées par défaut avec la propriété display à laquelle on donne la valeur `none`.
La passage de la souris sur une ligne change la valeur de la propriété pour `block` ce qui la rend visible.

Les sélecteurs à utiliser sont un peu plus complexes que ceux des listes à un seul niveau car il faut cibler uniquement les enfants directs d'un élément ul ou li et non pas tous les descendants.
On utilise pour cela le combinateur > comme nous l'avons vu dans Sélectionner ▸ Sélecteur d'enfants

L'exemple suivant montre la réalisation d'un menu à 2 niveaux avec les principes décrits. On remarquera que les éléments de 1er niveau sont créés avec des liens a, même si ce ne sont pas des liens réels ( l'attribut `href` est une ancre interne "inexistante" qui pointera de la sorte sur le début de la page). En utilisant ces sortes de liens, il est plus facile de styler le menu (et en particulier quand il y a plus de 2 niveaux).

Exemple : menu horizontal
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Les CSS</title> <link href="styles.css" rel="stylesheet"> </head> <body> <ul class="menu-horizontal"> <li><a href="#">Personnages &dtrif;</a> <ul class="menu-vertical"> <li><a href="p1.html">Yoda</a></li> <li><a href="p2.html">Luke</a></li> <li><a href="p3.html">Palpatine</a></li> <li><a href="p4.html">Vador</a></li> </ul> </li> <li><a href="#">Vaisseaux &dtrif; <ul class="menu-vertical"></a> <li><a href="v1.html">A Wing</a></li> <li><a href="v2.html">B Wing</a></li> <li><a href="v3.html">X Wing</a></li> </ul> </li> </ul> </body> </html>
Fichier CSS : styles.css
/* propiétés communnes aux menus */ .menu-horizontal, .menu-vertical { margin: 0; padding: 5px; list-style: none; background: white; border-radius: 10px; border: 1px solid; } .menu-horizontal { height: 2em; line-height: 2em; } /* tous les liens (enfants et descendants) */ .menu-horizontal a { display: block; text-decoration: none; color: black; } /* sélecteur d'enfant : uniquement les lignes du menu horizontal et pas celles des autres listes imbriquées */ .menu-horizontal > li { float: left; margin: 0 5px; width: 100px; } /* au survol de la souris sur une ligne 1er niveau on affiche le sous-menu correspondant */ .menu-horizontal > li:hover .menu-vertical { display: block; } /* les sous-menus sont cachés par défaut */ .menu-vertical { display: none; } /* survol des liens sous-menus */ .menu-vertical a:hover { text-decoration: underline; }

Si on voulait positionner plus précisément les sous-menus, il faudrait apporter les modifications suivantes :

- la ligne conteneur d'un sous-menu devrait être positionnée avec `position: relative` pour que le sous-menu la prenne comme position de référence,
- le sous-menu devrait être positionné avec `position: absolute` et on devrait lui donner une largeur,
- la position du sous-menu devrait être définie pas les propriétés top et/ou bottom et/ou left et/ou right

Avec l'exemple précédent on pourrait avoir quelque chose comme :

    .menu-horizontal > li {
    	float: left;
    	margin: 0 5px;
    	width: 100px;
    	position: relative;
    }
    .menu-vertical {
    	display: none;
    	position: absolute;
    	left: -10px;
    	top: 1.5em;
    	width: 100px;
    }

#### Menu à 3 niveaux

Complétez le code HTML et le code CSS pour obtenir le menu à 3 niveaux ci-dessous.

menu niveau 1
menu niveau 2
1er menu niveau 3
2éme menu niveau 3

La page a une image de fond : `../exemple/img/etoiles.jpg`.

Menu de niveau 1

La barre de menu a une hauteur de 60 pixels et la police est Verdana ou Geneva ou sans-serif, à la taille de 15 pixels.
Le fond est un dégradé linéaire qui commence par la couleur `#AEBCBF` et se termine par `#0A0809`. Il y a 2 autres points d'arrêt : `#6E7774` à 45% et `#0A0E0A` à 65%.

Les lignes ont une largeur de 130 pixels et sont séparées par un espace de 10 pixels.

Les liens ont une hauteur de 40 pixels avec une marge intérieure de 4 pixels et sont blancs.
Au survol de la souris ils deviennent `yellow` et sont entourés par une ombre de 2 pixels avec 2 pixels de renfort, jaune avec une transparence de 0.5. Le fond du lien est noir avec une transparence de 0.2.

Menu de niveaux 2 et 3

Les menus de niveaux 2 et 3 ont une fond de couleur `#0A0D0A`. Ils ont une largeur de 150 pixels et des marges internes verticales de 5 pixels et horizontales de 10 pixels. Ils sont entourés par par une ombre de 2 pixels avec 2 pixels de renfort, jaune avec une transparence de 0.5.

Au survol de la souris les liens deviennent `yellow` et leur fond devient noir avec une transparence de 0.2.

Conseil

Commencez déjà par la mise en place des listes, puis par le fonctionnement de l'affichage des différents niveaux de menu. Quand la gestion des survols et des affichages est correcte, stylez plus précisément les éléments avec les couleurs, marges, ombres, etc.

Code à compléter

Une solution possible