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

100

Tengo problemas para comprender el comportamiento de la :afterpropiedad CSS . Según la especificación ( aquí y aquí ):

Como sus nombres indican, las :beforey los :afterpseudo-elementos 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 ... <p>funciona, <img>no lo <input>hace , no lo <table>hace. Podría probar más, pero el punto está claro. Tenga en cuenta que esto parece bastante consistente en todos los navegadores. ¿Qué determina si un objeto puede aceptar una propiedad :beforey :after?

eykanal
fuente

Respuestas:

156

imgy inputambos son elementos reemplazados .

Un elemento reemplazado es cualquier elemento cuya apariencia y dimensiones están definidas por un recurso externo. Los ejemplos incluyen imágenes ( <img>etiquetas), plugins ( <object>etiquetas), y elementos de formulario ( <button>, <textarea>, <input>, y <select>tags). Todos los demás tipos de elementos pueden denominarse elementos no reemplazados.

:beforey :aftersolo funciona con elementos no reemplazados.

De la especificación :

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

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

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

Evidentemente, eso no funcionará con <img src="" />.

treinta y dos
fuente
2
"El contenido generado no altera el árbol del documento". Así que me sorprendería que pudieras encontrar algo como " <before></before>" en la fuente.
2011
4
@Knu: Tienes razón, lo expliqué mal. Nunca encontrarás <before></before>. Debería haber dicho "fingir DOM" o algo así. El punto era mostrar que :beforey :afterestán dentro del elemento, no fuera de él.
thirtydot
No, no se almacenan en la sombra DOM.
herramienta
3
La especificación citada no dice eso :beforey :afterno funciona para elementos reemplazados; simplemente dice que no "define completamente" cómo y que esto se definirá en el futuro (lo que no ha sucedido hasta ahora). Lo que sucede en DOM es irrelevante aquí. Si bien los navegadores no admiten estos pseudoelementos para algunos elementos, esto no está en las especificaciones, solo lo que hacen las implementaciones.
Jukka K. Korpela
Solía ​​considerar lógica la explicación de que ::beforey ::afterno funciona para elementos nulos (vacíos) que nunca tienen contenido real, antes / después de lo cual podrían aplicarse. Pero, sorprendentemente, funcionan como hrelemento en casi todos los navegadores.
Ilya Streltsyn
9

:beforey :afterno es necesario que funcionen para elementos reemplazados, y las especificaciones 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 ocurrido hasta ahora.

Los proveedores de navegadores simplemente decidieron evitar problemas al no implementar estos pseudoelementos para algunos elementos.

No está nada claro qué significa "elemento reemplazado", y el significado parece haber cambiado un poco. A menudo se interpreta que significa lo mismo que elemento vacío (un elemento con EMPTYcontenido declarado, es decir, un elemento que no puede tener ningún contenido), pero CSS 2.1 muestra una hoja de estilo de muestra con el selector br:before(aunque los navegadores han ignorado esto, implementando brsu propio camino). Se puede argumentar que cada vez más elementos se han movido al alcance de la representación CSS, al menos en parte. Por ejemplo, un inputelemento (incluida su fuente, colores, etc.) se puede controlar en gran medida con CSS en los navegadores modernos.

No parecen navegadores (Firefox, IE, Chrome) para apoyar el :aftery :beforepseudo-elementos para los elementos vacíos distintos hr. Porque hr, IE y Chrome colocan el contenido generado dentro de un cuadro con borde, que es la implementación de hr; el contenido hace que la caja sea más alta. Firefox coloca el contenido de ambos (!) Pseudoelementos después de la regla horizontal que es su implementación 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 pseudoelementos no se pueden utilizar para elementos vacíos ya que sus definiciones HTML no permiten ningún contenido. Este es un error de categoría. Las reglas de sintaxis de un lenguaje de marcado no restringen lo que puede hacer en CSS

Para concluir, :aftery :beforeactualmente no son utilizables para los elementos vacíos (excepto marginalmente a hr), pero esto se debe principalmente a las implementaciones y puede cambiar en el futuro.

Jukka K. Korpela
fuente
-1

Los elementos que no tienen etiqueta de cierre son elementos nulos 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 pseudo elementos solo en las 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%);
    }
  }
}
Mattia Astorino
fuente
no funcionará en todos los navegadores ... y no hay ninguna especificación que diga que ahora podemos ... si tienes uno, compártelo porque no es seguro considerar un pseudo elemento con entrada
Temani Afif
Funciona en todos los navegadores excepto IE. Incluso flexbox no es compatible con IE 9, así que ¿dónde está el problema? Esta solución funciona en todos los navegadores Blink, Webkit y Quantum y puede ser muy útil para las personas que trabajan en entornos de solo webkit como Electron.
Mattia Astorino
Como dijo en su respuesta, no hay especificaciones para ello, por lo que algún día puede dejar de funcionar. No es lo único que se comporta y funciona sin ninguna especificación definida, pero nunca debemos confiar en ellos y decir que funcionan. es como etiquetas obsoletas, todavía funcionan, pero deberíamos dejar de usarlas porque algún día no lo harán. Entonces sí, esto puede ser útil para las personas y mis comentarios también son útiles para advertir a las personas que deben ser conscientes de que esto no es oficial.
Temani Afif