La liste ordonnée peut-elle produire un résultat qui ressemble à 1.1, 1.2, 1.3 (au lieu de seulement 1, 2, 3,…) avec css?

201

Une liste ordonnée peut-elle produire des résultats qui ressemblent à 1.1, 1.2, 1.3 (au lieu de seulement 1, 2, 3, ...) avec CSS? Jusqu'à présent, l'utilisation list-style-type:decimaln'a produit que 1, 2, 3, et non 1.1, 1.2., 1.3.

Richard77
la source
Je suggère de comparer la réponse acceptée avec celle de Jakub Jirutka. Je pense que ce dernier est encore mieux.
Frank Conijn
Solution élégante. Une idée pourquoi Wikipedia utilise un ul pour ses sections de contenu au lieu de cela?
Mattypants
1
@davnicwil J'accepte; On dirait que j'ai probablement appliqué le duplicata dans le mauvais ordre en septembre.
TylerH
Cool, maintenant je me sens mal à l'aise car cela ne m'est jamais venu à l'esprit que cela pourrait être une simple erreur comme ça - excuses!
davnicwil

Réponses:

290

Vous pouvez utiliser des compteurs pour ce faire:

La feuille de style suivante numérote les éléments de liste imbriqués comme "1", "1.1", "1.1.1", etc.

OL { counter-reset: item }
LI { display: block }
LI:before { content: counters(item, ".") " "; counter-increment: item }

Exemple

ol { counter-reset: item }
li{ display: block }
li:before { content: counters(item, ".") " "; counter-increment: item }
<ol>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
  <li>li element</li>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
</ol>

Voir Compteurs imbriqués et étendue pour plus d'informations.

Gombo
la source
2
très bonne réponse. Quel est le support pour cela?
Jason McCreary
1
@ Jason McCreary: Eh bien, c'est l'inconvénient: les compteurs ne sont pas pris en charge dans IE jusqu'à la version 8 .
Gumbo
3
Cette solution manque une toute petite chose: le point suivant le numéro d'article. Il ne ressemble pas au style de liste standard. Corrige en ajoutant un point à la règle pour li:before: content: counters(item, ".")". ";
LS
4
C'est une mauvaise réponse. Cela ne fonctionne pas correctement. Découvrez la réponse de Jakub Jirutka ci
M. Pablo
1
@Gumbo je sais, et la réponse de Jakub m'a donné la numérotation correcte.
M. Pablo
236

Aucune des solutions de cette page ne fonctionne correctement et universellement pour tous les niveaux et les longs paragraphes (enveloppés). Il est vraiment difficile d'obtenir une indentation cohérente en raison de la taille variable du marqueur (1., 1.2, 1.10, 1.10.5,…); il ne peut pas être «simulé», même avec une marge / un remplissage précalculé pour chaque niveau d'indentation possible.

J'ai finalement trouvé une solution qui fonctionne réellement et n'a pas besoin de JavaScript.

Il est testé sur Firefox 32, Chromium 37, IE 9 et le navigateur Android. Ne fonctionne pas sur IE 7 et versions antérieures.

CSS:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
}

ol > li {
  display: table;
  counter-increment: item;
  margin-bottom: 0.6em;
}

ol > li:before {
  content: counters(item, ".") ". ";
  display: table-cell;
  padding-right: 0.6em;    
}

li ol > li {
  margin: 0;
}

li ol > li:before {
  content: counters(item, ".") " ";
}

Exemple: Exemple

Essayez-le sur JSFiddle , bifurquez-le sur Gist .

Jakub Jirutka
la source
1
Bon travail pour réaliser ce type d'indentation. Je dirais néanmoins que les 2 premiers cas d'indentation que vous avez énumérés sont une question de préférence plutôt que de bien et de mal. Considérez le cas 1 et le cas 2 - ce dernier parvient à insérer beaucoup plus de niveaux avant que l'espacement ne devienne difficile, tout en ayant l'air plutôt soigné. En outre, MS Word et le style de navigateur par défaut utilisent tous deux le retrait du cas 2. Je suppose qu'ils le font aussi mal?
Saul Fautley
2
@ saul-fautley C'est faux en termes de typographie. Votre exemple avec un nombre insensé de niveaux imbriqués montre que la numérotation imbriquée ne convient pas à trop de niveaux, mais c'est assez évident. MS Words n'est pas un système de composition, c'est un simple processeur de documents avec une mauvaise typographie. Style de navigateur par défaut… oh, vous ne savez pas grand-chose sur la typographie, n'est-ce pas?
Jakub Jirutka
3
Cela fonctionne vraiment (techniquement) pour tous les niveaux et les longs paragraphes. S'il est raisonnable d'utiliser une douzaine de niveaux, c'est une autre question qui n'a rien à voir avec la solution technique. Le fait est que vous n'avez pas à prédéfinir une règle CSS pour chaque niveau d'imbrication comme avec certaines autres solutions.
Jakub Jirutka
4
Bien que je ne dirais pas qu'il y a quelque chose de intrinsèquement «mauvais» avec les autres réponses, je dirais qu'elles sont incomplètes. Cette réponse est parfaite et a même fonctionné dans un site au style horriblement bizarre que je modifie.
DanielM
2
@tremby: L'écart peut être résolu en utilisant li "display: table-row" au lieu de "display: table". Le problème que cela pose est que le li ne peut alors pas utiliser de marges / remplissages car les lignes de table sont toujours dimensionnées automatiquement par leur contenu. Cela peut être contourné en ajoutant un "li: after" avec "display: block". Voir jsFiddle pour un exemple complet. En prime, j'ai ajouté "text-align: right" à "li: before" pour aligner les chiffres à droite.
mmlr
64

