logoCoderhouse.png
By Nicolas Alliaume • junio 28, 2016

Introducción a Pseudo-clases en CSS

Hola! Soy Nico, profe de Coderhouse en Uruguay. Hoy les traigo un post sobre Pseudo-clases de CSS.

¿Pseudo-qué?

Gran parte del CSS que escribimos son selectores, y la mayoría, por lo general, involucra clases. Las clases permiten identificar a uno o más elementos que, a efectos de CSS, comparten estilos. Por ejemplo, podemos tener una clase 'boton', y estilizarla para que todos los botones del sitio tengan el mismo estilo cuando les agregamos esa clase.

Las PSEUDO-clases, por otro lado, no son clases comunes de CSS. De hecho, no aparecen en el HTML de nuestros sitios. Son un recurso que utilizaremos desde CSS para:

1 - Estilizar estados de los elementos
2 - Estilizar elementos que cumplen algunas características, por ejemplo, de posicionamiento

Las pseudo-clases ya están definidas en la especificación de CSS, y son muy fáciles de usar. Veamos como hacerlo.

1- Estilizar estados de los elementos

Muchas veces queremos que los elementos de una página, principalmente aquellos que son interactivos, tengan un estilo distinto por momentos. ¿Notaste alguna vez que los links que ya visitaste en Google están en un color distinto, más violeta? Los links visitados son un ejemplo muy común de pseudo-clases CSS. También los son los botones cuando pasamos el mouse por arriba.

CSS define varios estados que podemos utilizar para personalizar los estilos. En el caso de los links, los estados son: visited (visitado), hover (mouse por encima), active (activo) y link (no visitado). Veamos un ejemplo de como usar estos estados.

a {
font-size: 12pt;
font-family: Roboto, sans-serif;
}

a:link {
color: black;
}

a:visited {
color: grey;
}

a:active, a:hover {
color: green;
}

En este ejemplo definimos el estilo base para todos los links con el selector "a", y luego le damos estilos distintos, particulares a cada uno de los estados: queremos que los links no visitados sean negros, que los visitados sean grises, y que cuando estén activos o con el mouse por encima sean verdes.

He encontrado que el estado "active" es el más dificil de entender. Basicamente, cuando usamos un mouse para navegar, es un estado que existe entre el momento en el que se hace click y se suelta, pero también es se activa cuando se navega entre los elementos usando <tab>.

El estado "hover" es el más usado, ya que se puede utilizar con cualquier tipo de elemento. Veamos otro ejemplo.

<html>
<head>
<style>
div { /* 1 */
background: green;
height: 300px;
width: 300px;
}

div > div { /* 2 */
background: blue;
height: 150;
width: 150;
}

div:hover { /* 3 */
background: yellow;
}

div > div:hover { /* 4 */
background: red;
}
</style>
</head>
<body>
<div>
<div></div>
</div>
</body>
</html>

En este caso tenemos 3 estilos distintos que podemos observar: azul y verde, amarillo y azul, y amarillo y rojo. Cuando recien cargamos la página y posicionamos el mouse fuera de todos los elementos, se verán 2 cuadrados, uno dentro del otro, de colores verde y azul (comentarios 1 y 2). Cuando posicionamos el mouse encima del cuadrado más grande, pero fuera del más chico, veremos que el más grande cambia a color amarillo (comentario 3). Al mover el mouse por encima del cuadrado más chico, veremos que cambia a rojo, y el de afuera permanece amarillo (comentario 4). Ésto último sucede porque el cuadrado chico está dentro del grande. Tecnicamente, cuando estamos sobre el chico, también estamos sobre el grande que está detrás.

Mouse fuera de todo Mouse fuera de todo

Mouse dentro del grande Mouse dentro del grande

Mouse dentro del chico Mouse dentro del chico

Podemos usar h:hover con botones, listas, secciones, hasta el body mismo.

