2016-02-17 15 views
11

Ho qualcosa che si comporta allo stesso modo dello snippet fornito. Ho una lista di articoli, che quando uno è selezionato, voglio che sia visualizzato in cima alla lista, cosa che posso facilmente fare con l'ordine flex. Solo uno può essere selezionato alla volta. Ma poiché ciascuno degli elementi dell'elenco ha dei bordi, l'ultimo elemento non dovrebbe avere un bordo. Semplicemente usando il li:last-of-type funziona bene per la maggior parte dei casi, tranne quando è l'ultimo elemento della lista che è selezionato.CSS: last-of-type non funziona in combinazione con: non

Ho provato diversi selettori che dovrebbero selezionare l'ultimo elemento dell'elenco in un elenco non ordinato che non ha una data classe, ma il selettore last-of-type non sembra comportarsi correttamente.

Nel caso in cui non sia chiaro nel codice, il selettore a cui mi riferisco è .selection li:not(.selected):last-of-type. E il problema è il doppio bordo in fondo alla lista. Dovrebbe essere un singolo confine proveniente dall'elemento della lista non ordinata.

.selection ul { 
 
    display: flex; 
 
    flex-direction: column; 
 
    border: .15rem solid #666; 
 
} 
 

 
.selection li { 
 
    order: 2; 
 
    border-bottom: .15rem dashed #666; 
 
} 
 

 
.selection li.selected { 
 
    order: 1; 
 
} 
 

 
/** This selector should work in my mind, but it doesn't **/ 
 
.selection li:not(.selected):last-of-type { 
 
    border-bottom: none; 
 
} 
 

 
/** Non-important styles to put it into context **/ 
 
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; } 
 
