Warning ::before/::after sin declaración content

Por qué ::before y ::after no se renderizan en absoluto sin una propiedad content, aunque sea solo con una cadena vacía.

El validador marca un bloque de regla ::before o ::after no vacío (también coincide con la sintaxis más antigua de un solo dos puntos :before/:after) que no tiene ninguna declaración content en ninguna parte.

Ejemplo

/* Incorrecto: nunca se renderiza, sin importar qué más esté definido */
.insignia::before {
  background: red;
  width: 8px;
  height: 8px;
}

/* Correcto */
.insignia::before {
  content: "";
  background: red;
  width: 8px;
  height: 8px;
}

Por qué importa

Según la especificación CSS, ::before y ::after generan un pseudo-elemento solo cuando su propiedad content se computa a algo distinto de none — el valor por defecto. Sin ninguna declaración content, content permanece en su valor por defecto de none, y el pseudo-elemento simplemente no existe en el árbol de renderizado — ninguna de las demás declaraciones de la misma regla (background, border, width, height, transforms) tiene nada a lo cual aplicarse. Para un elemento puramente decorativo sin texto real, content: ""; (una cadena vacía) es la forma estándar de satisfacer este requisito sin renderizar ningún contenido de texto.

Frequently asked questions

¿content: none también falla al renderizarse, igual que no tener content?

Sí — content: none es explícitamente lo mismo que el valor inicial de la propiedad, así que un pseudo-elemento con cualquiera de los dos, sin declaración content o con content: none, permanece sin renderizarse. Cualquier otro valor, incluida una cadena vacía, sí lo genera.

¿Por qué esta regla llegaría a no tener una declaración content en código real?

Generalmente porque content: "" se eliminó durante una refactorización (por ejemplo, al limpiar otras propiedades) sin notar que era imprescindible, o porque un desarrollador que viene de un framework donde los pseudo-elementos no existen asumió que un background/width/height bastaba por sí solo.