CSS: dopo non aver aggiunto contenuto a determinati elementi


100

Ho problemi a comprendere il comportamento della :afterproprietà CSS . Secondo le specifiche ( qui e qui ):

Come indica il loro nome, le :beforee :afterpseudo-elementi specificano la posizione del contenuto prima e dopo il contenuto albero del documento di un elemento.

Ciò non sembra porre restrizioni su quali elementi possono avere una :after(o :before) proprietà. Tuttavia, sembra di lavorare solo con specifici elementi ... <p>opere, <img>non lo fa, <input>non lo fa, <table>lo fa. Potrei testare di più, ma il punto è chiaro. Nota che questo sembra abbastanza coerente tra i browser. Cosa determina se un oggetto può accettare una proprietà :beforee :after?

Risposte:


156

imge inputsono entrambi elementi sostituiti .

Un elemento sostituito è qualsiasi elemento il cui aspetto e le cui dimensioni sono definite da una risorsa esterna. Esempi includono immagini ( <img>tag), plugin ( <object>tag), e gli elementi di forma ( <button>, <textarea>, <input>, e <select>tag). Tutti gli altri tipi di elementi possono essere indicati come elementi non sostituiti.

:beforee :afterfunziona solo con elementi non sostituiti.

Dalle specifiche :

Nota. Questa specifica non definisce completamente l'interazione di :beforee :aftercon gli elementi sostituiti (come IMG in HTML). Ciò sarà definito in maggiore dettaglio in una specifica futura.

Con span:before, span:after, il DOM ha questo aspetto:

<span><before></before>Content of span<after></after></span>

Evidentemente, questo non funzionerà <img src="" />.


2
"Il contenuto generato non altera l'albero del documento." Quindi sarei sorpreso se fossi in grado di trovare qualcosa come " <before></before>" nella sorgente.
Knu

4
@Knu: hai ragione, l'ho spiegato male. Non troverai mai <before></before>. Avrei dovuto dire "fingi DOM" o qualcosa del genere. Il punto era dimostrarlo :beforee :aftersono dentro l'elemento, non al di fuori di esso.
trenta punti il

No, non sono archiviati nel DOM ombra.
strumento

3
Le specifiche citate non lo dicono :beforee :afternon funzionano per elementi sostituiti; dice solo che non "definisce completamente" come e che questo verrà definito in futuro (cosa che finora non è accaduta). Quello che succede in DOM è irrilevante qui. Sebbene i browser non supportino il supporto di questi pseudo-elementi per alcuni elementi, questo non è nelle specifiche, ma solo ciò che fanno le implementazioni.
Jukka K. Korpela

Consideravo logica la spiegazione che ::beforee ::afternon funzionano per elementi void (vuoti) che non hanno mai un contenuto effettivo, prima / dopo il quale potevano essere applicati. Ma sorprendentemente, funzionano per hrelement in quasi tutti i browser.
Ilya Streltsyn

9

:beforee :afternon sono tenuti a lavorare per elementi sostituiti e le specifiche CSS non specificano come funzionerebbero per loro, e il concetto di elemento sostituito è alquanto vago.

La specifica CSS 2.1 suggerisce chiaramente che possono funzionare per elementi sostituiti, semplicemente dicendo che non "definisce completamente" come. Ciò si riferisce al problema per cui ci si aspetta che un elemento sostituito abbia il proprio rendering visivo, che non è controllato dai CSS, mentre gli pseudo-elementi dovrebbero aggiungere qualcosa al contenuto dell'elemento. La specifica aggiunge che questo sarà definito "in modo più dettagliato" in una specifica futura, ma finora non è avvenuto.

I fornitori di browser hanno semplicemente deciso di evitare problemi non implementando affatto questi pseudo-elementi per alcuni elementi.

Non è affatto chiaro cosa significhi "elemento sostituito" e il significato sembra essere leggermente cambiato. Viene spesso interpretato nel senso che significa lo stesso di un elemento vuoto (un elemento con EMPTYcontenuto dichiarato, cioè un elemento che non può avere alcun contenuto), ma CSS 2.1 stesso mostra un foglio di stile di esempio con il selettore br:before(sebbene i browser lo abbiano ignorato, implementando bril proprio modo). Si può sostenere che sempre più elementi sono entrati nell'ambito del rendering CSS, almeno in parte. Ad esempio, un inputelemento (inclusi il carattere, i colori, ecc.) È ampiamente controllabile con CSS nei browser moderni.

Browser attuali (Firefox, IE, Chrome) non sembrano sostenere l' :aftere :beforepseudo-elementi per elementi vuoti diversi hr. Per hrIE e Chrome posizionano il contenuto generato all'interno di una casella delimitata, che è l'implementazione di hr; il contenuto rende la scatola più alta. Firefox colloca il contenuto di entrambi (!) Pseudo-elementi dopo la regola orizzontale di cui è implementata hr. Questa variazione illustra i tipi di problemi di "interazione" a cui si fa riferimento in CSS 2.1.

Si afferma spesso che questi pseudo-elementi non possono essere utilizzati per elementi vuoti poiché le loro definizioni HTML non consentono alcun contenuto. Questo è un errore di categoria. Le regole di sintassi di un linguaggio di markup non limitano ciò che puoi fare in CSS

Per concludere, :aftere :beforeattualmente non sono utilizzabili per elementi vuoti (eccetto marginalmente per hr), ma ciò è dovuto principalmente alle implementazioni e potrebbero cambiare in futuro.


-1

Gli elementi che non hanno un tag di chiusura sono elementi void e non possono visualizzare il contenuto al loro interno:

https://www.w3.org/TR/html5/syntax.html#void-elements

Tutti i browser Blink, Webkit e Quantum consentono di creare pseudo elementi solo sulle caselle di controllo, ma questo è controverso poiché nessuna specifica consente questo comportamento.

Ecco un esempio: https://codepen.io/equinusocio/pen/BOBaEM/

input[type="checkbox"] {
  appearance: none;
  color: #000;
  width: 42px;
  height: 24px;
  border: 1px solid currentColor;
  border-radius: 100px;
  cursor: pointer;
  transition: all 100ms;
  background-size: 30%;
  outline: none;
  position: relative;
  box-sizing: border-box;
  background-color: #eee;
  transition: background-color 200ms;

  &::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    bottom: 2px;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background-color: currentColor;
    will-change: transform;
    transition: transform 200ms cubic-bezier(.01,.65,.23,1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  &:checked {
    background-color: aquamarine;

    &::before {
      transform: translateX(100%);
    }
  }
}

non funzionerà in tutti i browser ... e non ci sono specifiche che dicano che ora possiamo .. se ne hai uno, condividilo perché non è sicuro considerare pseudo elemento con input
Temani Afif

Funziona in tutti i browser tranne IE. Anche flexbox non è supportato da IE 9, quindi dov'è il problema. Questa soluzione funziona su tutti i browser Blink, Webkit e Quantum e può essere molto utile per le persone che lavorano in ambienti solo webkit come Electron.
Mattia Astorino

Come hai detto nella tua risposta, non ci sono specifiche per questo, quindi un giorno potrebbe smettere di funzionare. Non è l'unica cosa che si comporta e funziona senza specifiche definite, ma non dovremmo mai fare affidamento su di loro e dire che funzionano. è come tag obsoleti, funzionano ancora ma dovremmo smettere di usarli perché un giorno non lo faranno. Quindi sì, questo può essere utile alle persone ei miei commenti sono utili anche per avvertire le persone che dovrebbero essere consapevoli che questo non è ufficiale.
Temani Afif
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.