Selectores en CSS

publicado en la categoría CSS
En CSS, un selector es un vínculo entre el HTML y la hoja de estilo. Todas las etiquetas son selectores y cada uno de ellas posee un conjunto de propiedades generales y particulares. Pero como esto es insuficiente, también existen selectores especiales que nos permiten crear reglas muy específicas.

El CSS no es un lenguaje de programación sino un listado de propiedades organizado bajo ciertas reglas de sintaxis. Por ejemplo, para establecer que el texto incluido en una etiqueta de título se muestre de color azul escribiríamos algo así::

h1 {color: blue;}

Esto es lo que se llama una regla y consiste en dos partes, la primera se denomina selector (h1), la segunda declaración (color:blue) que, a su vez tiene dos partes, la propiedad (color) y el valor (blue).

El selector es un vínculo entre el HTML y la hoja de estilo. Todos los elementos (etiquetas) de un documento son selectores y cada uno de ellos posee un conjunto de propiedades generales y particulares. Pero está claro que eso solo es poco útil ya que las etiquetas disponibles son pocas así que necesitamos referenciarlas de otro modo.

Para eso existen dos atributos adicionales: el id se utiliza para dar un nombre a una etiqueta que queremos que tenga un estilo específico. Un nombre que debe ser único (sólo debe haber uno en toda la página y debería reservarse para elementos importantes); por el contrario, el atributo class nos permite agrupar estilos repetitivos y podemos utilizarlo en múltiples etiquetas.

Una de las características interesantes del CSS es la posibilidad de establecer reglas con selectores especiales; uno de ellos es el llamado selector de hijos (child selector) y para entender cómo funciona, hay que entender la parentela de las etiquetas. Dada una etiqueta, esta se considera la etiqueta padre (parent) de aquellos elementos que están dentro a quienes consideramos sus hijos (child). Siguiendo esta analogía, en CSS se habla de la herencia, es decir, ciertas propiedades definidas en el elemento padre se transmiten al hijo.

Como no todas las propiedades se heredan, existen selectores especiales que nos permiten definir estas cosas con mayor exactitud. Para seleccionar elementos hijos, usamos el símbolo > (mayor que) y de ese modo indicamos que cierta propiedad se aplicará sobre ellos y su utilidad se ve cuando tenemos estructuras relativamente complejas.

#demo h3 {
	color: white;
}
#demo > h3 {
	color: gold;
}

En ese ejemplo estamos definiendo que sólo los títulos h3 que sean hijos del div cuyo id es demo sean amarillos y el resto de los títulos sean blancos.

Otra alternativa nos permite seleccionar elementos adyacentes y eso lo hacemos con el carácter + (signo más). Por ejemplo, así estamos diciendo que, el párrafo que inmediatamente sigue a otro de cierta clase será de determinado color pero sólo ese:

p.ejemplo + p  {color: gold;}

este es un párrafo con la clase ejemplo

este es el párrafo adyacente al anterior

este no es el párrafo adyacente

¿Y que pasa si dos elementos no son adyacentes? El carácter ~ permite seleccionar dos o más elementos separados siempre que todos sean hijos de un mismo padre. Por ejemplo, así decimos que los textos de las etiquetas em> serán de color azul, que los de las etiquetas p serán de color negro pero que todos los textos en una etiqueta em que no sean la primera, serán de color rojo:

em {color: blue;}
p {color: black;}
p ~ em {color: red;}

¿Retorcido? Hay cosas peores ... pero, en la práctica, hay decenas de situaciones donde este tipo de reglas ayudan a simplificar las reglas ... aunque a simple vista no lo parezca.

Sigamos adelante ...

Hay selectores especiales que permiten que identifiquemos un elemento en función de alguno de sus atributos; se utilizan del mismo modo que cualquier otro y se aplican a etiquetas, clases o ids.

Empecemos con un ejemplo simple; esto, haría que los textos de las etiquetas p se vieran de color rojo sólo si esa etiqueta tuviera un atributo title:

p[title] {color: red;}

Lo mismo podría hacerse con cualquier otro atributo (href src class alt) pero estos selectores permiten mucho más ya que podemos aplicar las reglas de modo más amplio, aplicando una regla de estilo sólo si el atributo es exactamente igual a un determinado valor que debe estar entre comillas:

p[title="esto es verde"] {color: green;}

Una serie de caracteres se pueden usar como operadores estableciendo condiciones. Por ejemplo, anteponiéndole el carácter | al signo igual, la regla sólo se aplicará si el atributo tiene ese valor exacto o ese valor continúa con un guión.

