L'elenco ordinato può produrre risultati simili a 1.1, 1.2, 1.3 (anziché solo 1, 2, 3, ...) con CSS?


201

Un elenco ordinato può produrre risultati simili a 1.1, 1.2, 1.3 (anziché solo 1, 2, 3, ...) con CSS? Finora, l'utilizzo list-style-type:decimalha prodotto solo 1, 2, 3, non 1.1, 1.2., 1.3.


Suggerirei di confrontare la risposta accettata con quella di Jakub Jirutka. Penso che quest'ultimo sia ancora molto meglio.
Frank Conijn,

Soluzione elegante. Qualche idea sul perché Wikipedia utilizzi un ul per le sue sezioni di contenuto anziché questo?
Mattypants,

1
@davnicwil Sono d'accordo; sembra che probabilmente ho appena applicato il duplicato nell'ordine sbagliato a settembre.
TylerH,

Bene, ora mi sento imbarazzato perché non mi è mai venuto in mente che potrebbe essere un semplice errore del genere: scuse!
davnicwil,

Risposte:


290

Puoi usare i contatori per farlo:

Il seguente foglio di stile numera gli elementi dell'elenco nidificati come "1", "1.1", "1.1.1", ecc.

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

Esempio

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>

Vedere Contatori e ambito nidificati per ulteriori informazioni.


2
Bella risposta. Qual è il supporto per questo?
Jason McCreary,

1
@Jason McCreary: Beh, questo è il lato negativo: i contatori non sono supportati in IE fino alla versione 8 .
Gumbo,

3
Questa soluzione manca una piccola cosa: il punto che segue il numero dell'articolo. Non sembra lo stile dell'elenco standard. Risolto aggiungendo un punto alla regola per li:before: content: counters(item, ".")". ";
LS

4
Questa è una risposta scadente. Non funziona correttamente Dai un'occhiata alla risposta di Jakub Jirutka di seguito
Mr Pablo,

1
@Gumbo lo so, e la risposta di Jakub mi ha dato la numerazione corretta.
Pablo,

236

Nessuna delle soluzioni in questa pagina funziona correttamente e universalmente per tutti i livelli e paragrafi lunghi (a capo). È davvero difficile ottenere un rientro coerente a causa delle dimensioni variabili del marker (1., 1.2, 1.10, 1.10.5, ...); non può essere solo "simulato", nemmeno con un margine / riempimento precompilato per ogni possibile livello di rientro.

Alla fine ho capito una soluzione che funziona davvero e non ha bisogno di JavaScript.

È testato su Firefox 32, Chromium 37, IE 9 e Android Browser. Non funziona su IE 7 e precedenti.

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

Esempio: Esempio

Provalo su JSFiddle , biforcalo su Gist .


1
Ottimo lavoro nel raggiungere questo tipo di indentazione. Direi comunque che i primi 2 casi di rientro che hai elencato sono una questione di preferenza piuttosto che giusta e sbagliata. Prendi in considerazione il caso 1 e il caso 2 : quest'ultimo riesce a spremere molti più livelli prima che la spaziatura diventi ingombrante, pur continuando a sembrare piuttosto ordinata. Inoltre, MS Word e stile browser predefinito utilizzano entrambi il rientro del caso 2. Immagino che stiano anche sbagliando?
Saul Fautley,

2
@ saul-fautley È sbagliato in termini di tipografia. Il tuo esempio con un numero folle di livelli nidificati dimostra che la numerazione nidificata non è adatta a troppi livelli, ma è abbastanza ovvio. MS Words non è un sistema di composizione, è un semplice elaboratore di documenti con una tipografia scadente. Stile del browser predefinito ... oh, non sai molto sulla tipografia, vero?
Jakub Jirutka,

3
Funziona davvero (tecnicamente) per tutti i livelli e lunghi paragrafi. Se è ragionevole usare una dozzina di livelli, questa è un'altra domanda che non ha nulla a che fare con la soluzione tecnica. Il punto è che non è necessario predefinire una regola CSS per ciascun livello di annidamento come con alcune altre soluzioni.
Jakub Jirutka,

4
Anche se non direi che c'è qualcosa di intrinsecamente "sbagliato" con le altre risposte, direi che sono incomplete. Questa risposta è esatta e ha persino funzionato in un sito in uno stile orribilmente bizzarro che sto modificando.
DanielM

