Los hijos: first last only

publicado en la categoría CSS
Las pseudo-clases :first-xxxx seleccionan el primer elemento que cumple cierta condición; por el contrario, las pseudo-clases :last-xxxx hacen lo mismo pero contando de atrás hacia adelante.

La definición de pseudo-clase nos dice que es una forma de distinguir entre los diferentes tipos de etiquetas en función de alguna de sus características. Y la regla de sintaxis nos indica que se identifican con un carácter :.

Las pseudo-clases :first-xxxx seleccionan el primer elemento que cumple cierta condición; por el contrario, :last-xxxx hacen lo mismo pero contando de atrás hacia adelante.

La pseudo-clase :first-child selecciona el primer elemento que se encuentra dentro de otro o dicho de otro modo, los elementos hijos. Por ejemplo, en un div agregamos una serie de etiquetas img:

<div id="ejemplo1">
	<img src="URL_imagen1">
	<img src="URL_imagen2">
</div>

Podemos establecer una regla de estilo específica para la primera de esas imágenes:

#ejemplo1 img:first-child {border: 5px solid #f00; padding: 10px;}

Donde establecemos que, en cierto contenedor identificado con su id, la primera etiqueta img tendrá un borde pero las siguientes no.

Una variante: esto colocará en rojo, todos los textos en negrita de la primera etiqueta p que estén dentro de cierto contenedor:

#ejemplo2 p:first-child strong {color:red}
<div id="ejemplo2">
	<p>esto será <strong>rojo</strong> y esto otro <strong>también</strong></p>
	<p>pero ninguno de <strong>estos</strong> se verá <strong>rojo</strong></p>
</div>

esto será rojo y esto otro también

pero ninguno de estos se verá rojo

La pseudo-clase :last-child es similar pero hace lo inverso, selecciona el último elemento que se encuentra dentro de otro así que en el primer ejemplo, la imagen con borde sería la segunda:

#ejemplo2 img:last-child {border:2px solid red;}

Aunque no son utilizadas habitualmente, las pseudo-clases :first-of-type y :last-of-type nos permiten seleccionar él primer o el último elemento de su tipo dentro de un contenedor:

<div id="ejemplo3">
	<p>este texto será negro</p>
	<p><span>esto será rojo</span> <span>pero este texto será negro</span></p>
</div>

Vamos a definir que la primera etiqueta de tipo span se vea de color rojo:

#ejemplo3 span:first-of-type {color: red;}

Y ocurrirá eso, sin importar si esa etiqueta, a su vez, se encuentra dentro de otro contenedor:

este texto será negro

esto será rojo pero este texto será negro

Otra variante son las pseudo-clases :only-child y :only-of-type que seleccionan un elemento que es el único dentro de otro contenedor.

En el primer ejemplo con imágenes, ninguna de ellas tendría un borde si usáramos esta regla porque para que se aplicara el borde, sólo debería haber una:

#ejemplo1 img:first-child {border:2px solid red;}

Pero veamos este otro ejemplo:

<div id="ejemplo4">
	<div>
		<p>esto será rojo porque es único</p>
	</div>
	<div>
		<p>esto será negro</p>
		<p>y esto también será negro</p>
	</div>
</div>

Establecemos una regla para que toda etiqueta p incluida en un div sea de color rojo siempre y cuando sea la única:

#ejemplo4 div p:only-child {color: red;}

Y veremos esto:

esto será rojo porque es único

esto será negro

y esto también será negro

Hay que tener muy en cuenta que las pseudo-clases tienen prioridad sobre otro tipo de definiciones menos específicas. En este ejemplo:

<div id="ejemplo5">
	<p>este es <strong>el primero</strong> y no es azul sino <strong>rojo</strong></p>
	<p>pero <strong>estos</strong> se ven <strong>azules</strong></p>
</div>

Si se usara un selector como > que identifica todos los elementos hijos (children) y la pseudo clase :first-child, estableciendo dos colores distintos:

#ejemplo5 p:first-child strong {color:red}
#ejemplo5 p > strong {color:blue}

Sin importar el orden en que escribamos esas reglas, la pseudo clase :first-child tendrá prioridad:

este es el primero y no es azul sino rojo

pero estos se ven azules