Dado el siguiente escenario, ¿por qué el selector: after requiere una propiedad de contenido para funcionar?
.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; }
Observe cómo no ve el pseudo elemento hasta que especifique la propiedad de contenido:
.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"; }
¿Por qué es esta la funcionalidad prevista? Se podría pensar que el bloque de visualización obligaría al elemento a aparecer. Curiosamente, puedes ver los estilos dentro de depuradores web; sin embargo, no se muestran en la página.
Aquí hay algunas referencias a varias especificaciones y borradores del W3C:
Los pseudo-elementos ‘: before’ y ‘: after’ se pueden usar para insertar contenido generado antes o después del contenido de un elemento.
Los autores especifican el estilo y la ubicación del contenido generado con los pseudo-elementos: before y: after. Como indican sus nombres, los pseudo-elementos: before y: after especifican la ubicación del contenido antes y después del contenido del árbol de documentos de un elemento. La propiedad ‘contenido’, junto con estos pseudo-elementos, especifica qué se inserta.
Inicial: ninguno
Esta propiedad se usa con los pseudo-elementos: before y: after para generar contenido en un documento. Los valores tienen los siguientes significados:
none : el pseudo-elemento no se genera.
El estilo aplicado a los pseudoelementos :: before y :: after afecta la visualización del contenido generado. El atributo de content
es este contenido generado, y sin él presente, se asume el valor predeterminado de content: none
, lo que significa que no hay nada para que se aplique el estilo.
Si no quieres repetir el content:'';
varias veces, puede anular esto simplemente mediante el diseño global de todos los pseudo-elementos :: before y :: after dentro de su CSS ( ejemplo de JSFiddle ):
::before, ::after { content:''; }
En base a sus comentarios sobre las respuestas de los demás, creo que su pregunta es en realidad:
¿Por qué debe establecerse la propiedad de contenido para las pseudoclases en el CSS, en oposición al contenido de las no pseudoclases, que pueden configurarse en HTML o CSS?
La razón es que:
hacen, pero puede establecer su propiedad de contenido rápidamente mediante el marcado ( o con declaraciones CSS). Toma esta simple página:
Sabemos que esta página no mostrará nada, porque el elemento
no tiene texto. Una forma más precisa de reformular esto es que la propiedad de contenido del elemento
no tiene ningún valor .
Podemos cambiar esto fácilmente, configurando la propiedad de contenido del elemento h1 en el marcado HTML :
This sentence is the content of the p element.
Esto ahora se mostrará cuando se cargue, porque la propiedad de contenido del elemento
tiene un valor; ese valor es una cadena:
"This sentence is the content of the p element."
Alternativamente, podemos hacer que el elemento
se muestre estableciendo la propiedad de contenido del elemento
en el CSS :
p { content: "This sentence is the content of the p element set in the CSS."; }
Estas dos formas de inyectar la cadena en el elemento
son idénticas.
Ahora, considere hacer lo mismo con las pseudo-clases:
HTML: P
CSS: p:before { content: "BEFORE... " ; } p:after { content: " ...and AFTER"; }
El resultado:
BEFORE... P ...and AFTER
Finalmente, imagina cómo lograrías este ejemplo sin usar CSS. Es imposible, porque no hay forma de establecer el contenido de la pseudoclase en el marcado HTML.
Puede ser creativo e imaginar algo como esto podría funcionar:
BEFORE... P
...and AFTER
Pero no, porque
y
no son elementos HTML .
En conclusión:
La razón por la que necesita un content: ''
statement para cada pseudo-elemento ::before
y / or ::after
se debe a que el valor inicial del content
es normal
, que no computa a none
en los pseudo-elementos ::after
::before
y ::after
. Ver la especificación
La razón por la cual el valor inicial del content
no es una cadena vacía, sino un valor que no se computa para none
para los pseudo-elementos ::before
y ::after
, es doble:
Tener contenido en línea vacío al principio y al final de cada elemento es bastante tonto. Recuerde que el propósito original de los pseudo-elementos ::before
y ::after
es insertar el contenido generado antes y después del contenido principal de un elemento de origen. Cuando no hay contenido para insertar, crear un cuadro adicional solo para insertar nada no tiene sentido. Entonces el valor none
está allí para decirle al navegador que no se moleste en crear una caja adicional.
La práctica de usar pseudo-elementos vacíos ::before
y ::after
para crear cajas adicionales con el único propósito de la estética del diseño es relativamente nueva, y algunos puristas incluso pueden llegar a decir que es un truco por esta razón.
Tener contenido en línea vacío al principio y al final de cada elemento significa que cada elemento (no reemplazado), incluidos html
y body
, generaría de forma predeterminada no un cuadro, sino hasta tres cuadros (y más en el caso de los elementos que ya generar más que solo el cuadro principal, como elementos con estilos de lista). ¿Cuántas de las dos cajas adicionales por elemento usará realmente? Eso potencialmente puede triplicar el costo del diseño con muy poca ganancia.
De forma realista, incluso en esta década, menos del 10% de los elementos en una página necesitarán ::before
y ::after
pseudo-elementos para el diseño.
Por lo tanto, estos pseudoelementos se convierten en opt-in, porque hacer que se excluyan no solo es un desperdicio de recursos del sistema, sino simplemente ilógico dado su propósito original. La razón de rendimiento también es la razón por la que no recomiendo generar pseudo-elementos para cada elemento usando ::before, ::after
.
Pero luego puede preguntar: ¿por qué no hacer que la propiedad de display
no tenga valor predeterminado en none
en ::before, ::after
? Simple: porque el valor inicial de la display
no es none
; está en inline
Tener un cómputo en inline
de none
en ::before, ::after
no es una opción porque entonces nunca podría mostrarlos en línea. Tener el valor inicial de display
none
on on ::before, ::after
no es una opción porque una propiedad solo puede tener un valor inicial. (Esta es la razón por la que el valor inicial del content
siempre es normal
y simplemente se define para calcular none
en ::before, ::after
).
Hasta que agregue content: ...
, el elemento psuedo no existe en realidad.
Establecer otras propiedades de estilo no es suficiente para obligar al navegador a crear el elemento.