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.
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>
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
::beforey::afterson invisibles sincontent. La propiedadcontentes obligatoria. Si se omite, el pseudo-elemento no existe.content: ""(cadena vacía) sí crea el pseudo-elemento — útil para efectos visuales conposition: absolute,width,height,background, etc.- El contenido generado no es accesible. Screen readers tratan
::before/::afterde manera inconsistente. Nunca pongas información importante (como texto que el usuario necesite leer o copiar) encontent. Para iconos decorativos, ok. Para texto informativo, usá HTML real. contentacepta 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. ::placeholdertiene soporte de vendors histórico. Antes de ser estándar usaba prefijos como::-webkit-input-placeholder. Hoy::placeholdertiene 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.