Esiste un selettore CSS “precedente fratello”?

+ è per il prossimo fratello. Esiste un equivalente per il fratello precedente?

No, non esiste un selettore “fratello precedente”.

Su una nota correlata, ~ è per il fratello successore generale (ovvero l’elemento viene dopo questo, ma non necessariamente immediatamente dopo) ed è un selettore CSS3. + è per il prossimo fratello ed è CSS2.1.

Vedi Combined jibling combinator di Selectors Level 3 e 5.7 Selettori di fratelli adiacenti da CSS (Cascading Style Sheets) Level 2 Revisione 1 (CSS 2.1) .

Ho trovato un modo per definire tutti i fratelli precedenti (opposti a ~ ) che potrebbero funzionare a seconda di ciò che ti serve.

Diciamo che hai una lista di link e quando tieni il mouse su uno, tutti i precedenti dovrebbero diventare rossi. Puoi farlo in questo modo:

 /* default link color is blue */ .parent a { color: blue; } /* prev siblings should be red */ .parent:hover a { color: red; } .parent a:hover, .parent a:hover ~ a { color: blue; } 
  

Il livello 4 dei selettori introduce :has() (in precedenza l’indicatore sobject ! ) Che ti permetterà di selezionare un fratello precedente con:

 previous:has(+ next) {} 

… ma al momento della scrittura, si tratta di una certa distanza oltre il margine negativo per il supporto del browser.

Considera la proprietà order dei layout flex e griglia.

Mi concentrerò su flexbox negli esempi di seguito, ma gli stessi concetti si applicano a Grid.


Con la flexbox, è ansible simulare un precedente selettore di pari livello.

In particolare, la proprietà di order flessibile può spostare elementi attorno allo schermo.

Ecco un esempio:

Vuoi che l’elemento A diventi rosso quando l’elemento B è al passaggio del mouse.

 
  • A
  • B

PASSI

  1. Rendi l’ ul un contenitore flessibile.

     ul { display: flex; } 

  1. Invertire l’ordine dei fratelli nel mark-up.

     
    • B
    • A

  1. Usa un selettore di pari livello per scegliere come target l’elemento A (faremo ~ o + ).

     li:hover + li { background-color: red; } 

  1. Usa la proprietà flex order per ripristinare l’ordine dei fratelli sul display.

     li:last-child { order: -1; } 

… e voilà! Un selettore fratello precedente è nato (o almeno simulato).

Ecco il codice completo:

 ul { display: flex; } li:hover + li { background-color: red; } li:last-child { order: -1; } /* non-essential decorative styles */ li { height: 200px; width: 200px; background-color: aqua; margin: 5px; list-style-type: none; cursor: pointer; } 
 
  • B
  • A

Ho avuto la stessa domanda, ma poi ho avuto un momento “duh”. Invece di scrivere

 x ~ y 

Scrivi

 y ~ x 

Ovviamente questo corrisponde a “x” anziché a “y”, ma risponde “c’è una corrispondenza?” domanda e il semplice attraversamento DOM può farti raggiungere l’elemento giusto in modo più efficiente rispetto al ciclo in javascript.

Mi rendo conto che la domanda iniziale era una domanda CSS, quindi questa risposta è probabilmente del tutto irrilevante, ma altri utenti di Javascript potrebbero inciampare nella ricerca tramite la ricerca come ho fatto io.

Due trucchi In pratica invertendo l’ordine HTML degli elementi desiderati in HTML e usando
~ Operatore dei fratelli successivi :

float-right + inversa l’ordine degli elementi HTML

 div{ /* Do with the parent whatever you know just to make the inner float-right elements appear where desired */ display:inline-block; } span{ float:right; /* float-right the elements! */ } span:hover ~ span{ /* On hover target it's "previous";) elements */ background:red; } 
 
5 4 3 2 1

+ è per il prossimo fratello. Esiste un equivalente per il fratello precedente?

È ansible utilizzare i selettori a due assi :! e ?

Ci sono 2 selettori di pari livello successivi nel CSS convenzionale:

  • + è il selettore fratello successivo immediato
  • ~ è l’ eventuale selettore fratello successivo

Nel convenzionale CSS, non esiste un precedente selettore fratello .

Tuttavia, nella libreria di post-processor CSS dell’ascia , ci sono 2 selettori di pari livello precedenti:

  • ? è il precedente selettore fratello precedente (opposto di + )
  • ! è il precedente selettore fratello (opposto di ~ )

Esempio di lavoro:

Nell’esempio seguente:

  • .any-subsequent:hover ~ div seleziona qualsiasi div successivo
  • .immediate-subsequent:hover + div seleziona il div successivo immediato
  • .any-previous:hover ! div .any-previous:hover ! div seleziona qualsiasi div precedente
  • .immediate-previous:hover ? div .immediate-previous:hover ? div seleziona il div precedente immediato
 div { display: inline-block; width: 60px; height: 100px; color: rgb(255, 255, 255); background-color: rgb(255, 0, 0); text-align: center; vertical-align: top; cursor: pointer; opacity: 0; transition: opacity 0.6s ease-out; } code { display: block; margin: 4px; font-size: 24px; line-height: 24px; background-color: rgba(0, 0, 0, 0.5); } div:nth-of-type(-n+4) { background-color: rgb(0, 0, 255); } div:nth-of-type(n+3):nth-of-type(-n+6) { opacity: 1; } .any-subsequent:hover ~ div, .immediate-subsequent:hover + div, .any-previous:hover ! div, .immediate-previous:hover ? div { opacity: 1; } 
 

