Combinazione di pseudo-elementi CSS, ": after" the ": last-child"


122

Voglio creare elenchi "grammaticalmente corretti" usando i CSS. Questo è quello che ho finora:

I <li>tag vengono visualizzati orizzontalmente con virgole dopo di essi.

li { display: inline; list-style-type: none; }

li:after { content: ", "; }

Funziona, ma voglio che l '"ultimo figlio" abbia un punto invece di una virgola. E, se possibile, vorrei mettere "e" anche prima dell '"ultimo figlio". Gli elenchi a cui sto applicando lo stile vengono generati dinamicamente, quindi non posso semplicemente dare una lezione agli "ultimi figli". Non puoi combinare pseudo-elementi, ma questo è fondamentalmente l'effetto che voglio ottenere.

li:last-child li:before { content: "and "; }

li:last-child li:after { content: "."; }

Come lo faccio funzionare?


4
davvero non dovresti usare CSS per questo.
Funky Dude,

2
Devo essere un po 'd'accordo con Funky Dude. Sarebbe meglio farlo in HTML (o codebehind se è più del semplice HTML). CSS è per la formattazione :)
Zyphrax

16
Io ... personalmente, tendo a sostenere che, in un elenco, la formattazione è una caratteristica, non una necessità. Stando così le cose, l'utilizzo dei CSS consente più semplici aggiunte o rimozioni dall'elenco, rispetto all'utilizzo della codifica html o lato server. Ma sono strano così, a volte, e, onestamente ymmv, ecc ... =)
David dice reintegrare Monica il

9
E +1 per l'utilizzo della virgola di Oxford! :)
Brandon Rhodes

5
+1 per "+1 per Oxford Comma". Non ne ho mai sentito parlare (non sono nativo). Ma una rapida ricerca nel wiki dice che è naturale, perché non è usato in molte lingue. Divertente quello che si può imparare a
cercare su Google

Risposte:


168

Funziona :) (spero multi-browser, piace a Firefox)

li { display: inline; list-style-type: none; }
li:after { content: ", "; }
li:last-child:before { content: "and "; }
li:last-child:after { content: "."; }
<html>
  <body>
    <ul>
      <li>One</li>
      <li>Two</li>
      <li>Three</li>
    </ul>
  </body>
</html>


2
Un problema simile è il caso in cui si separano le voci di menu con caratteri pipe. La stessa soluzione funziona. Tuttavia, l'attributo di contenuto finale deve essere impostato su {content: none;} per eliminare il carattere pipe finale.
aridlehoover

2
Anche l'ordine è importante. li:last-child:afterfunziona ma li:after:last-childnon funziona.
Richard Ayotte

1
Tieni presente che :last-childnon appartiene alle specifiche CSS3, quindi non è supportato da IE8 e dalle versioni precedenti.
Cthulhu

23

Mi piace per gli elementi dell'elenco negli elementi <menu>. Considera il seguente markup:

<menu>
  <li><a href="/member/profile">Profile</a></li>
  <li><a href="/member/options">Options</a></li>
  <li><a href="/member/logout">Logout</a></li>
</menu>

Lo stile con il seguente CSS:

menu > li {
  display: inline;
}

menu > li::after {
  content: ' | ';
}

menu > li:last-child::after {
  content: '';
}

Questo mostrerà:

Profile | Options | Logout

E questo è possibile grazie a ciò che Martin Atkins ha spiegato sul suo commento

Nota che in CSS 2 useresti :after, no ::after. Se usi CSS 3, usa ::after(due semicolonne) perché ::afterè uno pseudo-elemento (una singola semicolonna è per le pseudo-classi).


16

Un vecchio thread, tuttavia qualcuno potrebbe trarne vantaggio:

li:not(:last-child)::after { content: ","; }
li:last-child::after { content: "."; }

Questo dovrebbe funzionare in CSS3 e CSS2 [non testato].


11

È possibile combinare gli pseudo-elementi! Scusate ragazzi, l'ho capito da solo poco dopo aver pubblicato la domanda. Forse è meno comunemente usato a causa di problemi di compatibilità.

li:last-child:before { content: "and "; }

li:last-child:after { content: "."; }

Funziona perfettamente. I CSS sono sorprendenti.


12
Questo è un po 'un "angolo di pignoleria", ma "last-child" in realtà è una pseudo- classe , mentre "prima" e "dopo" sono pseudo-elementi. La differenza è che una pseudo-classe è un vincolo aggiuntivo su un elemento esistente, mentre uno pseudo-elemento è effettivamente un elemento completamente nuovo nell'albero di presentazione che è stato generato in CSS piuttosto che in HTML. Puoi combinarli per questo motivo: last-childè un modificatore su li, quindi dopo aver selezionato tutti gli lielementi che sono gli ultimi figli, selezioni (e crei implicitamente) un nuovo elemento prima e dopo ciascuno.
Martin Atkins

So che probabilmente hai dimenticato da tempo questo particolare thread, ma dal momento che hai menzionato che i tuoi elenchi erano di lunghezza variabile, vale la pena sottolineare che, nella maggior parte dei contesti, un elenco con esattamente due elementi non sarebbe corretto con una virgola in inglese. In altre parole, se volevi "pane e burro". piuttosto che "pane e burro". - allora la maggior parte delle soluzioni fornite qui sarebbero incomplete. Ho trovato un modo per aggirarlo e l'ho postato di seguito come risposta, nel caso in cui aiuti qualcuno a guardare ancora così in fondo al thread.
Matt Wagner

