lunes, 11 de abril de 2011

Herencia y cascada en CSS

Sigo camino recto a encontrar el nirvana del CSS.

En el anterior post vimos que era la directiva DOCTYPE, el modo quirk y strict del navegador y cómo validar nuestro código.

Hoy vamos a ver conceptos todos ellos relacionados ya con CSS, que ya toca.

RELACIONES ENTRE ELEMENTOS

Lo primero que deberías saber es que cuando un documento HTML se carga en el navegador, en realidad el navegador construye un árbol de contenido (DOM tree) con todos sus elementos.

En este árbol todos los elementos tienen una relación de parentesco con otros elementos. De este modo podemos encontrar las siguientes relaciones (esto es importante porque después y a través de los selectores podremos hacer uso de estas relaciones para afinar la selección):

·         Padre (Parent)

·         Hijo (Child)

·         Hermano (Sibling)

·         Hermano adyacente (Adjacent sibling)

·         Nieto o descendente (Descendent)

Por ejemplo, para el siguiente código:

<div id="Div1">

<div id="Div1_1">

</div>

<div id="Div1_2">

<div id="Div1_2_1">

</div>

</div>

</div>

<div id="Div2">

</div>

·         Div1 es padre de Div1_1 y Div1_2

·         Div1_1 y Div1_2 son hijos de Div1

·         Div1 es hermano de Div2

·         Div1_1 es hermano de Div1_2

·         Div1_2_1 es hijo de Div1_2

·         Div1_2_1 es descendiente de Div1

·         Div1_2 es hermano adyacente de Div1_1, pero Div1_1 no es hermano adyacente de Div1_2

HERENCIA

Este es uno de los conceptos que se deben entender a la perfección sí o sí.

Como hemos visto antes, existe una relación de parentesco entre los elementos del documento. Pues bien, esta relación permite heredar propiedades CSS de padres a hijos.

Por ejemplo, si un elemento padre tiene especificado el color rojo, sus hijos automáticamente también tendrán el color rojo sin necesidad de especificar esta propiedad de forma explícita. Está claro que la herencia nos ayuda a escribir menos y de eso modo ahorrar código. Ahora bien, existen algunas normas a tener en cuenta a la hora de hablar de herencia:

·         No todas las propiedades CSS se heredan.

·         La herencia afecta a cualquier elemento descendente. Es decir, un hijo hereda de su padre pero a su vez, un nieto hereda del hijo de su padre, etc. Esto es así hasta que alguien rompa la herencia. Por ejemplo, si el hijo decidió tener el color amarillo (en vez del rojo que heredó de su padre), ahora el nieto heredará el color amarillo. En realidad, en caso de tener varios valores heredados (lo que pasa al nieto que hereda tanto del padre como del abuelo) siempre se aplica el valor más cercano en el parentesco.

¿Cómo saber si una propiedad es heredable?

 

Pues está el método “ensayo-error” que no recomiendo, y luego está el método científico que es leer la especificación de w3c y por cada propiedad hay una bonita información que nos dice si es o no heredable. Por ejemplo background-color no es heredable, pero font-size si es heredable.

 

Además, en la especificación también nos dice a qué elementos se puede aplicar qué propiedad, cuál es su valor inicial, etc.

clip_image001[1]


Para terminar de ilustrar la herencia veamos un ejemplo basado en el anterior.

Si tenemos la siguiente hoja de estilos:

<style type="text/css">

#Div1 { color: Red; }

#Div1_2 { color: Green; }

</style>

 

El color de Div1_2_1 ¿De qué color será? Veamos, hereda el color rojo (Red) de Div1 (abuelo) y también el color verde (Green) de Div1_2 (padre), así que su color finalmente será… Verde, que es el color más cercano en el parentesco.

clip_image002[1]

Aquí también aprovecho para meter la cuña de Firebug, ese “indispensable” complemento de Firefox que nos ayuda a entender el CSS (entre otras muchas cosas). Como vemos, la lista de estilos se lee de “abajo a arriba” y nos indique qué propiedades heredó el elemento y de quién.


CASCADA

Este concepto es un poco más duro de asimilar. De hecho, CSS es el acrónimo de Cascading Style Sheets. Como vemos la palabra Cascada (Cascading) está en el propio nombre de CSS así que digo yo que es importante pero ¿Qué es exactamente la cascada?

Antes de comenzar veamos un ejemplo para darnos cuenta de su importancia.

<style type="text/css">

#Div1

{

color: Red;

font-size: 12px;

}

</style>

 

<div id="Div1">

<h1 id="H1">Título 1</h1>

<div id="Div1_1">Div1_1</div>

</div>

 