2
@tremby: la discrepanza può essere risolta facendo usare li "display: table-row" invece di "display: table". Il problema che ciò comporta è che li non può quindi utilizzare alcun margine / padding poiché le righe della tabella vengono sempre ridimensionate automaticamente in base al loro contenuto. Questo può essere aggirato aggiungendo un "li: after" con "display: block". Vedi jsFiddle per un esempio completo. Come bonus extra ho aggiunto "text-align: right" a "li: before" per allineare i numeri a destra.
mmlr

64

La risposta scelta è un ottimo inizio, ma essenzialmente forza lo list-style-position: inside;stile sugli elementi dell'elenco, rendendo difficile leggere il testo a capo. Ecco una semplice soluzione che dà anche il controllo del margine tra il numero e il testo e allinea il numero a destra secondo il comportamento predefinito.

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/


Un aspetto negativo è che aggiunge un punto alla fine di ogni elemento dell'elenco.
Davin Studer,

3
@Davin Studer: aggiunge solo un punto alla fine di ogni numero, secondo il olcomportamento predefinito . Può essere facilmente rimosso cancellando l'ultimo "."dalla contentproprietà, ma questo mi sembra un po 'strano.
Saul Fautley,

14

Le soluzioni pubblicate qui non hanno funzionato bene per me, quindi ho fatto una combinazione di quelle di questa domanda e la seguente domanda: È possibile creare un elenco ordinato a più livelli in 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 */

Risultato:

immagine dello schermo

Nota: lo screenshot, se desideri vedere il codice sorgente o qualsiasi altra cosa provenga da questo post: http://estiloasertivo.blogspot.com.es/2014/08/introduccion-running-lean-y-lean.html


1
Questa è la risposta di lavoro migliore (e più semplice) dell'intera pagina.
Bruno Toffolo,

6

Nota: utilizzare CSS per creare la numerazione nidificata in un browser moderno. Vedi la risposta accettata Quanto segue è solo per interesse storico.counters


Se il browser supporta contente 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>


Questa soluzione fallisce in modo orribile quando gli elenchi sono nidificati.
LS

@LS È sempre possibile sistemare i selettori in base alle proprie esigenze. .foo > ol > li.
kennytm,

1
Il punto è che hai codificato "1". nello stile. Cosa succede quando l'elenco secondario è figlio del secondo elemento nell'elenco padre? Vuoi che appaia come "2.", ma sarà sempre "1." a causa del modo in cui è codificato qui. Qual è la soluzione? Crea nuovi set di stili per ogni numero possibile? No. Utilizzare la counters()funzione come negli esempi precedenti anziché la counter()funzione.
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>

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


2

Ho qualche problema quando ci sono due liste e la seconda è dentro DIV La seconda lista dovrebbe iniziare da 1. non 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: ho risolto il problema con questo http://jsfiddle.net/hy5f6161/


1

Nel prossimo futuro potresti essere in grado di utilizzare l' ::markerelemento psuedo per ottenere lo stesso risultato di altre soluzioni in una sola riga di codice.

Ricorda di controllare la tabella di compatibilità del browser poiché questa è ancora una tecnologia sperimentale. Al momento di scrivere solo Firefox e Firefox per Android, a partire dalla versione 68, supportano questo.

Ecco uno snippet che verrà visualizzato correttamente se provato in un browser compatibile:

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

Potresti anche voler dare un'occhiata a questo fantastico articolo distruggendo il tema sull'argomento.


0

Avevo bisogno di aggiungere questo alla soluzione pubblicata in 12 mentre stavo usando un elenco con una combinazione di componenti elenco ordinato e elenchi non ordinati. contenuto: no-close-quote sembra una cosa strana da aggiungere, lo so, ma funziona ...

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

0

Per me ha funzionato:

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

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

o questo http://jsfiddle.net/rLebz84u/3/ con altro testo giustificato


Perdita di tempo da guardare. Quasi identico a una risposta precedente. L'unica differenza è ")" è stata aggiunta alla fine del marker.
juanitogan,

0

questo è il codice corretto se si desidera ridimensionare il primo figlio di altri 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>

nel file 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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.