concepto CSS vigente

Pseudo-elementos

Fundamentos de CSS

Los pseudo-elementos son selectores que crean o apuntan a una sub-parte de un elemento que no existe como nodo en el HTML, como ::before y ::after para insertar contenido generado, o ::first-line para estilizar solo la primera línea de un párrafo.

Un pseudo-elemento es un selector que apunta a una parte de un elemento que no existe como nodo propio en el árbol HTML — o que crea un nodo virtual que tampoco existe en el HTML pero que el navegador renderiza como si existiera. La sintaxis es :: (doble dos puntos) seguido del nombre del pseudo-elemento, pegado al selector del elemento al que pertenece.

La diferencia conceptual con las pseudo-clases (:) es importante: una pseudo-clase selecciona un elemento según su estado o posición (p:first-child selecciona el párrafo que es primer hijo), mientras que un pseudo-elemento selecciona o crea una parte del elemento (p::first-line selecciona solo la primera línea del texto del párrafo). No seleccionan el elemento completo — seleccionan un fragmento de él, real o virtual.

::before y ::after son los más usados y también los más potentes: permiten insertar contenido generado antes o después del contenido de un elemento, sin modificar el HTML. Esto es la base de muchas técnicas CSS: decoraciones visuales, íconos, badges, bullets personalizados, separadores. El contenido generado no es parte del DOM accesible — no puede ser seleccionado por el usuario, no es copiable de la manera esperada, y los lectores de pantalla lo ignoran (en la mayoría de los casos). Por eso se usa para contenido decorativo, nunca para contenido informativo que el usuario deba leer o copiar.

::before virtual content: "★" <p> contenido real del HTML </p> ::after virtual content: "→" los pseudo-elementos no existen en el HTML — los crea CSS

Cómo funciona

::before — contenido generado antes del elemento

::before inserta un nodo virtual justo antes del contenido del elemento. Requiere obligatoriamente la propiedad content para existir — sin content, no se renderiza nada (aunque content: "" cadena vacía es válido y útil para efectos puramente visuales).

.nota::before {
  content: "📌 ";
  font-weight: bold;
}
<p class="nota">Recordá guardar el archivo.</p>

📌 Recordá guardar el archivo.

El pseudo-elemento ::before se comporta como un elemento inline por defecto, aunque se le puede cambiar el display. Hereda los estilos del elemento padre, incluyendo color y font-family, salvo que se sobreescriban explícitamente.

::after — contenido generado después del elemento

Funciona idénticamente a ::before, pero el contenido generado aparece justo después del contenido del elemento.

.precio::after {
  content: " USD";
  font-size: 0.75em;
  color: gray;
}
<span class="precio">29.99</span>
29.99 USD

Juntos, ::before y ::after son la base de muchas técnicas CSS: bullets personalizados en listas, decoraciones con bordes, badges de conteo, iconos de íconos de fuente, el clásico clearfix para floats y muchos efectos visuales sin JavaScript.

::first-line — primera línea de un bloque de texto

Aplica estilos solo a la primera línea renderizada de un elemento de bloque. La primera línea varía según el ancho del contenedor — el navegador lo recalcula automáticamente al redimensionar la ventana.

p::first-line {
  font-weight: bold;
  font-variant: small-caps;
}

Solo acepta un subconjunto de propiedades CSS (tipografía, color, background). No acepta propiedades de layout (margin, padding, etc.).

::placeholder — texto de placeholder en inputs

Estiliza el texto de marcador de posición de <input> y <textarea>.

input::placeholder {
  color: #94a3b8;
  font-style: italic;
}
<input type="text" placeholder="Escribí tu nombre...">

La diferencia : vs :: — el gotcha más frecuente

La doble dos puntos :: identifica pseudo-elementos; el simple : identifica pseudo-clases. En CSS2 ambos usaban : simple, lo que creó ambigüedad. CSS3 estandarizó :: para pseudo-elementos para distinguirlos claramente.

a:hover    { }  /* pseudo-clase — estado del elemento */
p::before  { }  /* pseudo-elemento — parte creada del elemento */

Los browsers modernos siguen soportando la sintaxis : para los pseudo-elementos más antiguos (:before, :after, :first-line, :placeholder) por retrocompatibilidad, pero la forma correcta y actual es siempre ::. La confusión más común: escribir :before en lugar de ::before — funciona, pero es estilo CSS2 y puede causar confusion al leer código.

Gotchas conceptuales

  • ::before y ::after son invisibles sin content. La propiedad content es obligatoria. Si se omite, el pseudo-elemento no existe. content: "" (cadena vacía) sí crea el pseudo-elemento — útil para efectos visuales con position: absolute, width, height, background, etc.
  • El contenido generado no es accesible. Screen readers tratan ::before/::after de manera inconsistente. Nunca pongas información importante (como texto que el usuario necesite leer o copiar) en content. Para iconos decorativos, ok. Para texto informativo, usá HTML real.
  • content acepta varios tipos. Cadena de texto ("★"), contador CSS (counter()), atributo del HTML (attr(href)), imagen (url()). La cadena vacía "" es la más común para efectos puramente visuales.
  • No se puede seleccionar texto de ::before/::after. El contenido generado no es parte del DOM seleccionable — el usuario no puede copiarlo con Ctrl+C como lo haría con texto normal.
  • ::placeholder tiene soporte de vendors histórico. Antes de ser estándar usaba prefijos como ::-webkit-input-placeholder. Hoy ::placeholder tiene soporte universal; los prefijos son código legacy.

Vigente / legacy

::before, ::after, ::first-line y ::placeholder son vigentes con soporte universal. La sintaxis :: (doble dos puntos) es CSS3 y reemplaza la sintaxis : de CSS2, que sigue funcionando en browsers pero es legacy. Pseudo-elementos más nuevos como ::marker (para bullets de lista) y ::selection (texto seleccionado) tienen soporte amplio en browsers modernos pero no están en el temario de este nivel.