Modifier ou designer les puces des éléments de liste n'est pas forcément un exercice de tout repos : nous avons souvent recours aux images de fond bien que d'autres techniques, plus simples à maintenir, mais moins connues, existent.
Faisons le tour des méthodes utilisables aujourd'hui, avec leurs avantages et inconvénients.
Viens découvrir mon <li>
Que savons-nous exactement de l'élément <li>
?
Sa fonction, selon les spécifications HTML, est de structurer un élément d'une liste ordonnée (dont l'ordre est pertinent) ou non ordonnée (dont l'ordre importe peu). Son parent direct est soit un élément <ul>
(liste non ordonnée), soit un <ol>
(liste ordonnée), et réciproquement les <ul>
et <ol>
ne peuvent contenir directement que des éléments <li>
(pas de conteneur intermédiaire). Dans la spécification HTML5 <menu>
est un parent possible de <li>
.
En terme d'affichage - donc de rendu CSS par défaut - les éléments <li>
ressemblent fortement à des éléments de type block
tout en bénéficiant de particularités. Et pour cause, leur valeur de display
par défaut n'est pas block
mais list-item
.
Les caractéristiques des éléments list-item
sont :
- se placent toujours l'un en dessous de l'autre par défaut (comme un retour chariot),
- occupent automatiquement, par défaut, toute la largeur disponible dans leur parent,
-
peuvent être dimensionnés à l'aide des propriétés telles que
width
,height
,min-width
,min-height
,... -
peuvent bénéficier des propriétés CSS liées aux puces (
list-style
,list-style-type
,list-style-image
,list-style-position
, …)
N'hésitez pas à en découvrir plus sur les différents types d'affichage par défaut.
Dans la pratique, il est possible d'assigner n'importe quelle valeur de display
à n'importe quel élément HTML : ainsi, une liste peut s'afficher horizontalement si ses éléments <li>
sont rendus en display: inline
. De même un paragraphe peut disposer de puces s'il est affiché en display: list-item
.
Les basiques : list-style
Les propriétés list-style-type
et list-style-image
existent depuis la version initiale de CSS, en 1996. Elles permettent de modifier le visuel de la puce associée aux éléments de liste <li>
.
list-style-type
La propriété list-style-type définit l'aspect de la puce sous forme graphique (glyphe) ou numérique pour les listes numérotées :
-
Les valeurs de glyphes sont
disc
,circle
etsquare
. -
Les valeurs pour les systèmes de numérotation sont :
decimal
,lower-roman
,upper-roman
,hebrew
,armenian
,katakana
, etc. -
La valeur supprimant la puce est
none
.
Vous en conviendrez avec moi : les options graphiques sont plutôt restreintes et les choix sont vite faits.
list-style-image
La propriété list-style-image offre la possibilité de remplacer la puce classique par une image dont vous aurez indiqué le chemin.
Là encore, le périmètre créatif se révèle limité, notamment parce qu'il n'est pas vraiment possible de positionner l'image précisément (même avec list-style-position
), il faut généralement retailler ou redimensionner l'image.
L'image de fond : background-image
À l'instar de n'importe quel élément HTML, les items de liste ont la faculté de pouvoir disposer d'image d'arrière-plan grâce à la propriété background-image
.
Il est ainsi possible de remplacer la puce initiale par l'image de son choix :
li {
list-style-type: none; /* on annule la puce par défaut */
background-image: url(image.png); /* on affiche l'image souhaitée */
background-repeat: no-repeat; /* on annule la répétition par défaut */
background-position: left center; /* on positionne où l'on veut */
padding-left: 20px; /* pour éviter la superposition du contenu */
}
Cette méthode présente certains atouts mais également des faiblesses par rapport à l'usage de list-style-image
:
- L'inconvénient principal est que si l'image de fond est plus haute que le contenu de la puce, une partie sera masquée. Il faut donc prévoir à l'avance la hauteur minimale de la puce.
- Le second désavantage est la suppression d'un marquer visuel (la puce) par une image, qui peut très bien être masquée volontairement par l'utilisateur.
-
L'avantage est que
background-position
permet de placer l'image de fond au pixel près, puisque rien n'empêche des déclarations telles quebackground-position: 0 3px;
ou encorebackground-position: 5% 10%;
Génération de contenu avec :before
Passons à présent à un autre registre, moins souvent exploré et pourtant bien plus vaste : la génération de puces avec le pseudo-élément CSS :before
.
Introduit en CSS2 (mais malheureusement reconnu qu'à partir d'Internet Explorer 8), :before
permet de générer du contenu avant un élément. Ce contenu peut être une chaîne de caractère, une image de fond ou une valeur d'attribut.
Les éléments de liste sont un cobaye parfait pour ce genre d'outil, à condition de prévoir une alternative pour les anciennes versions d'Internet Explorer.
Listes non ordonnées (<ul>)
La génération de contenu en CSS passe obligatoirement par une combinaison de :before
(ou :after
) et de la propriété content
; l'un ne va pas sans l'autre :
li {list-style-type: none;}
li:before {
content: "- "; /* on affiche une chaîne de caractère */
}
Certains caractères complexes ou exotiques peuvent être définis d'une manière plus particulière et fondée sur le code ISO 10646 (hexadécimal) que vous pouvez trouver par exemple sur ce site : http://ascii.cl/htmlcodes.htm :
li:before {
content: "\A4 \ "; /* caractère ISO 10646 */
}
Cependant, dans la plupart des cas - et notamment si votre encodage est en UTF-8 - il est parfaitement possible d'écrire directement le caractère (copier/coller) sans passer par des artifices ou des encodages barbares :
li:before {
content: "→ "; /* caractère UTF-8 */
}
Enfantin, n'est-ce pas ? Voici le résultat :
Listes ordonnées (<ol>)
Le cas des listes ordonnées est quelque peu particulier, notamment parce qu'il est nécessaire de disposer d'une puce différente (numérotée ou non) pour chaque élément de liste : difficile de s'en sortir avec des images de fond, par exemple.
Pour les listes ordonnées, les spécifications CSS 2.1 prévoient la possibilité d'employer des compteurs automatiques et personnalisables : le couple counter-reset
et counter-increment
.
ol {counter-reset: repas;} /* on initialise et nomme un compteur */
li {
list-style-type: none;
counter-increment: repas; /* on incrémente le compteur à chaque nouveau li */
margin-bottom: 10px;
}
li:before {
content: counter(repas); /* on affiche le compteur */
padding: 0 20px 6px;
margin-right: 8px;
vertical-align: top;
background: #678;
-moz-border-radius: 60px;
border-radius: 60px;
font-weight: bold;
font-size: 0.8em;
color: white;
}
Les exemples d'usage des compteurs peuvent se révéler nombreux et variés, par exemple une liste de tâches entièrement stylée en CSS :
… Ou même un calendrier !
Source : http://goetter.fr/lab/css3/calendar/
Commentaires
très intéressant.. habituée au background-image, je vais tester le li:before dès mon prochain projet web!
Oui effectivement très intéressant. Merci pour l'info
Excellent tout ça merci !
C'est vraiment le 15 juin ton anniversaire ?
Quoiqu'il en soit, les pseudos éléments :before et :after sont très puissant, il faut juste faire attention de ne pas mal utiliser la génération de contenu via le style. En l’occurrence ici le fallback est bien assuré.
Waw, jamais entendu parler des propriétés counter-reset et counter-increment mais les possibilités offertes sont plutôt bluffantes
Hey :-),
Le préfixe -moz- n'est plus nécessaire depuis Firefox4/Gecko2 : http://j.mp/mMVzod. Peut-être l'as-tu mis po... la compatibilité avec Firefox3.6 ? Dans tous les cas, -moz-border-radius n'est qu'un alias temporaire vers border-radius.
Belle astuce sinon ;-).
Il est énorme le calendrier!
C'est volontaire le choix du mois de Juin avec une seule date "à retenir"?
Ca sent un petit peu le repompage de Chris Coyier (http://www.456bereastreet.com/archive/201105/styling_ordered_list_numbers/), mais à part ça, bon article...
J'ai eu le même réflexe que LittleMowgli mais cet article a l'avantage de présenter les choses et les résultats avec des images un peu 'sexy'.. Une valeur ajoutée en qq sorte..
Merci en tout cas pour cet article.
S.
@LittleMowgli : tu n'as pas forcément tort :)
Pour tout dire, l'article était dans nos cartons depuis plusieurs mois (tu te doutes que nous n'avons pas conçu tous les exemples en une journée), mais l'article de Chris Coyier a été le déclencheur... même si je ne l'ai qu'à peine survolé.
@LittleMowgli & @Raphael : Sur 456bereastreet c'est Roger Johansson et non Chris Coyier si je ne m'abuse ;)
@Leimi : Effectivement ;) Le souci est que je lis les flux de CSS-Tricks (par Chris Coyier, donc). Ce dernier ayant fait un lien direct vers l'article, la confusion était facile ;)
J’avais un peu joué sur les contenus générés en CSS 2.1 (avec :before et :after) en travaillant sur ReMarkdown. Je laisse les curieux jeter un coup d’œil à la page de démo et au code.
La limite que j’ai rencontré, c’est l’impossibilité de supporter les attributs start et reversed de OL, et l'attribut value de LI.
Vraiment sympa surtout le before que je ne connassait pas !
le lien en dessous du calendrier est bloqué par avast qui y voit un cheval de troie
ce lien est aussi reconnu comme abritant un cheval de troie :
http://www.alsacreations.com/xmedia/tuto/exem...
@scott54 : merci, on est dessus.
Bonsoir à tous,
Super cet article, le css a des talents cachés ! Mais j'ai une question : ne pensez-vous pas que du coup l'attribut "content" remet en cause le principe de la séparation contenu/forme (HTML/CSS) voulu par le W3C ?
@Aedonya : ça dépend comment tu l'utilises, comme souvent. Il y a moyen de faire de pures horreurs niveau accessibilité (en y mettant de l'information qui n'apparaitra pas sans CSS et de toute façon pas aux lecteurs d'écran)
Ah sinon un calendrier du mois, c'est un tableau de 7 colonnes (lun-dim) et 5-6 lignes (les semaines). Une liste de 28-31 éléments sans par exemple pouvoir passer d'un mardi au(x) suivant(s), c'est moyen.
Super article !
Le CSS (dans toutes ces versions) est vraiment un outil passionnant et qui réserve de nombreuses surprises très utiles !
Merci !
Thx du tuyau mais toutes les ul et li auront ce style (le compteur), faut leur mettre des id a chaque fois pour les styler different ?
@jmlapam : je ne suis pas sûr d'avoir compris la question, mais il suffit d'identifier la liste que l'on veut styler en effet. Par exemple ol id="kiwi", tout simplement.