Es/Selectores avanzados de CSS
Contents
Referencia de selectores CSS
Introducción
En nuestro artículo Conceptos básicos de CSS, hemos introducido los más básicos de los selectores CSS: selectores de elemento, clase e id. Con estos selectores puede lograr mucho, pero no lo son todo en cuanto a selectores. Hay otros selectores que le permiten seleccionar elementos para aplicarle estilos basándose en diversos criterios más específicos y analizaremos la mayoría de ellos durante el transcurso de este artículo.
Nota: Estamos diciendo "la mayoría" aquí, porque aunque la mayoría de los navegadores actuales soportan todos los selectores especificados en el Módulo de selectores CSS3, nuevos selectores están siendo agregados/modificados todo el tiempo (manténgase verificando el borrador de trabajo de los selectores CSS4 para más información sobre actualizaciones). Pretendemos actualizar este recurso con nuevos selectores como y cuando logren un soporte más amplio por parte de los navegadores.
Verá muchos de estos selectores utilizados en nuestros artículos a medida que siga leyendo. No se preocupe si no los entiende todos de inmediato, manténgase consultando este artículo como referencia si necesita más ayuda.
Selectores universales
Los selectores universales seleccionan todos los elementos de una página. Por ejemplo, la siguiente regla dice que cada elemento de la página debe tener un borde negro sólido de 1 píxel:
* { border: 1px solid #000000; }
Selectores de atributo
Los selectores de atributo le permiten seleccionar elementos en función de los atributos que contienen. Por ejemplo, usted puede seleccionar todos los elementos <img>
con un atributo alt
mediante el siguiente selector:
img[alt] { border: 1px solid #000000; }
Note los corchetes.
Usando este selector podría decidir colocar un borde negro alrededor de las imágenes que tienen un atributo alt
y aplicar un borde rojo brillante al resto de las imágenes. Esta sería una técnica útil a emplear en pruebas de accesibilidad.
Selección por el valor de un atributo
Los selectores de atributo se hacen inmediatamente más útiles si consideramos que puede seleccionar por el valor del atributo, no sólo por el nombre del atributo. La regla siguiente selecciona todas las imágenes con un valor de atributo src
de alerta.gif
:
img[src="alerta.gif"] { border: 1px solid #000000; }
Nuevamente, esto puede ser útil para fines de depuración y quizá para aplicar estilos a iconos importantes o enlaces sin necesidad de agregar IDs o clases adicionales.
Tenga en cuenta que esto no es soportado por IE6 y anteriores.
Selección basándose en una sub-cadena dentro del valor de un atributo
Aquí es donde los selectores de atributos se hácen aún más útiles. Para empezar, podemos seleccionar y aplicar estilos a nuestro elemento <img src="alerta.gif">
usando el siguiente código:
img[src^="alerta"] { border: 1px solid #000000; }
El carácter ^ indica que este selector debe seleccionar los elementos <img>
sólo si tienen la cadena alerta
al comienzo del valor del atributo src
.
A continuación, podemos seleccionar nuestro elemento <img src="alerta.gif">
con esto:
img[src$="gif"] { border: 1px solid #000000; }
El carácter $ indica que este selector debe seleccionar los elementos <img>
sólo si tienen la cadena gif
al final del valor del atributo src
. Esto es realmente útil para aplicar estilos a enlaces que apuntan a tipos específicos de recursos, como archivos PDF o documentos de texto.
Por último, podemos seleccionar nuestro elemento <img src="alerta.gif">
de esta manera:
img[src*="ert"] { border: 1px solid #000000; }
El carácter * indica que este selector debe seleccionar los elementos <img>
sólo si tienen la cadena ert
en cualquier lugar dentro del valor del atributo src
.
Tenga en cuenta que éstos no son soportados por IE8 y anteriores.
Selección basándose en elementos delimitados dentro del valor de un atributo
Si tuviera un elemento en una página con un número de clases aplicadas, por ejemplo:
<article class="resaltado archivo ingles"></article>
Podría seleccionarlo usando cualquiera de los siguientes selectores:
article[class~="resaltado"] article[class~="archivo"] article[class~="ingles"]
El carácter ~ indica que estos selectores deben seleccionar un elemento <article>
cuyo valor de atributo class
es una lista de valores separados por espacios en blanco, pero sólo si uno de esos valores es igual al valor indicado dentro de las comillas.
Ahora veamos un elemento en una página con un valor de ID en forma de una lista separada por guiones:
<article id="ingles-diario-resaltado"></article>
Podría seleccionarlo usando el siguiente selector:
article[id|="ingles"]
El carácter | indica que este selector debe seleccionar un elemento <article>
cuyo valor del atributo id
es una lista de valores separados por guiones, pero sólo si el valor más a la izquierda es ingles
.
Tenga en cuenta que éstos no son soporatdos por IE8 y anteriores.
Selector de secundarios (hijos)
Puede utilizar un selector de secundarios (hijos) para seleccionar elementos específicos que son hijos de otros elementos específicos. Por ejemplo, la siguiente regla cambiará el texto de elementos <strong>
que son hijos de elementos <h3>
a color azul, pero no afectará a otros elementos <strong>
:
h3 > strong { color: blue; }
Tenga en cuenta que los selectores de secundarios no son soportados en IE 6 o anteriores.
Note también que el carácter > a menudo es llamado un combinador en este contexto, ya que combina varios elementos en un selector.
Selector de descendientes
Los selectores de descendientes son muy similares a los selectores de secundarios, excepto que los selectores de secundarios sólo seleccionan descendientes inmediatos; los selectores de descendientes seleccionan elementos coincidentes en cualquier lugar en la jerarquía de elementos, no sólo descendientes directos. Veamos lo que esto significa más cuidadosamente. Considere el siguiente fragmento de HTML:
<div> <p>Hola</p> <article> <p>En este párrafo diré adiós</p>. </article> </div>
En este fragmento de código, el elemento <div>
es el padre de todos los demás elementos. Tiene dos secundarios, un <p>
y un <article>
. El elemento <article>
tiene un elemento secundario único: otro <p>
.
Puede utilizar un selector de secundarios para seleccionar sólamente el <p>
que se encuentra inmediatamente dentro del <div>
, así:
div > p { ... }
En cambio, si utiliza un selector de descendientes, sería así:
div p { ... }
Ambos elementos <p>
serán seleccionados.
Selector de hermano adjacente
Este selector le permite seleccionar un elemento específico que viene inmediatamente después de otro elemento específico, en el mismo nivel de la jerarquía de elementos. Tomemos el ejemplo siguiente
<h2>Mi encabezado</h2> <p>Mi primer párrafo</p> <p>Mi segundo párrafo</p> <p>Mi tercer párrafo</p> <p>Mi cuarto párrafo</p> <p>Mi quinto párrafo</p>
Si desea seleccionar sólo el elemento <p>
que está inmediatamente después del elemento <h2>
(y cualquier otro elemento <p>
en la misma condición que pueda aparecer más adelante en el documento), puede utilizar la siguiente regla:
h2 + p { ... }
Tenga en cuenta que el selector de hermanos adyacentes no es soportado por IE6 o anteriores.
Note también que el carácter + a menudo es llamado un combinador en este contexto, ya que combina múltiples elementos en un selector.
Selectores de hermano general
El selector de hermano general es muy similar al selector de hermano adyacente, excepto que le permite seleccionar todos los hermanos del tipo de elemento especificado, no sólo el que aparece inmediatamente después del elemento en el lado izquierdo. La sintaxis es la siguiente:
h2 ~ p { ... }
Volviendo a nuestro ejemplo anterior, este conjunto de reglas seleccionará todos los cinco elementos de párrafo, no sólo el primero. También seleccionará el párrafo que se muestra a continuación:
<h2>Mi encabezado</h2> <h3>Mi subencabezado</h3> <p>Mi párrafo</p>
Tenga en cuenta que el selector de hermanos generales no es soportado por IE8 o anteriores.
Note también que el carácter ~ a menudo es llamado un combinador en este contexto, ya que combina múltiples elementos en un selector.
Pseudoclases
Las pseudoclases se utilizan para proporcionar estilos, pero no a los elementos sino a los diferentes estados de los elementos.
Pseudoclases de enlace y acción de usuario
Las pseudoclases más comunes que encontrará son las que que se utilizan para aplicarle estilos a los estados de los enlaces (verá esto en pleno uso en Estilos de listas y enlaces):
-
:link
— el estado normal, predeterminado de los enlaces, así como los encuentra por primera vez. -
:visited
— selecciona enlaces que ya ha visitado anteriormente con el navegador que está usando. -
:focus
— selecciona enlaces en los que se encuentra posicionado el cursor del teclado en el momento actual. -
:hover
— selecciona enlaces sobre los cuales se encuentra posicionado el cursor del ratón en el momento actual, también conocidos como enlaces activables. -
:active
— selecciona enlaces sobre los que se está haciendo clic en el momento actual, también conocidos como enlaces activos.
Tenga en cuenta que las últimas tres (estas son las "pseudoclases de acción de usuario"; las dos primeras son las pseudoclases de enlace) pueden utilizarse en los estados de prácticamente cualquier elemento en el que tenga sentido usarlas en una interfaz de usuario. Por ejemplo, puede que desee que un campo de entrada de formulario adopte un estilo diferente al colocarle adentro el cursor del teclado mediante el tabulador o tal vez desea que aparezca un cuadro de información solamente cuando coloca el cursor del ratón sobre una parte determinada de la pantalla.
Veamos algunos ejemplos. Las siguientes reglas CSS hacen que, de forma predeterminada, los enlaces sean azules (la opción predeterminada en la mayoría de los navegadores, de todos modos). Cuando se hacen activables, desaparece el subrayado predeterminado de los enlaces. Queremos este mismo efecto cuando el enlace es enfocado mediante el teclado, por lo que aplicamos la misma regla de :hover
para la pseudoclase :focus
. Cuando un enlace ya ha sido visitado, se torna gris. Finalmente, cuando un enlace está activo, se coloca en negritas, como un indicio adicional de que algo importante está sucediendo.
a:link { color: blue; } a:visited { color: gray; } a:hover, a:focus { text-decoration: none; } a:active { font-weight: bold; }
Tenga cuidado si no especifica estas reglas en el mismo orden que se muestra aquí, pues en caso contrario puede que no funcionen como se espera. Esto es debido a la forma en que la especificidad hace que las reglas posteriores en la hoja de estilos se sobrepongan a las reglas anteriores. Aprenderá más acerca de especificidad en Herencia y cascada.
Como ejemplo adicional, la pseudoclase :focus
también es útil como una ayuda en la usabilidad de los formularios. Por ejemplo, puede resaltar el campo de entrada que tiene el cursor activo parpadeante en su interior con una regla como esta:
input:focus { border: 2px solid black; background-color: lightgray; }
Pseudoclase de negación (not)
La pseudoclase de negación puede utilizarse para aplicar estilos explícitamente a elementos que no son seleccionados por un selector simple. Digamos que queríamos aplicar algunos estilos a un número de bloques de contenido; a todos excepto a uno. Los bloques podrían ser así:
<section id="resumen"> ... </section> <section id="experimento"> ... </section> <section id="pruebas"> ... </section> <section id="resultados"> ... </section> <section id="conclusiones"> ... </section> <section id="referencias"> ... </section>
Podríamos aplicar los estilos a todas las secciones, excepto a la de referencias haciendo esto:
#resumen, #experimento, #pruebas, #resultados, #conclusiones { ... }
O por el contrario, podríamos utilizar el selector de negación, de este modo:
section:not(#referencias) { ... }
Que es mucho más corto y simple.
Tenga en cuenta que el selector de negación no es soportado por IE8 y anteriores.
Pseudoclase de idioma (lang)
La pseudoclase :lang
selecciona elementos cuyos idiomas se han establecido en el idioma especificado mediante el atributo lang
. Por ejemplo, el siguiente elemento:
<p lang="es-VE">¡Qué carrizos! Este párrafo de texto está en español de Venezuela.<p>
Podría ser seleccionado usando la siguiente regla:
p:lang(es-VE) { ... }
Pseudoclase de destino (target)
La pseudoclase :target
le permite seleccionar un elemento si es el target de la URL de la página actual. Esto es realmente útil y permite algunos efectos muy interesantes, ya que efectivamente le permite establecer estilos que se aplicarán cuando hace clic en los enlaces. Por ejemplo:
<a href="#target">Hágame clic</a> <div id="target">¡Hola!</div>
Aquí tenemos un enlace sencillo seguido de un <div>
. El enlace hace referencia al <div>
mediante su ID. La URL actual sólo nos lleva al <div>
al hacer clic en el enlace. Para aplicarle estilos al <div>
únicamente cuando se haga clic en el enlace puede utilizar lo siguiente:
div:target { ... }
Para ver un ejemplo mucho más complicado del uso de :target
, lea CSS3: Interfaces basadas en :target (inglés) de Corey Mwamba.
Pseudoclases de estado de elemento de IU
Estas pseudoclases tratan todas de la aplicación de estilos a estados avanzados de elementos de la Interfaz de usuario (IU). Comúnmente las utilizará para aplicar estilos a elementos de formulario de HTML, especialmente cuando se utilizan algunas de las nuevas características de formulario de HTML5, como la validación nativa (vea Elementos adicionales de formulario del HTML5 para mayor información).
Digamos que estamos aplicándole estilos a un campo de entrada de formulario básico con un atributo valid
para su validación:
<input type="text" required>
Podríamos aplicarle estilos sólo cuando la información introducida en él es válida o inválida usando
input:valid {}
e
input:invalid {}
Podríamos aplicarle estilos dependiendo de si está activado (por defecto) o desactivado (mediante el atributo disabled
), usando
input:enabled {}
e
input:disabled {}
Por último, podríamos aplicarle estilos a una casilla de verificación sólo cuando está seleccionada de esta manera:
input[type="checkbox"]:checked {}
Pseudoclases estucturales
Las pseudoclases estructurales son selectores avanzados que le permiten seleccionar elementos específicos en función de su posición en la jerarquía del documento. Estos fueron introducidos en las CSS3 y creados en base a los selectores que ya hemos analizado, como el selector de hermanos adyacentes.
:root
selecciona el elemento raíz del documento, que suele ser el elemento <html>
. Por ejemplo:
html:root{ ... }
:nth-child(n)
le permite seleccionar un patrón de repetición de elementos dentro de un conjunto continuo de elementos como, por ejemplo, varios elementos de lista o varios párrafos o artículos juntos el uno al otro. Veamos un ejemplo:
<ul> <li>Primero</li> <li>Segundo</li> <li>Tercero</li> <li>Cuarto</li> <li>Quinto</li> <li>Sexto</li> <li>Séptimo</li> <li>Octavo</li> <li>Noveno</li> <li>Décimo</li> </ul>
En el parámetro n
establecemos el patrón que deseamos seleccionar. En este caso, para seleccionar elementos de lista hacemos esto:
li:nth-child(n)
Para seleccionar únicamente los elementos pares o impares, usaríamos estos:
li:nth-child(odd) li:nth-child(even)
O podríamos utilizar
li:nth-child(2n+1) li:nth-child(2n+0)
para hacer lo mismo.
Veamos algunos otros ejemplos de fórmulas:
-
li:nth-child(5)
: selecciona el 5to. elemento de lista adjacente. -
li:nth-child(4n+1)
: selecciona cada 4to. elemento y luego añade 1 a cada resultado. O sea, los números 5 y 9. -
li:nth-child(3n-2)
: selecciona cada 3er. elemento de lista y le resta 2 de cada resultado. O sea, los números 1, 4 y 7.
A continuación, pasemos a nth-last-child(n)
. Este hace lo mismo que nth-child(n)
, pero cuenta desde el último elemento de la secuencia, no desde el primero.
nth-of-type(n)
y nth-last-of-type(n)
hacen casi exactamente lo mismo que nth-child(n)
y nth-last-child(n)
, pero con una diferencia importante: los dos primeros hacen caso omiso de los elementos independientes intercalados en la secuencia repetida de elementos similares, porque seleccionan por tipo de elemento, no por el número del elemento. Los últimos seleccionan por el número del elemento.
Echémosle un vistazo a otro ejemplo:
<div> 1. <article class="resumen"> ... </article> 2. <article class="resumen"> ... </article> 3. <article class="resumen"> ... </article> 4. <article class="resumen"> ... </article> 5. <article class="resumen"> ... </article> 6. <blockquote><p> ... </p></blockquote> 7. <article class="resumen"> ... </article> 8. <article class="resumen"> ... </article> 9. <article class="resumen"> ... </article> </div>
En este ejemplo tenemos un elemento <div>
con ocho elementos <article>
secundarios (hijos) y un solo elemento <blockquote>
colocado en medio de ellos; el hijo número seis. Hay un total de nueve elementos secundarios.
Si utilizara article:nth-child(2n+0)
como selector para seleccionar todos los hijos de número par del <div>
, seleccionaría únicamente los <article>
s en las posiciones 2, 4 y 8. El <blockquote>
(posición número seis) no sería seleccionado porque no es un <article>
.
Si utilizara article:nth-of-type(2n+0)
como selector, seleccionaría los <article>
s en las posiciones 2, 4, 7 y 9. Esto es así porque éste selecciona por el tipo de elemento, no por la posición del hijo, por lo tanto, en este caso el <blockquote>
es totalmente ignorado y se seleccionan los <article>
s pares. Sí, dos de ellos son impares según mi esquema de numeración original porque en realidad el <blockquote>
existe y desplaza su posición, pero article:nth-of-type(2n+0)
ignora el <blockquote>
, contando efectivamente las posiciones 7 y 9 como 6 y 8.
A continuación, vamos a echar un vistazo a :first-child
y :last-child
. Estas pseudoclases seleccionan sólo la primera o última instancia de un elemento que es el primer o último elemento secundario de su elemento padre. Por lo tanto, considerando el ejemplo de arriba una vez más, podríamos utilizar los siguientes para seleccionar, respectivamente, el primer y el último elemento <article>
:
article:first-child { ... } article:last-child { ... }
blockquote:first-child
no seleccionaría nada, porque el primer hijo no es un <blockquote>
.
first-of-type
y last-of-type
también funcionan de una manera muy similar, pero estos seleccionan basándose en el tipo de elemento, no en la posición en que se encuentra el hijo. Así, article:first-of-type
seleccionaría exactamente el mismo elemento <article>
que article:first-child
, pero blockquote:first-of-type
seleccionaría el único <blockquote>
en el ejemplo, porque es el primero de su tipo, aunque es el 6to. hijo.
Existen algunas otras cosas que debemos considerar rápidamente:
-
only-child
: selecciona un elemento sólo si es el único hijo de su elemento padre. Por ejemplo,article:only-child
no seleccionaría nada en nuestro ejemplo anterior porque hay más de un elemento<article>
hijo. -
only-of-type
: selecciona un elemento sólo si es el único elemento hermano de su tipo dentro del elemento padre. Por ejemplo,blockquote:only-of-type
seleccionaría el<blockquote>
en el ejemplo anterior porque es el único de su tipo presente. -
empty
: selecciona un elemento sólo si no tiene ningún elemento hijo (incluyendo nodos de texto). Por ejemplo,div:empty
seleccionaría<div></div>
, pero no<div>1</div>
o<div><p>¡Hola!</p></div>
Pseudoelementos
Los pseudoelementos difieren de las pseudoclases en que no seleccionan estados de elementos, sino que seleccionan partes de un elemento.
:first-letter
En primer lugar, puede seleccionar la primera letra dentro de un elemento determinado utilizando la siguiente regla:
p:first-letter { font-weight: bold; font-size: 300%; background-color: red; }
La primera letra de cada párrafo estará ahora en negritas, será 300% más grande que el resto del párrafo y tendrá un fondo rojo. Este es un buen comienzo hacia la creación de un efecto de capitular decente.
:first-line
Para colocar en negritas la primera línea de cada párrafo, puede utilizar la siguiente regla:
p:first-line { font-weight: bold; }
Contenido generado usando :before y :after
Puede utilizar los pseudoelementos :before
y :after
para especificar que cierto contenido debe ser insertado antes y después del elemento que está seleccionando. A continuación, especifica qué contenido desea insertar o generar. Como un simple ejemplo, puede utilizar la siguiente regla para insertar una imagen decorativa después de cada enlace en la página:
a:after { content: " " url(flor.gif); }
También puede utilizar la función attr()
para insertar los valores de los atributos de los elementos después del elemento. Por ejemplo, puede colocar el destino de cada enlace del documento entre paréntesis después de cada uno de ellos usando la siguiente regla:
<code>a:after { content: "" "(" attr(href) ")"; }</code>
Esta es una magnífica técnica para usarla en una hoja de estilos de impresión en la que desea mostrar las direcciones URL en el documento en lugar de mantenerlas escondidas dentro de los enlaces (inútiles en una página impresa).
También puede insertar valores numéricos crecientes después de elementos que se repiten (como viñetas o párrafos) mediante la función counter()
, esto se explica con más detalle en Numeración automática con contadores CSS (inglés) por David Storey.
Estos selectores no son soportados en IE 7 o anteriores. Tenga en cuenta que: no debe insertar información importante con CSS, el contenido no estará disponible para las ayudas técnicas y que un usuario puede decidir no usar su hoja de estilos. La regla de oro es que las CSS son para aplicar estilos, el HTML es para el contenido importante.
Sintaxis con doble dos puntos de CSS3 para pseudoelementos
Por favor, tenga en cuenta que los pseudoelementos se escriben de una nueva manera en las CSS3 usando doble dos puntos, por ejemplo a::after { ... }
, para así diferenciarlos de las pseudoclases. Puede ver esto con frecuencia en las CSS. Sin embargo, las CSS3 también siguen permitiendo sólo dos puntos para los pseudoelementos en aras de la compatibilidad con versiones anteriores y le aconsejamos que se quede con esta sintaxis por el momento.