Posso avere più: prima di pseudo-elementi per lo stesso elemento?


116

È possibile avere più :beforepseudo per lo stesso elemento?

.circle:before {
    content: "\25CF";
    font-size: 19px;
}
.now:before{
    content: "Now";
    font-size: 19px;
    color: black;
}

Sto cercando di applicare gli stili precedenti allo stesso elemento usando jQuery, ma viene applicato solo quello più recente, mai entrambi.

Risposte:


94

In CSS2.1, un elemento può avere al massimo uno di qualsiasi tipo di pseudo-elemento in qualsiasi momento. (Ciò significa che un elemento può avere sia uno :beforeche uno :afterpseudo-elemento - semplicemente non può averne più di uno di ogni tipo.)

Di conseguenza, quando hai più :beforeregole che corrispondono allo stesso elemento, verranno tutte sovrapposte e applicate a un singolo :beforepseudo-elemento, come con un elemento normale. Nel tuo esempio, il risultato finale è simile a questo:

.circle.now:before {
    content: "Now";
    font-size: 19px;
    color: black;
}

Come puoi vedere, contentavrà effetto solo la dichiarazione che ha la precedenza più alta (come detto, quella che arriva per ultima) - il resto delle dichiarazioni viene scartato, come nel caso di qualsiasi altra proprietà CSS.

Questo comportamento è descritto nella sezione Selettori di CSS2.1 :

Gli pseudo-elementi si comportano esattamente come gli elementi reali nei CSS con le eccezioni descritte di seguito e altrove.

Ciò implica che i selettori con pseudo-elementi funzionano proprio come i selettori per elementi normali. Significa anche che la cascata dovrebbe funzionare allo stesso modo. Stranamente, CSS2.1 sembra essere l'unico riferimento; né i selettori css3i cascade css3 lo menzionano affatto, e resta da vedere se sarà chiarito in una specifica futura.

Se un elemento può abbinare più di un selettore con lo stesso pseudo-elemento e vuoi che si applichino tutti in qualche modo, dovrai creare regole CSS aggiuntive con selettori combinati in modo da poter specificare esattamente cosa dovrebbe fare il browser in quelli casi. Non posso fornire un esempio completo che includa la contentproprietà qui, poiché non è chiaro ad esempio se il simbolo o il testo debbano venire prima. Ma il selettore di cui hai bisogno per questa regola combinata è .circle.now:beforeo .now.circle:before- qualunque selettore tu scelga è una preferenza personale poiché entrambi i selettori sono equivalenti, è solo il valore della contentproprietà che dovrai definire tu stesso.

Se hai ancora bisogno di un esempio concreto, vedi la mia risposta a questa domanda simile .

La specifica del contenuto css3 legacy contiene una sezione sull'inserimento di più ::beforee ::afterpseudo-elementi utilizzando una notazione compatibile con la cascata CSS2.1, ma si noti che quel particolare documento è obsoleto: non è stato aggiornato dal 2003 e nessuno lo ha ha implementato questa funzione nell'ultimo decennio. La buona notizia è che il documento abbandonato sta attivamente subendo una riscrittura sotto le spoglie di css-content-3 e css-pseudo-4 . La cattiva notizia è che la caratteristica degli pseudo-elementi multipli non si trova da nessuna parte in nessuna delle due specifiche, presumibilmente a causa, ancora una volta, della mancanza di interesse da parte dell'implementatore.


12
Nel caso specifico, se un elemento appartiene sia alla classe circleche alla classe now, entrambe le regole si applicano allo :beforepseudoelemento dell'elemento, ma il normale CSS implica che solo una delle contentimpostazioni può avere effetto (dalle normali regole a cascata). Il punto è che contentnon si accumula.
Jukka K. Korpela

Risulta che questa domanda a cui ho risposto diversi mesi dopo è un duplicato di questa. Da allora ho unito la maggior parte delle informazioni dall'altra risposta, che fondamentalmente si espande su tutto ciò che @Jukka ha detto sopra, in questa in quanto riceve molto più traffico, oltre ad arrivare per primo.
BoltClock

1
Dopo 13 anni, la bozza css-content-3 è stata finalmente aggiornata . La sezione pseudo-elementi è stata definitivamente rimossa a favore di css-pseudo-4, che non consente più ::before::afterpseudo-elementi.
Oriol

@Oriol: 12 anni, in realtà. l'FPWD di css-pseudo-4 è stato introdotto l'anno scorso, momento in cui css-content-3 era già stato aggiornato per indicare la nuova specifica.
BoltClock

@BoltClock La bozza dell'editor css-content-3 su drafts.csswg.org è stata aggiornata qualche tempo fa, ma la bozza funzionante su w3.org era ancora quella del 2003 fino a poco tempo fa. Avevo ancora qualche speranza ...
Oriol

31

Se il tuo elemento principale ha alcuni elementi figlio o testo, puoi utilizzarli.

Posiziona il tuo elemento principale relativo (o assoluto / fisso) e usa entrambi: prima e: dopo posizionato assoluto (nella mia situazione doveva essere assoluto, non so del tuo).

Ora se vuoi un altro pseudo-elemento, collega un assoluto: prima a uno dei figli dell'elemento principale (se hai solo testo, mettilo in uno span, ora hai un elemento), che non è relativo / assoluto / fisso .

Questo elemento inizierà a comportarsi come se il suo proprietario fosse il tuo elemento principale.

HTML

<div class="circle">
    <span>Some text</span>
</div>

CSS

.circle {
    position: relative; /* or absolute/fixed */
}

.circle:before {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

.circle:after {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

.circle span {
    /* not relative/absolute/fixed */
}

.circle span:before {
    position: absolute;
    content: "";
    /* more styles: width, height, etc */
}

2
Sebbene la risposta selezionata sia accurata, questa è stata una soluzione praticabile per il mio caso. Sono stato in grado di simulare la presenza di più elementi psuedo senza dover aggiungere più nodi al DOM!
matt.kauffman23

@ matt.kauffman23 quindi, potresti per favore dire come hai simulato?
BbIKTOP

1
@BbIKTOP scusa ho appena visto il tuo commento. Nel mio caso stavo lavorando su un modal che ha sempre avuto figli, quindi ho finito con qualcosa del tipo:.modal:first-child:before { …
matt.kauffman23

@ matt.kauffman23 A ricordare un dettaglio come questo dopo più di 6 anni, hai un bel ricordo!
ChrisOdney,

1

Ho risolto questo problema usando:

.element:before {
    font-family: "Font Awesome 5 Free" , "CircularStd";
    content: "\f017" " Date";
}

Usando la famiglia di caratteri "font awesome 5 free" per l'icona, e dopo, dobbiamo specificare il carattere che stiamo usando di nuovo perché se non lo facciamo, il navigatore userà il carattere predefinito (times new roman o qualcosa di simile Questo).

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.