Anteponiéndo el carácter ^ seleccionaremos aquellos atributos que comiencen con ese valor y con el caracter $ seleccionaremos todos los atributos que terminen con ese valor.

Anteponiendo el carácter ~ seleccionaremos todos los atributos que contengan determinado valor sin importa su posición:

p[title|='rojo'] {color:red;}
p[title^="ejemplo"] {color:yellow;}
p[title$="ejemplo"] {color:yellow;}
p[title~="ejemplo"] {color:yellow;}

No existen limitaciones en el uso de los atributos y nada nos impide crear uno para satisfacer una necesidad especial, por ejemplo:

p[miatributo="algo"] {color: yellow;}

Al igual que los selectores comunes, estos pueden ser combinados, por ejemplo:

p[title="ejemplo"][class="demo"] {color: yellow;}
p[title^="palabra"][miatributo$="detalle"] {color: yellow;}
ver/ocultar ejemplos

.demo[title="rojo exacto"] {color:red;}

title="rojo" : NO ES EXACTOtitle="rojo exacto" : ESTE SI

.demo[title|='rojo'] {color:red;}

title="rojo" : ES EXACTOtitle="no es rojo" : ESTE NOtitle="rojo-123" : incluye guión

.demo[title^='rojo'] {color:red;}

title="no es rojo" : NOtitle="rojo y algo más" : SI

.demo[title$='rojo'] {color:red;}

title="este es rojo" : SItitle="rojo y algo más" : NO

.demo[title*='rojo'] {color:red;}

title="verde amarillo azul"title="verde rojo azul"title="también es rojo"

Usando los selectores de atributos podemos diferenciar los enlaces de modo muy preciso y, de ese modo, establecer variantes gráficas surtidas, personales, locas o casi cualquier cosa. Por ejemplo, si quisiéramos diferenciar los enlaces internos a nuestro sitio de los enlaces externos podríamos agregar propiedades especificas para que nuestros propios enlaces, se viesen distintos, usando parte de la dirección URL:

a[href*="misitio."] { /* acá las propiedades */ }

Lo mismo podríamos hacer de modo inverso, establecer una regla para que lo que se vea distinto sean los enlaces externos:

a[href ^= "http"]:not([href *= "misitio."]) { /* acá las propiedades */ }

Estos selectores condicionales permiten detectar casi cualquier cosa y de ese modo, mostrar las etiquetas con ciertos efectos gráficos diferenciados en función de alguna regla sin tener que editar las etiquetas HTML ya que podemos agregar contenido usando la propeidad content. Por ejemplo, sería relativamente sencillo detectar los enlaces que se abren en una ventana separada (target="_blank") y diferenciarlos de aquellos que no lo hacen anteponiéndoles algún ícono:

a[target="_blank"]:before {
    content: url(URL_imagen);
    margin-right: .2em;
}

Con el mismo criterio podríamos utilizar los selectores condicionales para detectar tipos de archivos. Por ejemplo, esto permitiría detectar todos los enlaces que contengan un vínculo a un archivo PDF:

a[href $='.pdf'] { /* acá las propiedades */ }

Lo mismo, podríamos hacer para cualquier tipo de archivo y, si vamos a jugar un poco, aprovechamos para establecer un cursor personal:

a.[href$=".pdf"] {cursor:url(http://i.imgur.com/ddKqPaP.png), pointer;}
a.[href$=".txt"] {cursor:url(http://i.imgur.com/JPjCICL.png), pointer;}
a.[href$=".zip"] {cursor:url(http://i.imgur.com/JXnTZzw.png), pointer; }

Por cierto, no hay que olvidarse del llamado selector universal que está representado por un asterisco y que debería utilizarse como primera regla en cualquier hoja de estilo para eliminar aquellas propiedades por defecto que suelen ser perturbadoras o no sabemos de dónde vienen.

Este selector funciona como comodín por lo tanto, si agregamos algo así, eliminaríamos todos los márgenes y separaciones de todas las etiquetas a las que, posteriormente, podríamos definir:

* {
  margin: 0;
  padding: 0;
}

El selector universal no sólo se utiliza de ese modo, también puede ser parte de cualquier otra regla. Por ejemplo, podríamos establecer todas las fuentes de las etiquetas dentro de un div y de ese modo, no será necesario crear reglas individuales para cada uno de esos contenidos.

div * {font-size: 2em;}