li { padding: 1rem 2rem; background-color: #ebebeb; } 
 
li:hover { background-color: #ccc; } 
 
a { color: inherit; text-decoration: none; }
<div class="selection"> 
 
    <ul> 
 
    <li><a href="">1</a></li> 
 
    <li><a href="">2</a></li> 
 
    <li class="selected">3</li> 
 
    </ul> 
 
</div>

Ho anche creato questo Codepen snippet per dimostrare il problema.

Ho la sensazione che questo sia un problema con il selettore :last-of-type, e forse lo sto usando male, ma nella mia mente, il selettore di cui sopra dovrebbe funzionare.

Qualsiasi aiuto o informazioni su come risolvere questo problema, o un altro modo per selezionare l'elemento, o informazioni sul motivo per cui questo non funziona sarebbe apprezzato.

+0

Questo suona * * come un 'nth-of-class' domanda che, ovviamente, non esiste. –

+0

Si dovrebbe anche essere consapevoli del fatto che 'nth-of-type' funziona con il DOM, ma il flexbox' order' è puramente ** visivo **. –

+0

Beh, è ​​più di un "ultimo di non-classe". – Pavlin

risposta

5

considerare questo approccio alternativo:

  • sbarazzarsi del selettore :not interamente
  • Dare il ul un bordo solo sulla sinistra, a destra e in alto
  • Applicare il bordo inferiore solo al li

ul { 
    display: flex; 
    flex-direction: column; 
    border-top: .15rem solid #666; 
    border-left: .15rem solid #666; 
    border-right: .15rem solid #666; 
} 

li { border-bottom: .15rem solid #666; } 

Revised Codepen


Ecco perché il vostro selettore non funziona:

.selection li:not(.selected):last-of-type { border-bottom: none; } 

Mi sembra che tu stai dicendo che si desidera abbinare l'ultima li elemento più a lungo in quanto non ha la classe selected.

Ma questo non è il modo in cui funziona last-of-type. Se lo li è un fratello, il selettore lo abbinerà, indipendentemente da class. Il selettore corrisponde agli elementi DOM. Ciò significa che anche se si applica display: none a li, il selettore corrisponderà comunque.

6.6.5.9. :last-of-type pseudo-class

Il :last-of-type pseudo-classe rappresenta un elemento che è l'ultimo fratello del suo tipo nella lista dei figli del suo elemento genitore.

fonte: https://drafts.csswg.org/selectors-3/#last-of-type-pseudo

Maggiori dettagli: How to get nth-child selector to skip hidden divs

+0

Sarebbe anche bello se potessi avere un bordo diverso sui miei elementi di lista che sul bordo esterno generale, come dimostrerò nello snippet rivisto. Questo approccio non funziona in questo scenario. – Pavlin

+1

Grazie per la spiegazione, sembra che abbia capito male il selettore. Pensavo che il selettore ': not' avrebbe creato un nuovo contesto da cui partiva il selettore': last-of-type'. Ora mi è chiaro che non è affatto così. – Pavlin

2

Invece di cercare di rimuovere border-bottom dall'ultima voce selezionata (che è difficile o impossibile in CSS), è modo più semplice per impostare a border-top per ciascun articolo e rimuovere quello in eccesso visivamente sopra gli altri, che è ... .selected!
tuo vincolo di avere:

un bordo diverso sul mio elementi della lista che sul bordo esterno generale

è consentito con questa soluzione.

Updated pen

.selection ul { 
 
    display: flex; 
 
    flex-direction: column; 
 
    border: .15rem solid #666; 
 
} 
 

 
.selection li { 
 
    order: 2; 
 
    border-top: .15rem dashed #666; 
 
    background: lightblue; 
 
} 
 

 
.selection li.selected { 
 
    order: 1; 
 
    border-top: none; 
 
    background: tomato; 
 
} 
 

 
/** Non-important styles to put it into context **/ 
 
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; } 
 
li { padding: 1rem 2rem; background-color: #ebebeb; } 
 
li:hover { background-color: #ccc; } 
 
a { color: inherit; text-decoration: none; }
<div class="selection"> 
 
    <ul> 
 
    <li><a href="">1</a></li> 
 
    <li><a href="">2</a></li> 
 
    <li class="selected">3</li> 
 
    </ul> 
 
</div>

+0

Questo è davvero perfetto. Mi sento stupido per non pensarci adesso ^^. Grazie, questo soddisfa tutti i requisiti. – Pavlin

1

considerare questo più come un hack che una risposta.

solo per dimostrare che può essere, in qualche modo, fatto in CSS

l'elemento giallo è quella selezionata.

.selection ul { 
 
    display: flex; 
 
    flex-direction: column; 
 
    border: .15rem solid #666; 
 
} 
 

 
.selection li { 
 
    order: 2; 
 
    border-bottom: .15rem dashed #666; 
 
} 
 

 
div.selection li.selected { 
 
    order: 1; 
 
    background-color: yellow; 
 
} 
 

 
.selection li:nth-last-child(2) { 
 
    order: 3; 
 
} 
 

 
.selection li:not(.selected):nth-last-child(2) { 
 
    border-bottom: none; 
 
} 
 

 
.selection li.selected:nth-last-child(2) ~ li { 
 
    border-bottom: none; 
 
} 
 

 

 
/** Non-important styles to put it into context **/ 
 
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; } 
 
li { padding: 1rem 2rem; background-color: #ebebeb; } 
 
li:hover { background-color: #ccc; } 
 
a { color: inherit; text-decoration: none; } 
 
.selection {display: inline-block; width: 160px;}
<div class="selection"> 
 
    <ul> 
 
    <li><a href="">1</a></li> 
 
    <li><a href="">3</a></li> 
 
    <li class="selected">2</li> 
 
    </ul> 
 
</div> 
 
<div class="selection"> 
 
    <ul> 
 
    <li><a href="">1</a></li> 
 
    <li><a href="">3</a></li> 
 
    <li><a href="">2</a></li> 
 
    </ul> 
 
</div> 
 
<div class="selection"> 
 
    <ul> 
 
    <li><a href="">1</a></li> 
 
    <li class="selected"><a href="">3</a></li> 
 
    <li><a href="">2</a></li> 
 
    </ul> 
 
</div>

+0

È molto carino! – Pavlin