Perché gli pseudo-elementi: before e: after richiedono una proprietà ‘content’?

Dato il seguente scenario, perché il selettore: after richiede una proprietà content per funzionare?

Si noti come non si vede lo pseudo elemento fino a quando non si specifica la proprietà del contenuto:

 .test { width: 20px; height: 20px; background: blue; position:relative; } .test:after { width: 20px; height: 20px; background: red; display: block; position: absolute; top: 0px; left: 20px; content:"hi"; } 
 

Perché questa è la funzionalità prevista? Si penserebbe che il blocco di visualizzazione forzerebbe l’elemento a mostrare. Stranamente, puoi effettivamente vedere gli stili all’interno dei web debugger; tuttavia, non vengono visualizzati nella pagina.

Ecco alcuni riferimenti a varie specifiche e bozze di W3C:

Selettori di livello 3

Gli pseudo-elementi ‘: before’ e ‘: after’ possono essere utilizzati per inserire il contenuto generato prima o dopo il contenuto di un elemento.

Il: prima e: dopo pseudo-elementi

Gli autori specificano lo stile e la posizione del contenuto generato con gli pseudo-elementi: before e: after. Come indicano i loro nomi, gli pseudo-elementi: before e: after specificano la posizione del contenuto prima e dopo il contenuto della struttura del documento di un elemento. La proprietà ‘content’, insieme a questi pseudo-elementi, specifica cosa viene inserito.

L’attributo del contenuto

Iniziale: nessuno

Questa proprietà viene utilizzata con gli pseudo-elementi: before e: after per generare contenuto in un documento. I valori hanno i seguenti significati:

noneLo pseudoelemento non viene generato.


Lo stile applicato a :: before e :: after pseudo-elements influisce sulla visualizzazione del contenuto generato. L’attributo content è questo contenuto generato e, senza esso presente, il valore predefinito del content: none è assunto, il che significa che non vi è nulla a cui lo stile deve essere applicato.

Se non vuoi ripetere il content:''; più volte, puoi sovrascriverlo semplicemente definendo globalmente tutti gli pseudo-elementi all :: before e :: after all’interno del tuo CSS ( esempio JSFiddle ):

 ::before, ::after { content:''; } 

Sulla base dei tuoi commenti sulle risposte degli altri, credo che la tua domanda sia in realtà:

Perché la proprietà content per le pseudo-classi deve essere impostata nel CSS, diversamente dal contenuto delle non-pseudo-classi, che possono essere impostate in HTML o CSS?

Il motivo è questo:

  • per definizione, le pseudo-classi vengono create dynamicmente per ogni singolo elemento specificato dal markup HTML di una pagina
  • tutti gli elementi della pagina, comprese le pseudo-classi, devono avere una proprietà content da visualizzare.
  • Anche gli elementi HTML come

    fanno altrettanto, ma puoi impostare rapidamente la loro proprietà del contenuto usando markup ( o con dichiarazioni CSS).

  • Tuttavia, a differenza degli elementi non pseudo-class , le pseudo-classi non possono ricevere valori nel markup stesso.
    Pertanto, tutte le pseudo-classi sono invisibili (le loro proprietà ‘content’ non hanno valore) a meno che tu non dica loro di essere (dando loro un valore con le dichiarazioni CSS).

Prendi questa semplice pagina:

  

Sappiamo che questa pagina non mostrerà nulla, perché l’elemento

non ha testo. Un modo più accurato per riformulare questo, è che la proprietà del contenuto dell’elemento

non ha valore .

Possiamo facilmente cambiare questo, impostando la proprietà content dell’elemento h1 nel markup HTML :

  

This sentence is the content of the p element.

Questo verrà visualizzato quando caricato, perché la proprietà content dell’elemento

ha un valore; quel valore è una stringa:

 "This sentence is the content of the p element." 

In alternativa, possiamo far visualizzare l’elemento

impostando la proprietà content dell’elemento

