CSS

Donnez du style à vos listes d'éléments

Article par (Intégrateur du Dimanche, Strasbourg)
Créé le , mis à jour le (127724 lectures)
Tags : css, liste, content, before, puces

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 :

list-style-type

  • Les valeurs de glyphes sont disc, circle et square.
  • 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 que background-position: 0 3px; ou encore background-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 :

li:before

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;		
}

li:before 2

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 :

une liste décorée

… Ou même un calendrier !

un calendrier en CSS

Source : http://goetter.fr/lab/css3/calendar/

Commentaires

Olliewood a dit le

très intéressant.. habituée au background-image, je vais tester le li:before dès mon prochain projet web!

doingenia a dit le

Oui effectivement très intéressant. Merci pour l'info

lix a dit le

Excellent tout ça merci !

ClementRoy a dit le

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é.

Gili a dit le

Waw, jamais entendu parler des propriétés counter-reset et counter-increment mais les possibilités offertes sont plutôt bluffantes

HyWaN a dit le

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 ;-).

Nemesys a dit le

Il est énorme le calendrier!

C'est volontaire le choix du mois de Juin avec une seule date "à retenir"?

LittleMowgli a dit le

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...

syndrael a dit le

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.

Raphael a dit le

@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é.

Leimi a dit le

@LittleMowgli & @Raphael : Sur 456bereastreet c'est Roger Johansson et non Chris Coyier si je ne m'abuse ;)

LittleMowgli a dit le

@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 ;)

fvsch a dit le

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.

davin_asga a dit le

Vraiment sympa surtout le before que je ne connassait pas !

scott54 a dit le

le lien en dessous du calendrier est bloqué par avast qui y voit un cheval de troie

scott54 a dit le

ce lien est aussi reconnu comme abritant un cheval de troie :
http://www.alsacreations.com/xmedia/tuto/exem...

Raphael a dit le

@scott54 : merci, on est dessus.

Aedonya a dit le

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 ?

Felipe a dit le

@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.

Etix a dit le

Super article !

Le CSS (dans toutes ces versions) est vraiment un outil passionnant et qui réserve de nombreuses surprises très utiles !

Merci !

jmlapam a dit le

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 ?

Raphael a dit le

@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.