Definiciones y sintaxis CSS3
En el tema Selectores CSS nivel4 encontrará una recopilación de todos los selectores incluyendo los nuevos de CSS nivel 4.
Selectores CSS Nivel 3 (CSS3)
Los selectores CSS son patrones que realizan una selección de elementos en una página HTML o XML. La especificación en fase REC (estándar) W3C - CSS Selectors Level3 (CSS3) reúne los ya existentes y que también he publicado en este sitio en el tema CSS2.1 selectores así como otros nuevos que expondré en estos temas. Realmente no hay un CSS3 sino niveles de CSS, pues la especificación ya se ha desglosado en módulos evolucionando cada uno de ellos en niveles. El último nivel debe asumir lo especificado en niveles anteriores. A los efectos es como si CSS1 y CSS2 se desglosaran en módulos y pasaran a llamarse módulos del nivel 1 y 2 de CSS. Ahora tenemos el nivel 3 de CSS en todos esos módulos recogiendo y/o mejorando lo especificado en los niveles anteriores. Aunque seguimos conociéndolo como CSS3, tendremos que empezar a cambiar la forma de decir las cosas puesto que habrán algunos módulos que están ya en nivel 4. Un caso es el que nos ocupa sobre selectores W3C CSS Selectors Level 4 actualmente en fase WD, pero que no expondré aquí. El estado actual de las especificaciones CSS puede verlo en W3C CSS Specifications.
El nivel 3 de Selectores CSS ya está consolidado en los navegadores más recientes y conviene conocerlo para sacar el mayor partido a CSS. Empezaremos con una lista de definiciones más ajustada a la nueva especificación y un repaso a la sintaxis. De paso revisaremos la especificación poniendo enlaces a lo que ya tenía publicado sobre CSS2.1 y a lo nuevo en estos temas.
Definiciones y sintaxis CSS
Diferenciar entre los términos nos ayudará a leer documentación sobre CSS. Esta lista de definiciones engloba lo más importante que podemos encontrar en una hoja de estilo CSS:
- Hoja de estilo
- Una o más reglas y/o reglas arroba
- Regla at (regla arroba)
- Empieza con @ seguido de una palabra clave, una expresión y punto y coma. O bien un bloque conteniendo reglas. Algo como
@charset "utf-8";
o bien@media print { ...reglas... }
- Regla
- Una regla consiste en un grupo de selectores seguido por un bloque de declaraciones.
- Grupo de selectores
- Son uno o más selectores separados con coma (,).
- Selector
- Es una cadena de uno o más selectores simples separados por combinadores. (Estas definiciones se exponen en el siguiente apartado).
- Bloque de declaraciones
- Una más declaraciones separadas por punto y coma (;) y entre llaves ({ }).
- Declaración
- Una pareja propiedad y valor separados por dos puntos (:) y finalizado con punto y coma (;).
Un esquema gráfico de una hoja de estilo muy sencilla nos ayudará a entender la sintaxis CSS:
Una hoja de estilo es todo el contenido que puede haber dentro de un elemento <style>
o vinculado desde un archivo externo con <link rel="stylesheet" href="...ruta al archivo..." />
. La regla arroba sin bloque @charset "utf-8"
nos permite declarar el conjunto de caracteres del documento. Todo el estilo se incluye dentro de alguna regla con bloque @media clave { ... }
, donde clave
puede ser all, screen, print
entre otros. Por defecto cuando el estilo no se incluye dentro de un bloque @media
se supone englobado dentro de un @media all
que significa que aplica a todos los medios. Las reglas sin más son el verdadero cuerpo del estilo. Se componen de un grupo de selectores seguido por un bloque de declaraciones. El grupo de selectores se explica en el siguiente apartado. El bloque de declaraciones consta de parejas propiedad y valor separadas por punto y coma.
Definiciones sobre selectores CSS
Las principales definiciones sobres selectores son las siguientes:
- Grupo de selectores
- Dos o más selectores separados por comas que comparten una misma declaración. Por ejemplo:
h1, h2, h3 {color: blue}
- Selector
- Es una cadena de una o mas secuencias de selectores simples separadas por combinadores. Un pseudo-elemento puede ser añadido a la última secuencia de selectores simples en un selector.
- Secuencia de selectores simples
- Es una cadena de selectores simples que no se encuentran separados por un combinador. Siempre empieza con un selector de tipo o un selector universal no pudiendo contener más de estos.
- Selector simple
- Es uno de los siguientes:
- Selector de tipo de elemento es el nombre de un tipo de elemento HTML, por ejemplo
h1
. - Selector universal se escribe con un asterisco (*) y representa cualquier tipo de elemento HTML. Cuando es seguido por una secuencia de selectores simples o pseudo-elementos se puede omitir. Por ejemplo:
*[val=2]
es igual que[val=2]
*.val
es igual que.val
*:first-child
es igual que:firstchild
div *:first-child
se podría omitir quedando comodiv :first-child
. Aunque si no nos percatamos del espacio lo podríamos confundir condiv:first-child
que sería ya otra cosa diferente. - Selector de atributo permite seleccionar un elemento atendiendo a algún atributo. Los cuatro primeros
E[att]
,E[att=val]
,E[att~=val]
yE[att|=val]
se establecieron en selectores de atributo de CSS2-1. Otros nuevos se incorporan ahora en los selectores por atributos de CSS3. - Selector de clase es como
E.val
seleccionando un elementoE
con un atributoclass="val"
. Esta parte no ha variado con respecto a selectores de clase de CSS2-1. En ambas especificaciones se comenta que la selección por claseE.val
es equivalente a la selección por atributoE[class~=val]
. Por lo tanto un selector de clase nos permite seleccionar un nombre de clase entre una lista de clases separadas por espacios, aspecto que en su día no tuve en cuenta y que conviene conocer. - Selector de identificador es como
E#ident
seleccionando el elementoE
con un atributoid="ident"
. Esto permanece igual que lo visto en selectores por identificadores en CSS2-1. - Selector de pseudo-clase nos permite una selección basada en información que se encuentra fuera del árbol del documento o que no puede ser expresada usando los otros selectores simples. Las que ya se encontraban en las pseudo-clases de CSS2-1 eran las de primer hijo, de vínculo, dinámicas para acciones del usuario y de lenguaje. Ahora con las pseudo-clases de CSS3 se incorporan nuevos grupos y es la parte de selectores que más se ha incrementado.
- Selector de tipo de elemento es el nombre de un tipo de elemento HTML, por ejemplo
- Pseudo-elemento (opcionalmente finaliza un selector)
- Permiten aplicar estilo a contenidos que no se podrían marcar de otra forma, creando externamente un nuevo elemento que no existe en el documento. Vea que un pseudo-elemento no es un selector simple, ubicándose al final de un selector (tipo más secuencia más pseudo-elemento opcional). En pseudo-elementos de CSS2-1 teníamos
E:first-line
,E:first-letter
y para contenido generadoE:before
yE:after
. CSS3 no incorpora ningún pseudo-elemento nuevo. - Combinadores
- Son el espacio blanco (espacio, tabulador y salto de línea), signo mayor que (>), signo más (+) y tilde (~). Los combinadores permiten aplicar una selección por contexto entre varios selectores simples. En la selección por contexto en CSS2-1 teníamos
E F
,E>F
yE+F
. Ahora con los combinadores de CSS3 se incorporaE~F
para seleccionar un elementoF
precedido por un elementoE
pero no necesariamente de forma inmediata. - Sujeto del selector
- Son los elementos de un árbol del documento que son representados por un selector. Un selector representa algún elemento que satisface las condiciones que impone el selector.
Un esquema gráfico con un ejemplo de un grupo de selectores nos ayudará a entenderlo:
*.val p.cls:first-child::first-letter,div.val p#id>a:hover+b[att]
El selector representado en el esquema visual anterior se aplica al siguiente ejemplo:
Ejemplo:
Un párrafo <p> sin id con vínculo <a> más <b> sin att más vínculo <a> más <b att>
Un párrafo <p id="id"> con vínculo <a> más <b> sin att más vínculo <a> más <b att>
Un párrafo <p class="cls"> por fuera del <div class="val"> no es afectado por el estilo de la primera letra.
Código completo de este ejemplo
El estilo representado es *.val p.cls:first-child::first-letter, div.val p#id > a:hover + b[att]
. Cuando aún no hemos practicado lo suficiente con selectores puede ser duro de entender hasta que vayamos adquiriendo soltura con estas expresiones. En el esquema vemos un grupo de selectores formados por dos selectores. El primero tiene dos secuencias de selectores simples separados por el combinador espacio y finalizado con un pseudo-elemento. Una secuencia es una cadena de selectores simples, siempre empezando con una selector simple tipo o universal, luego puede tener cero o más selectores simples que no sean de tipo o universal. Las partes de la secuencia no pueden llevar ningún espacio entre ellas. El pseudo-elemento, que siempre estará al final del selector, se separa con doble dos puntos (::) en CSS3 pero en CSS2-1 se separa con dos puntos (:). Esto se hizo para diferenciar los pseudo-elementos de las pseudo-clases, aunque aún siguen funcionando los pseudo-elementos con sólo dos puntos (:) para los ya existentes en CSS2-1 (:first-line, :first-letter, :before, :after
).
Con este otro ejemplo podemos interactuar con la hoja de estilo para modificar el estilo de los elementos:
Ejemplo:
Párrafo primer hijo.
Otro párrafo hijo
Párrafo último hijo
Otro párrafo por fuera del <div>
anterior.
Código completo de este ejemplo
Para probar como se ejecuta el encadenamiento de selectores hemos puesto cuatro casillas de verificación para observar este proceso. El ejemplo se ejecuta con JavaScript modificando la regla en la hoja de estilo, tal como se explica en el apartado siguiente. Inicialmente aparecen todas las casillas desactivadas. Puede activarlas en cualquier orden, pero para el orden dado se exponen las siguientes observaciones:
- Con
div.miclase
seleccionamos todos los elementos de la página que seanclass="miclase"
. Sólo hay un<div class="miclase">
y lo verá con color azul y fondo naranja. - Si agregamos ahora
div.miclase p.miparrafo
seleccionamos todos los elementos párrafo<p class="parrafo">
que estén dentro de<div class="miclase">
. Por fuera hay otro que no será seleccionado. - Al aplicar la pseudo-clase
div.miclase p.miparrafo:first-child
partimos de la selección anterior (los tres párrafos) y elegimos el que tenga la condición de primer hijo del<div class="val">
. Es el primero de los tres pues no hay otro elemento que sea primer hijo del<div>
, dado que el texto que hay antes del primer párrafo no contiene HTML y los nodos texto no se consideran elementos a efectos de aplicar selectores CSS. - Por último sobre esa selección (el primer hijo) aplicamos el pseudo-elemento
div.miclase p.miparrafo:first-child::first-letter
generándose un nuevo elemento con la primera letra del primer párrafo para dotarle del estilo. Usamos (:) en lugar de (::) para que sea compatible con navegadores que no soporten CSS3.
Algunas otras combinaciones entre las anteriores darán distinto resultado. Marcando p.miparrafo::first-letter
aplicará estilo a la primera letra de todos los <p class="miparrafo">
de la página. Marcando sólo ::first-letter
resaltará la primera letra de todos los elementos de bloque de la página. En este caso al no haber un selector de tipo por defecto se supone que es todos los elementos, es decir, equivale a *::first-letter
.
Las hojas de estilo stylesheet
El estilo lo podemos incorporar en un archivo externo, en un elemento <style>
en el <head>
del documento o en línea dentro de un atributo style
del elemento. Los dos primeros son las llamadas hojas de estilo o style sheet. Lo óptimo es incluirlo en un archivo externo si ese estilo es de frecuente uso en múltiples documentos del sitio. En otro caso si sólo afecta a un documento o es de pequeño tamaño es mejor ubicarlo en el <head>
del documento pues así evitamos peticiones adicionales al servidor de un archivo externo. Hay que ubicar todo el estilo lo más arriba que podamos en el documento, pues el navegador cargará esos estilos y los tendrá disponibles cuanto antes para comenzar a renderizar la página.
Pero para hacer una página como esta con ejemplos CSS y dotarla de mayor utilidad he creido conveniente incorporar el estilo con JavaScript. Así la acción del usuario puede modificar el estilo de un elemento y observar con detenimiento como se aplica el mismo. Para evitar tener que incorporar el estilo en línea con JavaScript hemos de buscar la forma de incorporarlo a las hojas de estilo. La especificación W3C DOM Level 2: Style Sheets trata de establecer un estándar para que todos los navegadores manejen de igual forma las hojas de estilo. Está página W3C Dynamic style - manipulating CSS with JavaScript también nos ayudará sobre el tema. El siguiente ejemplo busca todas las hojas de estilo de este documento y hace cambios en una de ellas (ejecute el botón "BUSCAR HOJAS"):
Ejemplo:
Código completo de este ejemplo
En la lista de hojas de estilo de este documento aparecen las vinculadas externamente en los archivos cabeza-pie.css, interior.css y formatos.css. Luego hay dos con A la href = null
correspondiente a dos elementos <style>
ubicados en la cabecera del HTML de esta página.primera segunda le he puesto un id = hoja-estilo-head
que aparece resaltado en azul y es sobre la que se ejecuta el ejemplo de este apartado. La otra hoja (hoja-estilo-head2
) nos sirve para ejecutar un ejemplo en el apartado anterior.
<style>
en la página. Las hojas de estilo con id="css-before"
y id="css-after"
contienen el estilo que antes estaba en los archivos que vinculaba externamente. Por lo tanto todas las hojas de estilo de esta página tendrán href=null
pues están en elementos <style>
.Se pueden observar los métodos insertRule()
y deleteRule()
. Estos son los estándar para insertar y eliminar una regla en la hoja de estilo. Chrome 23.0 también incorpora addRule()
y removeRule()
que son métodos equiparables a los de IE8, navegador que no soporta los métodos estándar. Sin embargo para IE8 y cualquier navegador que no soporte estos métodos yo se los agrego con este código:
El código para el ejemplo anterior tiene las funciones insertarRegla()
y eliminarRegla()
. Al cargarse la página se ejecuta el listado de hojas de estilo que se encuentran en document.styleSheets
. Iteramos por las hojas de estilo y extraemos el atributo href
y el id
. Cuando identificamos id = hoja-estilo-head
guardamos una referencia a esta hoja que es el estilo del elemento <style>
que hay en la cabecera de esta página. Ahí insertaremos o eliminaremos una regla para dotar de color rojo al elemento de prueba.
El elemento <span id="palabra2">
no tiene inicialmente un color declarado y toma el color verde heredado del contenedor padre, como se observa en la primera imagen de estas capturas de pantalla. Vea como Matched CSS Rules son las reglas CSS encontradas para ese elemento, mientras que inherited from... es lo heredado del padre.
Tras ejecutar la inserción de la regla vemos el color rojo en una regla separada. El color verde del padre aparece tachado significando que ese estilo ha sido sobrescrito. Al eliminar la regla volvemos a la situación inicial, tomando de nuevo el color verde.
Las acciones del ejemplo anterior podíamos haberlas hecho con estilo directo, es decir, con algo como elemento.style.color = "red"
. Pero a efectos de hacer ejemplos sobre selectores CSS y que sean a la vez interactivos usando JavaScript hay que aprender a insertar y eliminar reglas en una hoja de estilo.