CSS: después de no agregar contenido a ciertos elementos

Tengo problemas para entender el comportamiento del CSS :after propiedad. De acuerdo con la especificación ( aquí y aquí ):

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.

Esto no parece imponer restricciones sobre qué elementos pueden tener una propiedad :after (o :before ). Sin embargo, parece que solo funciona con elementos específicos …

funciona, no, does not,

does. Podría probar más, pero el punto está hecho. Tenga en cuenta que esto parece bastante uniforme en todos los navegadores. ¿Qué determina si un objeto puede aceptar a :before y :after propiedad?

img y input son ambos elementos reemplazados .

Un elemento reemplazado es cualquier elemento cuya apariencia y dimensiones están definidas por un recurso externo. Los ejemplos incluyen imágenes ( tags), complementos ( tags) y elementos de formulario ( , , y tags). Todos los demás tipos de elementos se pueden denominar elementos no reemplazados.

:before y :after solo :after trabajar con elementos no reemplazados.

De la especificación :

Nota. Esta especificación no define completamente la interacción de :before y :after con los elementos reemplazados (como IMG en HTML). Esto se definirá con más detalle en una especificación futura.

Con span:before, span:after , el DOM se ve así:

 Content of span 

Evidentemente, eso no funcionará con .

:before y :after no están obligados a trabajar para elementos reemplazados, y las especificaciones de CSS no especifican cómo funcionarían para ellos, y el concepto de elemento reemplazado es algo vago.

La especificación CSS 2.1 sugiere claramente que pueden funcionar para elementos reemplazados, simplemente diciendo que no “define completamente” cómo. Esto se relaciona con el problema de que se espera que un elemento reemplazado tenga su propia representación visual, que no está controlada por CSS, mientras que los pseudoelementos deberían agregar algo al contenido del elemento. La especificación agrega que esto se definirá “con más detalle” en una especificación futura, pero esto no ha tenido lugar hasta el momento.

Los vendedores del navegador simplemente decidieron evitar problemas al no implementar estos pseudo-elementos para algunos elementos.

No está claro para nada qué significa “elemento reemplazado”, y el significado parece haber cambiado algo. A menudo se interpreta como que significa lo mismo que elemento vacío (un elemento con contenido declarado EMPTY , es decir, un elemento que no puede contener ningún contenido), pero CSS 2.1 muestra una hoja de estilos de muestra con el selector br:before (aunque los navegadores han ignorado esto , implementando br su propio camino). Se puede argumentar que cada vez más elementos se han movido dentro del scope de la representación CSS, al menos en parte. Por ejemplo, un elemento de input (incluyendo su fuente, colores, etc.) es ampliamente controlable con CSS en los navegadores modernos.

Los navegadores actuales (Firefox, IE, Chrome) no parecen ser compatibles con :after y :before pseudo-elements para elementos vacíos que no sean hr . Por hr , IE y Chrome colocan el contenido generado dentro de un cuadro delimitado, que es la implementación de hr ; el contenido hace que la caja sea más alta. Firefox coloca el contenido de ambos (!) Pseudo-elementos después de la regla horizontal que es su implementación de hr . Esta variación ilustra los tipos de problemas de “interacción” a los que se hace referencia en CSS 2.1.

A menudo se afirma que estos pseudo-elementos no se pueden usar para elementos vacíos ya que sus definiciones HTML no permiten ningún contenido. Este es un error de categoría. Las reglas de syntax de un lenguaje de marcado no restringen lo que puedes hacer en CSS

Para concluir :after y :before actualmente no se pueden usar para elementos vacíos (excepto marginalmente para hr ), pero esto se debe principalmente a implementaciones y puede cambiar en el futuro.

Los elementos que no tienen etiqueta de cierre son elementos vacíos y no pueden mostrar contenido dentro de ellos:

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

Todos los navegadores Blink, Webkit y Quantum le permiten crear pseudoelementos solo en casillas de verificación, pero esto es controvertido ya que ninguna especificación permite este comportamiento.

Aquí un ejemplo: 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%); } } }