Hover over any of the blocks below

Hover for ? selector
Hover for ! selector
Hover for ~ selector
Hover for + selector

Un’altra soluzione di flexbox

Puoi utilizzare l’ordine inverso degli elementi in HTML. Quindi, oltre order come nella risposta di Michael_B, puoi usare la flex-direction: row-reverse; o flex-direction: column-reverse; a seconda del layout.

Campione di lavoro:

 .flex { display: flex; flex-direction: row-reverse; /* Align content at the "reversed" end ie beginning */ justify-content: flex-end; } /* On hover target its "previous" elements */ .flex-item:hover ~ .flex-item { background-color: lime; } /* styles just for demo */ .flex-item { background-color: orange; color: white; padding: 20px; font-size: 3rem; border-radius: 50%; } 
 
5
4
3
2
1

Al momento non esiste un modo ufficiale per farlo, ma puoi usare un piccolo trucco per raggiungere questo objective! Ricorda che è sperimentale e presenta alcune limitazioni … (controlla questo link se ti preoccupi della compatibilità con navigator)

Quello che puoi fare è usare un selettore CSS3: la pseudo class chiamata nth-child()

 #list>* { display: inline-block; padding: 20px 28px; margin-right: 5px; border: 1px solid #bbb; background: #ddd; color: #444; margin: 0.4em 0; } #list :nth-child(-n+4) { color: #600b90; border: 1px dashed red; background: orange; } 
 

The oranges elements are the previous sibling li selected using li:nth-child(-n+4)

1

2

3

4
5

6

7

8

9

Se si conosce la posizione esatta, l’esclusione :nth-child() di tutti i fratelli successivi funzionerebbe.

 ul li:not(:nth-child(n+3)) 

Quale sceglierebbe tutti i li prima del terzo (es. 1 ° e 2 °). Ma, a mio parere, questo sembra brutto e ha un usecase molto stretto.

Puoi anche selezionare l’ennesimo bambino da destra a sinistra:

 ul li:nth-child(-n+2) 

Che fa lo stesso

Sfortunatamente non esiste un selettore di fratelli “precedenti”, ma è comunque ansible ottenere lo stesso effetto usando il posizionamento (es. Fluttuazione a destra). Dipende da cosa stai cercando di fare.

Nel mio caso, volevo un sistema di classificazione a 5 stelle prevalentemente CSS. Avrei bisogno di colorare (o scambiare l’icona di) le stelle precedenti. Facendo galleggiare ogni elemento a destra, sto essenzialmente ottenendo lo stesso effetto (l’html per le stelle quindi deve essere scritto “all’indietro”).

Sto usando FontAwesome in questo esempio e lo scambio tra gli unicodes di fa-star-o e fa-star http://fortawesome.github.io/Font-Awesome/

CSS:

 .fa { display: inline-block; font-family: FontAwesome; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* set all stars to 'empty star' */ .stars-container { display: inline-block; } /* set all stars to 'empty star' */ .stars-container .star { float: right; display: inline-block; padding: 2px; color: orange; cursor: pointer; } .stars-container .star:before { content: "\f006"; /* fontAwesome empty star code */ } /* set hovered star to 'filled star' */ .star:hover:before{ content: "\f005"; /* fontAwesome filled star code */ } /* set all stars after hovered to'filled star' ** it will appear that it selects all after due to positioning */ .star:hover ~ .star:before { content: "\f005"; /* fontAwesome filled star code */ } 

HTML: (40)

JSFiddle: http://jsfiddle.net/andrewleyva/88j0105g/

A seconda del tuo objective esatto, c’è un modo per raggiungere l’utilità di un selettore genitore senza usarne uno (anche se ne esistesse uno) …

Diciamo che abbiamo:

  

Cosa possiamo fare per rendere visivamente il blocco Socks (compresi i colors dei calzini) usando la spaziatura?

Cosa sarebbe bello ma non esiste:

 ul li ul:parent { margin-top: 15px; margin-bottom: 15px; } 

Cosa esiste:

 li > a { margin-top: 15px; display: block; } li > a:only-child { margin-top: 0px; } 

Questo imposta tutti i link di ancoraggio con un margine di 15px in alto e lo reimposta su 0 per quelli senza elementi UL (o altri tag) all’interno di LI.

Ho avuto un problema simile e ho scoperto che tutti i problemi di questa natura possono essere risolti come segue:

  1. dai a tutti i tuoi articoli uno stile.
  2. dai uno stile al tuo articolo selezionato.
  3. dai uno stile agli oggetti successivi usando + o ~.

in questo modo sarai in grado di ridimensionare i tuoi articoli attuali, precedenti (tutti gli oggetti sostituiti con gli elementi attuali e successivi) e i tuoi prossimi elementi.

esempio:

 /* all items (will be styled as previous) */ li { color: blue; } /* the item i want to distinguish */ li.milk { color: red; } /* next items */ li ~ li { color: green; } 
  • Tea
  • Milk
  • Juice
  • others

Spero che aiuti qualcuno.

Come è già stato detto più volte – con div ~ p tutti gli elementi

che sono preceduti da un elemento

sono selezionati.

Dai un’occhiata a questo elenco di tutti i selettori CSS.