La réponse choisie est un bon début, mais elle force essentiellement le list-style-position: inside;style sur les éléments de la liste, ce qui rend le texte enveloppé difficile à lire. Voici une solution de contournement simple qui permet également de contrôler la marge entre le nombre et le texte, et aligne à droite le nombre selon le comportement par défaut.

ol {
    counter-reset: item;
}
ol li {
    display: block;
    position: relative;
}
ol li:before {
    content: counters(item, ".")".";
    counter-increment: item;
    position: absolute;
    margin-right: 100%;
    right: 10px; /* space between number and text */
}

JSFiddle: http://jsfiddle.net/3J4Bu/

Saul Fautley
la source
Un inconvénient est qu'il ajoute un point à la fin de chaque élément de la liste.
Davin Studer
3
@Davin Studer: il ajoute seulement un point à la fin de chaque numéro, selon le olcomportement par défaut . Il peut facilement être supprimé en supprimant le dernier "."de la contentpropriété, mais cela me semble un peu étrange.
Saul Fautley
14

Les solutions publiées ici ne fonctionnaient pas bien pour moi, j'ai donc fait un mélange de celles de cette question et de la question suivante: Est-il possible de créer une liste ordonnée à plusieurs niveaux en HTML?

/* Numbered lists like 1, 1.1, 2.2.1... */
ol li {display:block;} /* hide original list counter */
ol > li:first-child {counter-reset: item;} /* reset counter */
ol > li {counter-increment: item; position: relative;} /* increment counter */
ol > li:before {content:counters(item, ".") ". "; position: absolute; margin-right: 100%; right: 10px;} /* print counter */

Résultat:

capture d'écran

Remarque: la capture d'écran, si vous souhaitez voir le code source ou quoi que ce soit de cet article: http://estiloasertivo.blogspot.com.es/2014/08/introduccion-running-lean-y-lean.html

chelder
la source
1
C'est la meilleure (et la plus simple) réponse de travail de la page entière.
Bruno Toffolo
6

Remarque: Utilisez CSS pour créer une numérotation imbriquée dans un navigateur moderne. Voir la réponse acceptée. Ce qui suit est à titre historique seulement.counters


Si le navigateur prend en charge contentet counter,

.foo {
  counter-reset: foo;
}
.foo li {
  list-style-type: none;
}
.foo li::before {
  counter-increment: foo;
  content: "1." counter(foo) " ";
}
<ol class="foo">
  <li>uno</li>
  <li>dos</li>
  <li>tres</li>
  <li>cuatro</li>
</ol>

kennytm
la source
Cette solution échoue horriblement lorsque les listes sont imbriquées.
LS
@LS Vous pouvez toujours adapter les sélecteurs à vos besoins. .foo > ol > li.
kennytm
1
Mon point est que vous avez codé en dur "1". dans le style. Que se passe-t-il lorsque la sous-liste est un enfant du deuxième élément de la liste des parents? Vous voulez qu'il apparaisse comme "2.", mais ce sera toujours "1." à cause de la façon dont il est codé ici. Quelle est la solution? Faire de nouveaux ensembles de styles pour chaque nombre possible? Non. Utilisez la counters()fonction comme dans les exemples ci-dessus au lieu de la counter()fonction.
LS
2
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="author" content="Sandro Alvares - KingRider">
    </head>
    <body>
        <style type="text/css">
            li.title { 
                font-size: 20px; 
                font-weight: lighter; 
                padding: 15px; 
                counter-increment: ordem; 
            }
            .foo { 
                counter-reset: foo; 
                padding-left: 15px; 
            }
            .foo li { 
                list-style-type: none; 
            }
            .foo li:before { 
                counter-increment: foo; 
                content: counter(ordem) "." counter(foo) " "; 
            }
        </style>
        <ol>
            <li class="title">TITLE ONE</li>
            <ol class="foo">
                <li>text 1 one</li>
                <li>text 1 two</li>
                <li>text 1 three</li>
                <li>text 1 four</li>
            </ol>
            <li class="title">TITLE TWO</li>
            <ol class="foo">
                <li>text 2 one</li>
                <li>text 2 two</li>
                <li>text 2 three</li>
                <li>text 2 four</li>
            </ol>
            <li class="title">TITLE THREE</li>
            <ol class="foo">
                <li>text 3 one</li>
                <li>text 3 two</li>
                <li>text 3 three</li>
                <li>text 3 four</li>
            </ol>
        </ol>
    </body>
