Los Selectores CSS son una de las piezas más importantes del Desarrollo Web, pues son la forma en la que podemos seleccionar una etiqueta HTML para poder aplicarle las propiedades de estilo que deseamos.
Hace poco dimos un vistazo a HTML5 y a los Minificadores de Código (JavaScript, HTML, CSS, y demás), y ahora llega el turno de ver los Selectores CSS. Para ellos, empezaremos viendo los Tipos de Selectores CSS:
- Selectores de Etiqueta (Tag Selectors, AKA Type Selector o Element Selectors)
- Selectores de Clase (Class Selectors)
- Selectores de ID (ID Selectors)
- Agrupación de Selectores y el Selector Universal (*)
- Selectores de Descendientes (Descendant Selectors)
- Selectores de Hijos (Child Selectors)
- Selectores de Hermanos (Siblings Selectors)
- Pseudo-Clases y Pseudo-Elementos
- Selectores de Atributos (Attribute Selectors)
Para seguidamente ver el funcionamiento de la Herencia de Estilos CSS, la resolución de conflictos en caso de empate, la forma de configurar una propiedad de un estilo para que no se pueda sobrescribir, y la forma de resetear los estilos predeterminados de los navegadores (CSS Reset).
Selectores de Etiqueta (Tag Selectors, AKA Type Selectors or Element Selectors)
Son muy eficientes. Permiten seleccionar todas las ocurrencias de una etiqueta HTML en una página Web. Ej: p { color : red; }
Selectores de Clase (Class Selectors)
Permiten seleccionar uno o más elementos, definiendo un nombre que se deberá asignar a las etiquetas HTML deseadas (utilizando el atributo class) para aplicarlas el estilo deseado. Los nombres de los Selectores de Clase deben comenzar por una letra (aunque pueden incluir números y guiones) y son susceptibles de mayúsculas y minúsculas. A continuación se muestran dos ejemplo, el primero selecciona cualquier etiqueta con el atributo class="aviso", mientras que el segundo seleccionar sólo los párrafos con el atributo class="aviso".
- .aviso { color : red; }
- p.aviso { color : red; }
Una ventaja de la utilización de los Selectores de Clase (Class Selectors) es que es posible asignar varias clases a una misma etiqueta HTML, simplemente separando las diferentes clases con un espacio (ej: <div class="articulo destacado">), permitiendo de este modo aplicar múltiples estilos a una misma etiqueta de una forma muy sencilla.
Selectores de ID (ID Selectors)
Permiten seleccionar un elemento HTML único, el cual debe ser etiquetado con el atributo ID. Existen varios casos de uso típicos, como por ejemplo:
- Utilizar el atributo ID en la etiqueta <body> para identificar el tipo de página (ej: Home, Artículo, Noticia, etc.) y aplicar el estilo correspondiente.
- Utilizar el atributo ID en las etiquetas <div> utilizadas para las principales secciones de la página (ej: cabecera, pié, barra lateral, cuerpo de la página, etc.) y aplicar el estilo correspondiente.
Algunos desarrolladores Web tienden a dejar de utilizar los selectores de ID, aunque en la práctica siguen estando muy utilizados. Ej: #cabecera { color : red; }
Agrupación de Selectores y el Selector Universal (*)
Es posible aplicar un mismo estilo a múltiples selectores a la vez, separándolos por comas, tal y como se aprecia en los siguientes ejemplos:
- p, a, h1, h2, h3 { color : red; }
- h1, .aviso, #cabecera { color : red }
Además, también podemos utilizar el Selector Universal, para de este modo seleccionar todos los elementos HTML de una forma sencilla. Ej: * { Font-family : "Arial"; }
Selectores de Descendientes (Descendant Selectors)
Permiten seleccionar los elementos descendientes (tanto hijos como nietos, etc.) de un elemento determinado, pudiendo seleccionar los elementos descendientes que deseemos o todos los descendientes (utilizando el Selector Universal *).
- div p { color : red; }
- h1 strong { color : red; }
- #cabecera p { color : red; }
- .articulo a { color : red; }
- .contacto .telefono { color : red; }
- p * { color : red; }
Los Selectores de Descendientes (Descendant Selectors) facilitan la creación de módulos. Es decir, podemos asignar una clase a un div, y utilizando los Selectores de Descendientes aplicar los estilos deseados a todos los elementos HTML contenidos dentro de dicho div, como si se tratase de un módulo independiente.
Selectores de Hijos (Child Selectors)
Permiten seleccionar los elementos hijos (y sólo los hijos directos, por lo tanto quedan excluidos los nietos, etc.) de un elemento determinado. Algunos ejemplos:
- div > p { color : red; }
- h1 > strong { color : red; }
- #cabecera > p { color : red; }
- .articulo > a { color : red; }
- .contacto > .telefono { color : red; }
Selectores de Hermanos (Siblings Selectors)
Permite seleccionar el siguiente hermano (+) o todos los siguientes hermanos (~) de un elemento dado. Téngase en cuenta que el símbolo ~ (tilde) se obtiene pulsando AltGr+4 y pulsando un espacio.
- .c2+p { color : red; }
- .c2~p { color : red; }
Pseudo-Clases y Pseudo-Elementos
Tenemos varios tipos:
- Pseudo-Clases para enlaces: a:link, a:visited, a:hover, a:active
- Pseudo-Elementos para formatear texto: :first-letter, :first-line
- Pseudo-Clases específicas para selección de elementos hijos: :first-child, :last-child, :nth-child (permite seleccionar elementos pares, o impares, o cada n elementos empezando de un elemento dado), :first-of-type, :last-of-type, :nth-of-type.
- La Pseudo-Clase negación: :not(). Permite seleccionar todos los elementos excepto los que cumplen cierta condición. Su utilización está sujeta a ciertas limitaciones, ya que sólo puede utilizarse con selectores simples, y sólo puede utilizarse una única vez en un mismo selector.
- Otras Pseudo-Clases y Pseudo-Elementos: :focus (aplicar al coger el foco), :before (añade contenido justo antes del elemento), :after (añade contenido justo después del elemento), ::selection ó ::-moz-selection (dependiendo del navegador, aplica a los elementos seleccionados por el usuario)
Algunos ejemplos:
- p:first-letter { color : red; }
- p.novedad:before { content : “Nuevo!”; color : red; }
- h2.first-child { color : red; }
- tr:nth-child(odd) { background-color : red; }
- tr:nth-child(even) { background-color : green; }
- tr:nth-child(3n+2) { color: blue; }
- .noticia p:first-of-type
- .articulo img:nth-of-type(odd) { float : left; }
- .articulo img:nth-of-type(even) { float : right; }
- input:focus { background-color : red; }
- a[href^="http://"]:not([href^="https://guillesql.es"]) { color : red; }
- ::selection { color : red; }
- p::selection { color : blue; }
Selectores de Atributos (Attribute Selectors)
Permiten seleccionar elementos en función de los atributos que tienen (ej: img[title] ) o del valor exacto de dichos atributos (ej: a[href="https://guillesql.es"] ó input[type="text"] ), lo cual resulta muy útil en diferentes casos, como por ejemplo al trabajar con formularios. Incluso es posible:
- Seleccionar elementos en función del valor por el que comienza un atributo (Ej: a[href^="http://"] ).
- Seleccionar elementos en función del valor por el que finaliza un atributo (Ej: a[href$=".pdf"]).
- Seleccionar elementos en función del valor que contiene un atributo (Ej: a[href*="guillesql.es"] ).
Herencia de Estilos CSS
Además de conocer los Selectores CSS, es muy importante conocer la Herencia de Estilos CSS, el proceso por el cual las propiedades de estilo asignadas a una etiqueta HTML son heredadas por las etiquetas descendentes de la misma (es decir, las etiquetas existentes en su interior). De este modo, podemos aprovechar la Herencia de Estilos CSS para simplificar enormemente nuestras Hojas de Estilo, ya que ciertas propiedades al ser heredadas no será necesario repetirlas múltiples veces en múltiples estilos, permitiendo la creación de Hojas de Estilo más sencillas y ligeras. Básicamente deberemos tener en cuenta las siguientes reglas básicas al trabajar con la Herencia de Estilos CSS:
- No todas las propiedades CSS son heredables. Algunas como la fuente (ej: font-family) se pueden heredar, mientras que otras como las relacionadas con el posicionamiento de elementos en la página, márgenes, colores de fondo, o los bordes, no son heredadas.
- Los propios navegadores tienen sus propios estilos por defecto para ciertas etiquetas, como por ejemplo, el tamaño de fuente en las etiquetas h1-h6, lo que implica que ciertas propiedades CSS sólo puedan ser heredadas por ciertos elementos (mientras que otros no lo hereden).
- En caso de conflicto ganará el estilo más específico o cercano. Es decir, si especificamos una fuente en la etiqueta <body> y otra fuente en una etiqueta <p>, se utilizará la fuente especificada en el <p>.
Como siempre, deberemos comprobar su funcionamiento en diferentes navegadores, para garantizar que obtenemos el resultado deseado.
Resolución de Conflictos: Cascada de Estilos
Un conflicto de estilos es una situación en la que se intentan aplicar varios estilos a una misma etiqueta HTML, de tal modo que en dichos estilos existe alguna propiedad común (ej: background-color), por lo que sólo uno de los estilos será el que finalmente aplicará el valor de dicha propiedad – ej: background-color – a la etiqueta. Por supuesto, el resto de propiedades que no están en conflicto, podrán ser aplicadas, independientemente del estilo en el que estén definidas.
Los conflictos de estilos se producen principalmente en los siguientes dos casos:
- Debido a la Herencia de Estilos CSS, cuando una misma propiedad es heredada desde varios elementos ascendientes (ascentors). En este caso, gana el estilo aplicado a la etiqueta (ancestro) más cercana.
- Debido a que una misma propiedad CSS es aplicada a través de varios estilos en la misma etiqueta HTML, por ejemplo, porque dicha etiqueta tenga asignadas varias Clases, Estilos de Etiqueta, Estilos de ID, Estilos en línea (utilizando el atributo style de la etiqueta HTML), etc. El estilo ganador depende de cada caso, como veremos a continuación.
Llegados a este punto, tenemos que aclarar cómo se resuelven los conflictos cuando una misma propiedad CSS es aplicada a través de varios estilos en la misma etiqueta HTML. Para ello, los navegadores asignan un valor o peso a cada estilo, de un modo similar al siguiente (ojo, esto es una aproximación, no todos los navegadores deben de hacer este cálculo exactamente como aquí lo describimos):
- Selector de Etiqueta: 1 punto.
- Selector de Clase: 10 puntos.
- Selector de ID: 100 puntos.
- Selector en línea: 1000 puntos.
Estos valores son aditivos. Así, un estilo con un selector div p tendrá un valor de 20 (10+10), mientras que un estilo con un selector #cabecera img tendrá un valor de 101 (100+1). De este modo, el navegador realizará sus cálculos, y en caso de conflicto el estilo con un valor más alto ganará.
Pero ¿qué ocurre en caso de empate? Pues muy fácil, en caso de empate gana el estilo que aparece después. Es decir, si los dos estilos aparecen en la misma hoja de estilos, el que aparezca primero es el que pierde y el que aparezca después es el que gana. En caso de que los dos estilos en conflicto pertenezcan a hojas de estilo distintas, gana el que pertenezca a la hoja de estilos que se cargue después (es decir, que aparezca después en el <head>).
Cómo especificar que una propiedad de un estilo no se puede sobrescribir: !important
Con lo visto hasta ahora (selectores, herencia, y resolución de conflictos) surge este pequeño detalle: ¿Cómo especificar que una propiedad de un estilo no se debe poder sobrescribir por otra más específica? Afortunada o desafortunadamente, esto sí es posible, lo cual puede resultar de utilidad en algunas ocasiones. Para ello deberemos añadir el texto !important al final de la propiedad de estilo que deseamos proteger, como se muestra en el siguiente ejemplo: div p { color : red !important; }
Eliminar los estilos predeterminados de los navegadores: CSS Reset
Como comentamos antes, los propios navegadores incorporan unos estilos predeterminados, que son los responsables de que ciertas etiquetas tengan el aspecto que tienen por defecto, sea el caso del tamaño por defecto de los encabezados (h1-h6), por poner un ejemplo.
En ocasiones, estos estilos predeterminados de los navegadores pueden resultar contraproducentes, debido a que existen pequeñas diferencias en dichos estilos entre unos navegadores y otros. Por ello, en ocasiones puede incluso resultar interesante eliminar todos estos estilos predeterminados de los navegadores para eliminar inconsistencias, lo que también se conoce como CSS Reset.
Esto es posible, aunque deberemos realizarlo de forma manual, es decir, creando una hoja de estilos nueva en la cual añadiremos los estilos que deseamos sobrescribir. Seguidamente, podremos crear nuestras propias hojas de estilos, que añadiremos después en nuestra página, para de este modo, en caso de conflicto se resuelva de la forma que nos interesa (como ya hemos explicado antes ;-).
Una simple búsqueda por los interneses, nos ofrecerá distintas Hojas de Estilo CSS Reset que podremos utilizar o tomar como punto de partida, por lo que tampoco será necesario que perdamos tiempo en crearla nosotros desde cero. Un conocido ejemplo es el siguiente: CSS Tools: Reset CSS
Despedida y Cierre
Hasta aquí llega el artículo de hoy. Evidentemente, el mundo de las Hojas de Estilo CSS tan sólo comienza con los Selectores CSS, es decir, hay mucho más que ver para poder trabajar de una forma profesional con los Estilos en el Desarrollo Web, pero igualmente, es una de las partes más importantes, por lo que he creído conveniente aprovechar para escribir este artículo.
Poco más por hoy. Como siempre, confío que la lectura resulte de interés.