6

Solo per menzionare, in CSS 3

:dopo

dovrebbe essere usato in questo modo

::dopo

Da https://developer.mozilla.org/de/docs/Web/CSS/::after :

La notazione :: after è stata introdotta nei CSS 3 per stabilire una discriminazione tra pseudo-classi e pseudo-elementi. I browser accettano anche la notazione: dopo introdotta in CSS 2.

Quindi dovrebbe essere:

li { display: inline; list-style-type: none; }
li::after { content: ", "; }
li:last-child::before { content: "and "; }
li:last-child::after { content: "."; }

3
Ogni browser che supporta la ::sintassi CSS3 con doppi due punti supporta anche solo la :sintassi, ma IE 8 supporta solo i due punti singoli, quindi per ora si consiglia di utilizzare solo i due punti per il miglior supporto del browser. ::è il formato più recente rientrato per distinguere il contenuto pseudo dagli pseudo selettori. Se non hai bisogno del supporto di IE 8, sentiti libero di usare i due punti doppi. Da questo articolo
JohnnyQ

2
IE 8 non è più un giocatore in termini di standard del browser. Non supportato da Microsoft e non supporta HTML5 o CSS3 (pseudo elementi, trasformazioni, ecc.) Ho lavorato molto sulla compatibilità con le versioni precedenti, fino a un anno fa, risalendo a IE6 / IE7 (tramite Modernizr.) Abbiamo fatto molta strada e se intendi che il tuo sito presenti la sua identità online a lungo termine, senza che diventi una soluzione miope, considera semplicemente le entrate che guadagneresti da qualcuno che utilizza IE8. Nada. Anche gli anziani, 20 anni indietro rispetto ai tempi, utilizzano ora tablet e laptop 2 in 1.
Steven Ventimiglia

2

Aggiungendo un'altra risposta a questa domanda perché avevo bisogno esattamente di ciò che @derek stava chiedendo e ero già andato un po 'oltre prima di vedere le risposte qui. In particolare, avevo bisogno di CSS che potessero anche tenere conto del caso con esattamente due voci di elenco, in cui la virgola NON è desiderata. Ad esempio, alcune righe di autore che volevo produrre sarebbero simili alle seguenti:

Un autore: By Adam Smith.

Due autori: By Adam Smith and Jane Doe.

Tre autori: By Adam Smith, Jane Doe, and Frank Underwood.

Le soluzioni già fornite qui funzionano per un autore e per 3 o più autori, ma trascura di tenere conto del caso dei due autori, dove lo stile "Oxford Comma" (noto anche come stile "Harvard Comma" in alcune parti) non si applica - cioè, non dovrebbe esserci alcuna virgola prima della congiunzione.

Dopo un pomeriggio di armeggiare, mi è venuto in mente quanto segue:

<html>
 <head>
  <style type="text/css">
    .byline-list {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    .byline-list > li {
      display: inline;
      padding: 0;
      margin: 0;
    }
    .byline-list > li::before {
      content: ", ";
    }
    .byline-list > li:last-child::before {
      content: ", and ";
    }
    .byline-list > li:first-child + li:last-child::before {
      content: " and ";
    }
    .byline-list > li:first-child::before {
      content: "By ";
    }
    .byline-list > li:last-child::after {
      content: ".";
    }
  </style>
 </head>
 <body>
  <ul class="byline-list">
   <li>Adam Smith</li>
  </ul>
  <ul class="byline-list">
   <li>Adam Smith</li><li>Jane Doe</li>
  </ul>
  <ul class="byline-list">
   <li>Adam Smith</li><li>Jane Doe</li><li>Frank Underwood</li>
  </ul>
 </body>
</html>

Visualizza i sottotitoli come li ho sopra.

Alla fine, ho dovuto anche sbarazzarmi degli spazi vuoti tra gli lielementi, per evitare un fastidio: la proprietà inline-block avrebbe altrimenti lasciato uno spazio prima di ogni virgola. Probabilmente c'è un trucco decente alternativo per questo, ma non è questo l'argomento di questa domanda, quindi lo lascerò a qualcun altro per rispondere.

Fiddle qui: http://jsfiddle.net/5REP2/


2

Per avere qualcosa come Uno, due e tre dovresti aggiungere un altro stile CSS

li:nth-last-child(2):after {
    content: ' ';
}

Ciò rimuoverebbe la virgola dal penultimo elemento.

Codice completo

li {
  display: inline;
  list-style-type: none;
}

li:after {
  content: ", ";
}

li:nth-last-child(2):after {
  content: '';
}

li:last-child:before {
  content: " and ";
}

li:last-child:after {
  content: ".";
}
<html>

<body>
  <ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
  </ul>
</body>

</html>


0

Sto usando la stessa tecnica in una media query che trasforma efficacemente un elenco puntato in un elenco in linea su dispositivi più piccoli poiché risparmiano spazio.

Quindi il cambiamento da:

  • Voce di elenco 1
  • Voce di elenco 2
  • Voce di elenco 3

per:

Voce di elenco 1; Voce di elenco 2; Voce di elenco 3.


Sta cercando di farlo con CSS. Il tuo metodo è HTML hardcoded. Questo metodo viene normalmente utilizzato per visualizzare la navigazione.
Sparatan117
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.