Viendo este código cualquiera pensaría que tanto el elemento H1 como el elemento Div1_1 será rojos y tendrán un tamaño de fuente de 12px (ambas propiedades heredadas desde Div1), pero al verlo en acción nos damos cuenta que el elemento H1 heredó el color pero no el tamaño de fuente ¿Por qué?

clip_image003[1]

Para ambos elementos, Firebug muestra:

clip_image004[1]

Sin embargo, en la pestaña “Calculado” vemos que el elemento H1 tiene un valor de 24px para font-size:

clip_image005[1]

Si habilitamos “Mostrar CSS del agente de usuario”:

clip_image006[1]

Ahora ya podemos ver lo siguiente:

clip_image007[1]

Como vemos, la propiedad font-size: 12px no se aplica al elemento H1 y sin embargo se aplica un font-size: 2em (el doble de lo heredado, luego 12x2 = 24px). Pues bien, esto es la cascada.

Lo que hay que entender sobre la cascada es que, además de nuestra hoja de estilos, hay otros dos orígenes de estilos que también se pueden aplican a nuestro código. Es decir, además de nuestra hoja de estilos (también llamada de “autor”), encontraremos la hoja de estilos del “navegador” y la hoja de estilos del “usuario” (sobre las que, por cierto, no tenemos control alguno).

La hoja de estilos del navegador es la encargada de dar cierto formato inicial a los elementos HTML. Por ejemplo, la etiqueta <strong> se ve en negrita porque la hoja de estilos del navegador la pone inicialmente en negrita, es decir, la w3c “no” dice que <strong> es negrita, simplemente dice que <strong> es una etiqueta para resaltar texto ¿Cómo resaltarlo? Eso es problema del navegador, del autor de la página o del propio usuario. Esto mismo podría aplicarse a <em> (énfasis), H1, etc.

La hoja de estilos del usuario existe como mecanismo para prevalecer la voluntad del usuario final sobre cualquier otra. Por ejemplo, un usuario con problemas de visión podría definir que los textos siempre sean de un determinado tamaño que él pueda leer.

Finalmente encontramos la hoja de estilos del autor (que engloba todo el código CSS del creador de la página sin importar su ubicación en el documento).

La pregunta inmediata es ¿Quién prevalece? Pues la regla es muy sencilla, de menor a mayor importancia:

·         Navegador

·         Usuario

·         Autor

Con esto queda claro que “nosotros” (los autores) tenemos al final la última palabra sobre el diseño de nuestra página, pero claro, ¿Dónde quedó la solidaridad con ese usuario con problemas de vista al que “machacamos” sus estilos y todavía ve el texto pequeño? Para solucionar esto aparece en escena la regla !important.

!important

La regla !important se añade al final de la definición de la regla CSS.

#Div1 { font-size: 12px !important }

Su función es romper la herencia y la cascada y hacer que la definición de la regla sea la más importante, de modo que ante varias reglas iguales, prevalezca siempre la que se definió como !important.

Después de haber introducido !important ahora el orden de aplicación queda de la siguiente forma:

·         Navegador

·         Usuario

·         Autor

·         !important de autor

·         !important de usuario

Fijarse como finalmente el usuario y a través de !important puede hacer prevalecer su deseo de ver el texto en un tamaño mayor y así estará a salvo de creadores que hacen diseños para gente con super-vista.

ESTANDARIZANDO ESTILOS DEL NAVEGADOR

Por último y para finalizar este post, me gustaría hablarte sobre una solución más o menos estándar que se utiliza para resolver el problema de que distintos navegadores tiene distintas hojas de estilo de navegador.

Imagina por ejemplo que Firefox dijo que el texto de H1 tenía que ser el doble de lo heredado (2em) pero ¿Qué pasa si IE dice que tiene que ser 3 veces el doble de lo heredado? Cómo podrás imaginar eso puede echar por tierra nuestro diseño así que la solución para por “resetear” las hojas de estilo.

Esta solución básicamente “limpia” todos los estilos aplicados por las hojas de estilo del navegador como paso inicial antes de aplicar nuestras hojas de estilo de autor, de este modo podremos estar seguro de que nuestro diseño es “cross-browser” (se vea igual en todos los navegadores).

Puedes visitar los siguientes enlaces que explican esta técnica perfectamente http://www.anieto2k.com/2007/08/07/reseteando-estilos-css/, http://www.anieto2k.com/2009/07/27/css-reset-para-html5/

Un saludo!

4 comentarios:

  1. Excelente aporte, muy buena la forma de explicar!!

    ResponderEliminar
  2. buen aporte! muy buen explicado, se agradece

    ResponderEliminar
  3. Estupendo! Mi enhorabuena por su excelente post.

    ResponderEliminar
  4. me gusta el aporte y nisisquiera tuve q leerlo jajajajajajaaa

    ResponderEliminar