</html>

Résultat: http://i.stack.imgur.com/78bN8.jpg

KingRider
la source
2

J'ai un problème quand il y a deux listes et que la seconde est à l'intérieur de DIV La deuxième liste devrait commencer à 1. pas 2.1

<ol>
    <li>lorem</li>
    <li>lorem ipsum</li>
</ol>

<div>
    <ol>
        <li>lorem (should be 1.)</li>
        <li>lorem ipsum ( should be 2.)</li>
    </ol>
</div>

http://jsfiddle.net/3J4Bu/364/

EDIT: J'ai résolu le problème par ce http://jsfiddle.net/hy5f6161/

robertad
la source
1

Dans un avenir proche, vous pourrez peut-être utiliser l' ::markerélément pseudo pour obtenir le même résultat que d'autres solutions dans une seule ligne de code.

N'oubliez pas de vérifier le tableau de compatibilité du navigateur car il s'agit toujours d'une technologie expérimentale. Au moment de la rédaction, seuls Firefox et Firefox pour Android, à partir de la version 68, le prennent en charge.

Voici un extrait qui s'affichera correctement s'il est essayé dans un navigateur compatible:

::marker { content: counters(list-item,'.') ':' }
li { padding-left: 0.5em }
<ol>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
  <li>li element</li>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
</ol>

Vous pouvez également consulter cet excellent article de smashingmagazine sur le sujet.

tyrion
la source
0

J'avais besoin d'ajouter cela à la solution publiée dans 12 car j'utilisais une liste avec un mélange de composants de liste ordonnée et de listes non ordonnées. contenu: aucune citation ne semble étrange à ajouter, je sais, mais cela fonctionne ...

ol ul li:before {
    content: no-close-quote;
    counter-increment: none;
    display: list-item;
    margin-right: 100%;
    position: absolute;
    right: 10px;
}
benjarlett
la source
0

Ce qui suit a fonctionné pour moi:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
}

ol > li {
  display: table;
  counter-increment: item;
  margin-bottom: 0.6em;
}

ol > li:before {
  content: counters(item, ".") ") ";
  display: table-cell;
  padding-right: 0.6em;
}

li ol > li {
  margin: 0;
}

li ol > li:before {
  content: counters(item, ".") ") ";
}

Regardez: http://jsfiddle.net/rLebz84u/2/

ou celui-ci http://jsfiddle.net/rLebz84u/3/ avec plus de texte justifié

Willy Wonka
la source
Perte de temps à regarder. Presque identique à une réponse antérieure. Seule la différence est ")" a été ajouté à la fin du marqueur.
juanitogan
0

c'est le bon code si vous voulez que le premier enfant redimensionne d'autres css.

<style>
    li.title { 
        font-size: 20px; 

        counter-increment: ordem; 
        color:#0080B0;
    }
    .my_ol_class { 
        counter-reset: my_ol_class; 
        padding-left: 30px !important; 
    }
    .my_ol_class li { 
          display: block;
        position: relative;

    }
    .my_ol_class li:before { 
        counter-increment: my_ol_class; 
        content: counter(ordem) "." counter(my_ol_class) " "; 
        position: absolute;
        margin-right: 100%;
        right: 10px; /* space between number and text */
    }
    li.title ol li{
         font-size: 15px;
         color:#5E5E5E;
    }
</style>

dans le fichier html.

        <ol>
            <li class="title"> <p class="page-header list_title">Acceptance of Terms. </p>
                <ol class="my_ol_class">
                    <li> 
                        <p>
                            my text 1.
                        </p>
                    </li>
                    <li>
                        <p>
                            my text 2.
                        </p>
                    </li>
                </ol>
            </li>
        </ol>
sandeep kumar
la source