<html>
<head>
<style>
body {
background-color: #000;
}
body:hover {
background-color: #aaa;
}
</style>
</head>
<body></body>
</html>

Mouse fuera del body Mouse fuera del body

Mouse dentro del body Mouse dentro del body

También existen estados como :checked, que podemos utilizar con checkboxes. Veamos un ejemplo.

<html>
<head>
<meta charset="UTF-8">
<style>
body {
padding: 30px;
}
input {
display: block;
margin: 10px 20px;
padding: 2px;
}
input[type="checkbox"] {
display: inline-block;
margin-right: 5px;
}
input[name="codigo_descuento"] {
display: none;
}
#descuento:checked ~ input[name="codigo_descuento"] {
display: block;
}
</style>
</head>
<body>
<form>
<input name="email" type="email" placeholder="Email" required>
<input name="nombre" type="text" placeholder="Nombre completo" required>
<input name="descuento" type="checkbox" id="descuento">
<label for="descuento">Tengo un código de descuento</label>
<input name="codigo_descuento" type="text" placeholder="Código">
<input type="submit" value="Continuar">
</form>
</body>
</html>

En este caso, si marcamos el checkbox "Tengo un código de descuento" aparecerá el input para colocar el código. El selector ~ busca elementos que compartan el mismo padre (un hermano), en este caso, el input del código de descuento.

Combo no checked Combo no checked

Combo checked Combo checked

2- Estilizar elementos que cumplen alguna característica

Muchas veces necesitamos personalizar los estilos de algunos elementos aunque no haya interacción del usuario. Por ejemplo, cuando hacemos un menú horizontal, por lo general separamos los elementos usando un márgen en uno de sus laterales. Pero ya sea que usemos margen a la derecha o a la izquierda, uno de sus elementos (el primero si usamos márgen izquierdo o el último si usamos márgen derecho) tendrá un margen innecesario. Algo asi:

<html>
<head>
<meta charset="UTF-8">
<style>
body {
padding: 40px;
}
ul {
padding-left: 0;
list-style: none;
}
li {
display: inline-block;
margin-right: 20px;
}
</style>
</head>
<body>
<ul>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</body>
</html>

Margen derecho innecesario Margen derecho innecesario

Para quitar el margen derecho innecesario del último elemento, podemos agregar una simple regla CSS usando la pseudo-clase "last-child".

li:last-child {
margin-right: 0;
}

Sin margen derecho Sin margen derecho

Si hubiesemos utilizado margen-left, la solución es usando :first-child, un pseudo-clase que selecciona al primer elemento hijo de un padre.

Algunas veces necesitamos seleccionar hijos que no son ni el primero ni el último, y para eso existe nth-child, que es una pseudo-clase que recibe un parámetro. Veamos un ejemplo.

li:nth-child(3) {
font-weight: bold;
}

En este caso, al 3er elemento de la lista lo ponemos en negrita.
Si sos programador, atento: el primer elemento es índice 1.

Elemento en negrita

Piques a la hora de desarrollar

Las pseudo-clases interactivas (:hover, :visited, etc) pueden ser molestas a la hora de desarrollar cuando intentás mirar cómo se ven y usar el inspector web al mismo tiempo.

Particularmente utilizo Chrome para desarrollar frontend, y la consola tiene una utilidad muy buena para esto. Tiene una opción donde se puede elegir qué estado (hover, active, focus, visited) queremos que tenga un elemento sin importar la interacción del usuario, lo que permite debuggear los estilos mucho más facilemte.

Hay mas de una forma de hacer esto en Chrome:

Comentarios finales

Existen muchas más pseudo-clases que las que hemos visto en este post. Podés ver la lista completa de pseudo-clases en está página de la W3Schools.

Rara vez te vas a escapar de usarlas cuando desarrolles un sitio. Te invito a que mires la lista completa y pruebes algunos de ellos para y agarrándoles la mano!