nel CSS :

 p { content: "This sentence is the content of the p element set in the CSS."; } 

Questi due modi di iniettare la stringa nell’elemento

sono identici.

Ora, considera di fare la stessa cosa con le pseudo-classi:

 HTML:  

P

CSS: p:before { content: "BEFORE... " ; } p:after { content: " ...and AFTER"; }

Il risultato:

 BEFORE... P ...and AFTER 

Infine, immagina come realizzeresti questo esempio senza usare CSS. È imansible, perché non c’è modo di impostare il contenuto della pseudo-class nel codice HTML.

Potresti essere creativo e immaginare qualcosa del genere potrebbe funzionare:

 BEFORE...  

P

...and AFTER

Ma non è così, perché e non sono elementi HTML .

In conclusione:

  • Esistono classi di pseudo per ogni elemento di markup.
  • Sono invisibili di default, perché sono inizializzati senza proprietà del contenuto.
  • NON è ansible impostare la proprietà content per le pseudo classi con markup HTML.
    Pertanto, la proprietà del contenuto degli pseudo-elementi deve essere dichiarata con dichiarazioni CSS, per poter essere visualizzata.

La ragione per cui hai bisogno di un content: '' dichiarazione content: '' per ogni pseudo-elemento ::before e / o ::after è perché il valore iniziale del content è normal , che non calcola none sugli pseudo-elementi ::before e ::after . Vedi le specifiche

Il motivo per cui il valore iniziale del content non è una stringa vuota ma un valore che non calcola in none per gli pseudo-elementi ::before e ::after , è duplice:

  1. Avere contenuti inline vuoti all’inizio e alla fine di ogni elemento è piuttosto sciocco. Ricorda che lo scopo originale degli pseudo-elementi ::before e ::after è quello di inserire il contenuto generato prima e dopo il contenuto principale di un elemento di origine. Quando non ci sono contenuti da inserire, creare una casella aggiuntiva solo per inserire nulla è inutile. Quindi il valore none è lì per dire al browser di non preoccuparsi di creare una scatola aggiuntiva.

    La pratica dell’uso degli pseudo-elementi empty ::before e ::after per creare box aggiuntivi al solo scopo dell’estetica del layout è relativamente nuova, e alcuni puristi potrebbero persino spingersi fino al punto di chiamarlo un hack per questo motivo.

  2. Avere un contenuto in linea vuoto all’inizio e alla fine di ogni elemento significa che ogni elemento (non sostituito), inclusi html e body , genererebbe per impostazione predefinita non una casella, ma fino a tre caselle (e più nel caso di elementi che già generare più della semplice casella principale, come gli elementi con gli stili di lista). Quante delle due caselle aggiuntive per elemento utilizzerai effettivamente? Questo è potenzialmente triplicare il costo del layout per un guadagno molto piccolo.

    Realisticamente, anche in questo decennio, meno del 10% degli elementi di una pagina avrà mai bisogno di pseudo-elementi ::before e ::after per il layout.

E così questi pseudo-elementi sono fatti opt-in – perché farli opt-out non è solo uno spreco di risorse di sistema, ma semplicemente illogico dato il loro scopo originale. Il motivo della prestazione è anche il motivo per cui non consiglio di generare pseudo-elementi per ogni elemento usando ::before, ::after .

Ma allora potresti chiederti: perché la proprietà display non è none su none su ::before, ::after ? Semplice: perché il valore iniziale del display non è none ; è in inline . Avere inline computed to none su ::before, ::after non è un’opzione perché non è ansible visualizzarli in linea. Avere il valore iniziale di display essere none su ::before, ::after non è un’opzione perché una proprietà può avere solo un valore iniziale. (Questo è il motivo per cui il valore iniziale del content è sempre normal e viene semplicemente definito per calcolare su none su ::before, ::after .)

Fino a quando non aggiungi il content: ... , l’elemento psuedo in realtà non esiste .

L’impostazione di altre proprietà di stile non è sufficiente per forzare il browser a creare l’elemento.