¿Puede la lista ordenada producir un resultado similar a 1.1, 1.2, 1.3 (en lugar de solo 1, 2, 3, ...) con css?

201

¿Puede una lista ordenada producir resultados que se vean como 1.1, 1.2, 1.3 (en lugar de solo 1, 2, 3, ...) con CSS? Hasta ahora, el uso list-style-type:decimalha producido solo 1, 2, 3, no 1.1, 1.2., 1.3.

Richard77
fuente
Sugeriría comparar la respuesta aceptada con la de Jakub Jirutka. Creo que este último es incluso mucho mejor.
Frank Conijn
Solución elegante ¿Alguna idea de por qué Wikipedia usa un ul para sus secciones de contenido en lugar de esto?
Mattypants
1
@davnicwil Estoy de acuerdo; Parece que probablemente acabo de aplicar el duplicado en el orden incorrecto en septiembre.
TylerH
Genial, ahora me siento incómodo ya que nunca se me ocurrió que podría ser un simple error como ese: ¡disculpas!
davnicwil

Respuestas:

290

Puede usar contadores para hacerlo:

Los siguientes números de hoja de estilo anidan elementos de la lista como "1", "1.1", "1.1.1", etc.

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

Ejemplo

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>

Consulte Contadores anidados y alcance para obtener más información.

Gumbo
fuente
2
gran respuesta. ¿Cuál es el soporte para esto?
Jason McCreary
1
@Jason McCreary: Bueno, esa es la desventaja: los contadores no son compatibles con IE hasta la versión 8 .
Gumbo
3
Esta solución pierde una pequeña cosa: el punto que sigue al número de artículo. No se parece al estilo de lista estándar. Arregle agregando un punto a la regla para li:before: content: counters(item, ".")". ";
LS
44
Esta es una respuesta pobre. No funciona correctamente Echa un vistazo a la respuesta de Jakub Jirutka a continuación
Sr. Pablo
1
@Gumbo Lo sé, y la respuesta de Jakub me dio la numeración correcta.
Mr Pablo
236

Ninguna de las soluciones en esta página funciona de manera correcta y universal para todos los niveles y párrafos largos (ajustados). Es realmente difícil lograr una sangría consistente debido al tamaño variable del marcador (1., 1.2, 1.10, 1.10.5, ...); no puede ser simplemente "falso", ni siquiera con un margen / relleno precalculado para cada nivel de sangría posible.

Finalmente descubrí una solución que realmente funciona y no necesita JavaScript.

Se ha probado en Firefox 32, Chromium 37, IE 9 y el navegador de Android. No funciona en IE 7 y anteriores.

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, ".") " ";
}

Ejemplo: Ejemplo

Pruébalo en JSFiddle , bifurca en Gist .

Jakub Jirutka
fuente
1
Buen trabajo logrando este tipo de sangría. Sin embargo, aún argumentaría que los primeros 2 casos de sangría que ha enumerado son una cuestión de preferencia en lugar de correcto e incorrecto. Considere el caso 1 y el caso 2 : este último logra exprimir muchos más niveles antes de que el espacio se vuelva difícil de manejar, sin dejar de verse bastante ordenado. Además, MS Word y el estilo predeterminado del navegador usan sangría de caso 2. ¿Supongo que también lo están haciendo mal?
Saul Fautley
2
@ saul-fautley Está mal en términos de tipografía. Su ejemplo con una cantidad increíble de niveles anidados demuestra que la numeración anidada no es adecuada para demasiados niveles, pero eso es bastante obvio. MS Words no es un sistema de composición tipográfica, es un mero procesador de documentos con una tipografía pobre. Estilo de navegador predeterminado ... oh, no sabes mucho sobre tipografía, ¿verdad?
Jakub Jirutka
3
Realmente funciona (técnicamente) para todos los niveles y párrafos largos. Si es razonable usar docenas de niveles, esa es otra pregunta que no tiene nada que ver con la solución técnica. El punto es que no tiene que predefinir una regla CSS para cada nivel de anidación como con algunas otras soluciones.
Jakub Jirutka
44
Si bien no diría que hay algo intrínsecamente "incorrecto" con las otras respuestas, diría que están incompletas. Esta respuesta es acertada, e incluso funcionó en un sitio horriblemente extraño que estoy modificando.
DanielM
2
@tremby: La discrepancia se puede resolver haciendo que li use "display: table-row" en lugar de "display: table". El problema que esto trae es que la li no puede usar márgenes / rellenos ya que las filas de la tabla siempre se dimensionan automáticamente por su contenido. Esto se puede solucionar agregando un "li: after" con "display: block". Ver jsFiddle para un ejemplo completo. Como un extra adicional agregué "text-align: right" a "li: before" para alinear los números a la derecha.
mmlr
64

