El podcast de CSS 015: Seudoclases
Supongamos que tienes un formulario de registro de correo electrónico y deseas que el campo del formulario de correo electrónico tenga un borde rojo si contiene una dirección de correo electrónico no válida.
¿Cómo puede hacerlo?
Puedes usar una seudoclase :invalid
de CSS, que es una de las muchas seudoclases que proporciona el navegador.
Una seudoclase te permite aplicar estilos según los cambios de estado y factores externos. Esto significa que tu diseño puede reaccionar a las entradas del usuario, como una dirección de correo electrónico no válida. Estos se abordan en el módulo de selectores y, en este módulo, los analizaremos con más detalle.
A diferencia de los seudoelementos, sobre los que puedes obtener más información en el módulo anterior, las seudoclases se vinculan a estados específicos en los que puede estar un elemento, en lugar de partes de ese elemento en general de estilo.
Estados interactivos
Las siguientes seudoclases se aplican debido a una interacción que un usuario tiene con tu página.
:hover
Si un usuario tiene un dispositivo apuntador, como un mouse o un panel táctil, y lo coloca sobre un elemento, puedes conectarte a ese estado con :hover
para aplicar estilos.
Esta es una manera útil de indicar que se puede interactuar con un elemento.
:active
Este estado se activa cuando se interactúa de manera activa con un elemento (como un clic) antes de que se suelte este. Si se usa un dispositivo apuntador, como un mouse, este estado es cuando comienza el clic y aún no se suelta.
:focus
, :focus-within
y :focus-visible
Si un elemento puede recibir el enfoque, como un <button>
, puedes reaccionar a ese estado con la seudoclase :focus
.
También puedes reaccionar si un elemento secundario de tu elemento recibe el foco con :focus-within
.
Los elementos enfocables, como los botones, mostrarán un anillo de enfoque cuando estén enfocados, incluso cuando se haga clic en ellos. En este tipo de situación, un desarrollador aplicará el siguiente CSS:
button:focus {
outline: none;
}
Este CSS quita el anillo de enfoque predeterminado del navegador cuando un elemento recibe el foco, lo que presenta un problema de accesibilidad para los usuarios que navegan por una página web con un teclado.
Si no hay un estilo de enfoque, no podrán realizar un seguimiento de la ubicación actual del enfoque cuando usen la tecla Tab.
Con :focus-visible
, puedes presentar un estilo de enfoque cuando un elemento recibe el foco mediante el teclado y, al mismo tiempo, usar la regla outline: none
para evitarlo cuando un dispositivo puntero interactúa con él.
button:focus {
outline: none;
}
button:focus-visible {
outline: 1px solid black;
}
:target
La seudoclase :target
selecciona un elemento que tenga una id
que coincida con un fragmento de URL.
Supongamos que tienes el siguiente código HTML:
<article id="content">
…
</article>
Puedes adjuntar estilos a ese elemento cuando la URL contenga #content
.
#content:target {
background: yellow;
}
Esto es útil para destacar áreas a las que podrían estar vinculadas específicamente, como el contenido principal de un sitio web, mediante un vínculo de navegación.
Estados históricos
:link
La seudoclase :link
se puede aplicar a cualquier elemento <a>
que tenga un valor href
que todavía no haya visitado.
:visited
Puedes definir el estilo de un vínculo que ya visitó el usuario con la seudoclase :visited
.
Este es el estado opuesto a :link
, pero tienes menos propiedades de CSS para usar por motivos de seguridad.
Solo puedes aplicar ajustes de estilo a color
, background-color
, border-color
y outline-color
, y al color de SVG fill
y stroke
.
El orden es importante
Si defines un diseño :visited
, se puede anular con una seudoclase de vínculo con al menos la misma especificidad.
Por este motivo, te recomendamos que uses la regla de la LVHA para aplicar diseño a los vínculos con seudoclases en un orden específico: :link
, :visited
, :hover
y :active
.
a:link {}
a:visited {}
a:hover {}
a:active {}
Estados de formularios
Las siguientes seudoclases pueden seleccionar elementos de formulario, en los diversos estados en los que pueden estar estos elementos durante la interacción con ellos.
:disabled
y :enabled
Si el navegador inhabilita un elemento de formulario, como <button>
, puedes conectarte a ese estado con la seudoclase :disabled
.
La seudoclase :enabled
está disponible para el estado opuesto, aunque los elementos de forma también son :enabled
de forma predeterminada, por lo que es posible que no alcances esta seudoclase.
:checked
y :indeterminate
La seudoclase :checked
está disponible cuando un elemento de formulario complementario, como una casilla de verificación o un botón de selección, está marcado.
El estado :checked
es un estado binario(verdadero o falso), pero las casillas de verificación tienen un estado intermedio cuando no están marcadas ni desmarcadas.
Esto se conoce como el estado :indeterminate
.
Un ejemplo de este estado es cuando tienes un control "seleccionar todo" que marca todas las casillas de verificación en un grupo. Si el usuario desmarcara una de estas casillas de verificación, la casilla de verificación raíz ya no representaría que se marquen todas las opciones, por lo que debería pasar a un estado indeterminado.
El elemento <progress>
también tiene un estado indeterminado al que se le puede dar estilo.
Un caso de uso común es darle una apariencia a rayas para indicar que se desconoce cuánto más se necesita.
:placeholder-shown
Si el campo de un formulario tiene un atributo placeholder
y sin valor, se puede usar la seudoclase :placeholder-shown
para adjuntar diseños a ese estado.
En cuanto haya contenido en el campo, ya sea que tenga un placeholder
o no, este estado dejará de aplicarse.
Estados de validación
Puedes responder a la validación de formularios HTML con seudoclases, como :valid
, :invalid
y :in-range
.
Las seudoclases :valid
y :invalid
son útiles en contextos como un campo de correo electrónico que tiene un pattern
que debe coincidir, a fin de que sea un campo válido.
Este estado de valor válido se puede mostrar al usuario para ayudarlo a comprender que puede pasar de manera segura al siguiente campo.
La seudoclase :in-range
está disponible si una entrada tiene min
y max
, como una entrada numérica y el valor está dentro de esos límites.
Con los formularios HTML, puedes determinar si un campo es obligatorio con el atributo required
.
La seudoclase :required
estará disponible para los campos obligatorios.
Los campos que no son obligatorios se pueden seleccionar con la seudoclase :optional
.
Seleccionar elementos por índice, orden y caso
Hay un grupo de seudoclases que seleccionan elementos en función de dónde se encuentran en el documento.
:first-child
y :last-child
Si deseas encontrar el primer o el último elemento, puedes usar :first-child
y :last-child
.
Estas seudoclases mostrarán el primer o el último elemento en un grupo de elementos del mismo nivel.
:only-child
También puedes seleccionar elementos que no tengan elementos del mismo nivel, con la seudoclase :only-child
.
:first-of-type
y :last-of-type
Puedes seleccionar :first-of-type
y :last-of-type
, que, al principio, parecen hacer lo mismo que :first-child
y :last-child
, pero considera el siguiente código HTML:
<div class="my-parent">
<p>A paragraph</p>
<div>A div</div>
<div>Another div</div>
</div>
Y este CSS:
.my-parent div:first-child {
color: red;
}
Ningún elemento sería de color rojo porque el primer elemento secundario es un párrafo y no un div. La seudoclase :first-of-type
es útil en este contexto.
.my-parent div:first-of-type {
color: red;
}
Aunque el primer <div>
es el segundo elemento secundario, sigue siendo el primero de tipo dentro del elemento .my-parent
. Por lo tanto, con esta regla, será de color rojo.
:nth-child
y :nth-of-type
Tampoco estás limitado a los primeros y últimos tipos secundarios y tipos.
Las seudoclases :nth-child
y :nth-of-type
te permiten especificar un elemento que está en un índice determinado.
La indexación en los selectores CSS comienza en 1.
También puedes pasar más que un índice a estas seudoclases.
Si deseas seleccionar todos los elementos pares, puedes usar :nth-child(even)
.
También puedes crear selectores más complejos que encuentren elementos en intervalos espaciados con regularidad mediante la microsintaxis An+B.
li:nth-child(3n+3) {
background: yellow;
}
Este selector selecciona cada tercer elemento
a partir del elemento 3.
La n
en esta expresión es el índice, que comienza en cero y el 3 (3n
) es el valor por el que se multiplica ese índice.
Supongamos que tienes 7 elementos <li>
.
El primer elemento que se selecciona es 3 porque 3n+3
se traduce como (3 * 0) + 3
.
La siguiente iteración elegiría el elemento 6 porque n
ahora aumentó a 1
, por lo que es (3 * 1) + 3)
.
Esta expresión funciona para :nth-child
y :nth-of-type
.
Puedes experimentar con este tipo de selector en este nth-child-tester o en esta herramienta de selección de cantidad.
:only-of-type
Por último, puedes encontrar el único elemento de un tipo determinado en un grupo de elementos del mismo nivel con :only-of-type
.
Esto resulta útil si deseas seleccionar listas con un solo elemento o si deseas buscar el único elemento en negrita en un párrafo.
Cómo buscar elementos vacíos
A veces, puede ser útil identificar elementos completamente vacíos, y también existe una seudoclase para eso.
:empty
Si un elemento no tiene elementos secundarios, se les aplica la seudoclase :empty
.
Sin embargo, los elementos secundarios no son solo elementos HTML o nodos de texto: también pueden ser espacios en blanco, lo que puede resultar confuso cuando depuras el siguiente HTML y te preguntas por qué no funciona con :empty
:
<div>
</div>
Esto se debe a que hay un espacio en blanco entre el <div>
de apertura y de cierre, por lo que el valor vacío no funcionará.
La seudoclase :empty
puede ser útil si tienes poco control sobre el HTML y deseas ocultar elementos vacíos, como un editor de contenido WYSIWYG.
En este caso, un editor agregó un párrafo vacío suelto.
<article class="post">
<p>Donec ullamcorper nulla non metus auctor fringilla.</p>
<p></p>
<p>Curabitur blandit tempus porttitor.</p>
</article>
Con :empty
, puedes encontrarlo y ocultarlo.
.post :empty {
display: none;
}
Encontrar y excluir varios elementos
Algunas seudoclases te ayudan a escribir una CSS más compacta.
:is()
Si deseas encontrar todos los elementos secundarios h2
, li
y img
en un elemento .post
, te recomendamos escribir una lista de selectores como la siguiente:
.post h2,
.post li,
.post img {
…
}
Con la seudoclase :is()
, puedes escribir una versión más compacta:
.post :is(h2, li, img) {
…
}
La seudoclase :is
no solo es más compacta que una lista de selección, sino que también permite mayor flexibilidad.
En la mayoría de los casos, si hay un error o un selector no compatible en una lista de selectores, la lista completa de selectores dejará de funcionar.
Si hay un error en los selectores pasados en una seudoclase :is
, se ignorará el selector no válido, pero se usarán los que sean válidos.
:not()
También puedes excluir elementos con la seudoclase :not()
.
Por ejemplo, puedes usarlo para definir el estilo de todos los vínculos que no tengan un atributo class
.
a:not([class]) {
color: blue;
}
Una seudoclase :not
también puede ayudarte a mejorar la accesibilidad.
Por ejemplo, un <img>
debe tener un alt
, incluso si es un valor vacío, por lo que puedes escribir una regla de CSS que agregue un contorno rojo grueso a las imágenes no válidas:
img:not([alt]) {
outline: 10px red;
}
Verifica tus conocimientos
Pon a prueba tus conocimientos sobre seudoclases
Las pseudoclases actúan como si una clase se aplicara de forma dinámica a un elemento, mientras que los seudoelementos actúan sobre un elemento en sí.
:
simple o doble como carácter distintivo clave en el selector.¿Cuáles de las siguientes son una seudoclase funcional?
:is()
:target
()
después de ellas para indicar que aceptan parámetros.:empty
()
después de ellas para indicar que aceptan parámetros.:not()
¿Cuáles de las siguientes seudoclases se deben a una interacción del usuario?
:hover
:press
:squeeze
:target
:focus-within
¿Cuáles de las siguientes son seudoclases de estado <form>
?
:enabled
:fresh
:indeterminate
:checked
:in-range
:loading
:valid