La respuesta elegida es un gran comienzo, pero esencialmente obliga al list-style-position: inside;estilo de los elementos de la lista, lo que dificulta la lectura del texto envuelto. Aquí hay una solución simple que también da control sobre el margen entre el número y el texto, y alinea el número a la derecha según el comportamiento predeterminado.

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
fuente
Una desventaja es que agrega un punto al final de cada elemento de la lista.
Davin Studer
3
@Davin Studer: solo agrega un punto al final de cada número, según el olcomportamiento predeterminado . Se puede eliminar fácilmente eliminando el último "."de la contentpropiedad, pero esto me parece un poco extraño.
Saul Fautley
14

Las soluciones publicadas aquí no funcionaron bien para mí, así que hice una combinación de las preguntas de esta pregunta y la siguiente: ¿Es posible crear una lista ordenada de varios niveles 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 */

Resultado:

captura de pantalla

Nota: la captura de pantalla, si desea ver el código fuente o lo que sea de esta publicación: http://estiloasertivo.blogspot.com.es/2014/08/introduccion-running-lean-y-lean.html

chelder
fuente
1
Esta es la mejor (y más simple) respuesta de trabajo de toda la página.
Bruno Toffolo
6

Nota: Use CSS para crear numeración anidada en un navegador moderno. Ver la respuesta aceptada. Lo siguiente es solo para interés histórico.counters


Si el navegador admite contenty 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
fuente
Esta solución falla horriblemente cuando las listas están anidadas.
LS
@LS Siempre puede acomodar los selectores para satisfacer sus necesidades. .foo > ol > li.
kennytm
1
Mi punto es que has codificado "1". en el estilo ¿Qué sucede cuando la sublista es hija del segundo elemento en la lista principal? Desea que aparezca como "2", pero siempre será "1". por la forma en que está codificado aquí. ¿Cual es la solución? ¿Hacer nuevos conjuntos de estilos para cada número posible? No. Use la counters()función como en los ejemplos anteriores en lugar de la counter()función.
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>

Resultado: http://i.stack.imgur.com/78bN8.jpg

KingRider
fuente
2

Tengo algún problema cuando hay dos listas y la segunda está dentro de DIV La segunda lista debe comenzar en 1. no 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/

EDITAR: Resolví el problema con este http://jsfiddle.net/hy5f6161/

robertad
fuente
1

En el futuro cercano, podrá usar el ::markerelemento psuedo para lograr el mismo resultado que otras soluciones en una sola línea de código.

Recuerde consultar la tabla de compatibilidad del navegador ya que sigue siendo una tecnología experimental. En el momento de escribir solo Firefox y Firefox para Android, a partir de la versión 68, son compatibles con esto.

Aquí hay un fragmento que se representará correctamente si se prueba en un navegador 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>

Es posible que también desee consultar este excelente artículo de smashingmagazine sobre el tema.

tyrion
fuente
0

Necesitaba agregar esto a la solución publicada en 12 ya que estaba usando una lista con una mezcla de componentes de listas ordenadas y listas no ordenadas. content: no-close-quote parece algo extraño para agregar Lo sé, pero funciona ...

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

Lo siguiente funcionó para mí:

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, ".") ") ";
}

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

o este http://jsfiddle.net/rLebz84u/3/ con más texto justificado

Willy Wonka
fuente
Pérdida de tiempo para mirar. Casi idéntico a una respuesta anterior. La única diferencia es ")" se ha agregado al final del marcador.
juanitogan
0

este es el código apropiado si desea primero cambiar el tamaño de otro 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>

en archivo 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
fuente