27/09/2018 | Desarrollo de software,Tecnologías

Entendiendo CSS (parte 1)

Una de las mejores maneras de comenzar a aprender Cascading Style Sheets (CSS) es saltar directamente a la práctica y empezar a jugar con los propiedades y valores. Probablemente cogiendo consejos de varios blogs, viendo código fuente de referencia para ver cómo han conseguido determinados efectos o explorando repositorios open source en busca de fragmentos de código.

Sentarse e ir probando es una manera genial de empezar, pero si no tenemos cuidado, podemos acabar entendiendo mal algún fundamento crucial y tener problemas más adelante, sobre todo cuando queramos alcanzar diseños más complejos.

En esta primera entrega de la serie de entradas sobre CSS vamos a ver qué necesitamos para empezar por la base y conseguir que nuestro HTML luzca bonito. Responderemos a preguntas como: ¿cómo hago que mi texto sea negro o rojo?, ¿cómo hago que cierto contenido aparezca en el sitio de la pantalla que yo quiero?, ¿como decoro mi página con una imagen de fondo?

¿Qué es CSS?

No es un lenguaje de programación. Tampoco un lenguaje de marcado. Es un lenguaje específico para diseño gráfico. Nos sirve para aplicar estilos de forma selectiva elementos del DOM (estructura de documento escrito normalmente en HTML) que nosotros queramos. Por ejemplo, para hacer que todos los párrafos de texto (elementos tipo <p>) sean de color rojo, escribiríamos esto:

La estructura entera que vemos en la imagen recibe el nombre de “rule set” (o “rule” para abreviar).

Selector

Un nombre que representa el/los elementos HTML que queremos estilizar. Es la referencia o el “gancho” que conecta un estilo con un determinado elemento. Hay distintos tipos, como veremos más adelante.

Propiedad

Las características que podemos modificar del elemento (por ejemplo, además del color, podemos modificar el ancho del elemento con width, su alto con height, su tamaño de letra con font-size, etc.).

Valor de la propiedad

Aquí estableceremos uno de los posibles valores que la propiedad puede tomar (por ejemplo, color puede ser red, black, un valor hexadecimal como #1234ab, etc.).

Declaración

Una rule formada por propiedad y su valor.

Seleccionando nuestros elementos

Aprovechando que hemos visto el ejemplo de los párrafos, vamos a analizar las distintas formas de seleccionar un elemento HTML para aplicarle un estilo:

Selectores comunes

Los más comunes son los type y descendant selectors. Los selectores de tipo se usan para seleccionar un tipo particular de elemento (un p, h2, span, etc.). También son conocidos como selectores de element. Por ejemplo, así podemos hacer que todos los párrafos sean de color rojo:

Los descendants selectors permiten seleccionar los descendientes (no nos referimos solo a hijos directos, también pueden ser nietos o estar a cualquier otro nivel, siempre “hacia abajo”en el DOM). Así, todos los párrafos que sean descendientes de un blockquote serán de color rojo, el resto no:

Como el nombre sugiere, los selectores de ID y clase seleccionan un elemento según el valor de sus atributos ID y class. En CSS, denotamos una ID usando el carácter hash (#) seguido del ID, y para denotar una clase usamos un punto (.) seguido del nombre de la clase. En el siguiente ejemplo, solo los elemento con id=”intro” tendrán el fondo de color verde.

Y solo los elementos con class=”article” tendrán el fondo de color amarillo:

Podemos combinar selectores de distintos tipos para conseguir más precisión. Por ejemplo, solo los elementos de tipo h1 cuyo padre tenga id=”latest” serán de color rojo. Si el elemento es de tipo h1 pero su padre tiene id=”older”, h1 no recibirá ningún estilo.

A lo mejor te sorprendería saber que con estos cuatro tipo de selectores se pueden seleccionar un montón de elementos de maneras diferentes. A menudo, son la base de un CSS mantenible. Existen otros selectores avanzados que pueden ser muy útiles, pero no son igual de flexibles y potentes que los más simples y comunes que acabamos de ver.

Selectores avanzados

Mientras que el descendant selector seleccionará todos los descendientes de un determinado tipo de un elemento, el child selector solo seleccionará los descendientes directos de un determinado tipo de un elemento.

Si alguna vez queremos estilizar un elemento según su proximidad a otro, podemos usar el adjacent sibling selector. Nos permite seleccionar aquel elemento que es precedido por otro elemento compartiendo el mismo padre. Usa el combinador +.

El general sibling selector nos permite seleccionar todos los elementos que son precedidos por otro elemento compartiendo el mismo padre. Usa el combinador ~.

El universal selector es como un comodín, y selecciona todos los elementos.

Selectores de atributos

Selecciona un elemento según alguno de sus atributos. En la imagen de ejemplo de más abajo:

  1. Aquellos p que tengan un atributo title (no nos importa su valor).
  2. Aquellos input cuyo atributo type sea igual a “submit”.
  3. Aquellos a cuyo atributo href empiece por “https:”. “Empezar con” se indica con ^ antes del =.
  4. Aquellos img cuyo atributo src acabe en .jpg. “Acabar en” se indica con $ antes del =.
  5. Aquellos a cuyo atributo href contengan “/about/”. “Contener” se indica con * nens del =.
  6. Aquellos a cuyo atributo rel esté formado por una lista de strings separados por espacios, en la que uno de esos strings sea “next”.
  7. Aquellos a cuyo atributo hreflang acabe en “en” o “en” más “-” más algo más. Por ejemplo, elementos con atributos href=”en”, href=”en-us” o href=”en-UK” serían válidos.

Pseudo-clases

Son selectores que dependen no de la estructura del elemento, sino de su estado (si está clickado, si tiene el cursor encima, si tiene el foco en él, etc.). Una regla para recordarlos puede ser la siguiente:

El orden en el que son declaradas en el archivo CSS es importante.

Otras pseudo-clases están enfocadas a trabajar con las posiciones de los elementos, como las siguientes:

tr:nth-child(odd): aplica un estilo (fondo amarillo) a las filas (tr) cuya posición (dentro una tabla, por ejemplo) es impar (odd).

tr:nth-last-child(3): Selecciona la tercera fila (tr) del documento empezando por el final del mismo.

tr:nth-of-type(3): selecciona el tercer elemento de tipo tr en el documento.

tr:nth-last-of-type(3): selecciona el tercer elemento de tipo tr en el documento, empezando por el final del mismo.

Pseudo-clases para formularios

Hay un número de pseudo-clases que sirven específicamente para seleccionar elementos dentro de formularios. Por ejemplo:

:required (para cuando un elemento es obligatorio), :optional (como su nombre indica, para cuando un elementos es opcional), :valid (para cuando un elementos es válido), etc.

Conceptos importantes

Cascada

Es el proceso mediante el cual CSS sabe a qué elemento tiene que aplicar el estilo. Es especialmente útil cuando hay varias declaraciones de estilo que son aplicadas al mismo elemento HTML (un conflicto). Variables que tiene en cuenta el proceso de cascada a la hora de determinar qué estilo aplicar a qué elemento: importancia, origen de los estilos y especificidad.

Importancia y origen de los estilos

Un ejemplo:

Imagina que uno de los estilos que el navegador aplica por defecto hace que todos párrafos (<p>) sean de color negro.

Entonces, un usuario que visita nuestra página abre las Chrome Dev Tools y establece que todos los párrafos van a ser de color negro.

Pero, después imagina que nosotros, como desarrolladores, escribimos nuestra propia hoja de estilos para nuestra página y establecemos que los párrafos van a ser de color naranja.

Finalmente. también podría ocurrir que nosotros como desarrolladores o un usuario establezca una propiedad a un valor con la palabra clave !important, que haría que la propiedad se aplicase directamente, independientemente de quien la haya establecido. 

Entonces, ¿cómo sabe CSS qué estilo aplicar a qué elemento?

El proceso es el siguiente:

  1. Encontrar todas las declaraciones que aplican a un mismo elemento en concreto (en el ejemplo anterior, encontramos al menos tres estilos aplicados al elemento p proveniente de diferentes fuentes)
  2. Ordenar las declaraciones según su importancia (normal o !important) y origen (desarrollador, usuario o navegador). (Ver tabla azul).
  3. Si las declaraciones tienen la misma importancia y fuente, ordenarlas por especificidad del selector (a continuación, veremos qué es la especificidad).
  4. Finalmente, si las declaraciones tienen la misma importancia, fuente y especificidad, ordenarlas por el orden en el que aparecen en el archivo CSS. La última declaración gana.

Especificidad

La especificidad es un valor numérico que indica cuán preciso es un estilo. Mientras mayor sea ese valor para un estilo, más prioridad tiene de cara al resto de estilos para aplicarse finalmente. Para calcular la especificidad se tienen en cuenta cuatro variables:

– a: Vale un “punto” si el estilo está declarado en el mismo elemento HTML y no en el archivo CSS.

– b: Número de selectores de ID.

– b: Número de clases, pseudo-clases y selectores de atributos.

– c: Número de selectores por tipo y pseudo-elementos.

Algunos ejemplos:

Primero, podemos observar que el estilo declarado en línea es el que mayor especificidad tiene (1000) por lo que sobreescribirá a cualquier estilo que declaremos como desarrolladores (por ejemplo, en un archivo .css por separado). Por otro lado, podemos ver que tanto #wrapper #content {} como #content {} quieren aplicar un estilo al mismo elemento HTML. Como la especificidad del primero (200) es mayor que la del segundo (100), el estilo que se aplicará finalmente será el declarado en #wrapper #content {}.

Herencia

Cascada y herencia son dos conceptos frecuentemente confundidos. Pero son diferentes.

La herencia se refiere a los estilos que son aplicados de manera indirecta. Podemos pensar en esto como si se tratara de herencia en la vida real: si nuestros padres tienen ojos azules, es probable que nosotros heredemos también ese color. Pero es algo que nos llega porque el proceso funciona así, no lo hemos decidido nosotros. En CSS, los estilos se heredan de elementos padres a hijos.* En el siguiente ejemplo podemos ver que, aplicando un color rojo a todos los div’s del documento, sin declararlo explícitamente (por ejemplo, con p { color : red; }), tanto al elemento h1 como al p se les aplica el mismo color rojo. La transmisión de padres a hijos la podemos ver visualmente en el árbol del DOM.

Sin embargo, en CSS hay también estilos que son aplicados de manera directa. Esto ocurre cuando somos nosotros los que los escribimos “a mano” en el archivo CSS, usando selectores y dando valores a las propiedades.

* Propiedades que se pueden heredar en CSS pueden ser font-size o font-family. Y, como en la herencia en la vida real, hay propiedades que se heredan y otras que no (como border). La siguiente página proporciona una lista completa de las propiedades que se pueden heredar y las que no: https://www.w3.org/TR/CSS21/propidx.html.

Los estilos heredados no tienen especificidad como tal, ni siquiera cero (es como si fuera null).

Conclusiones

Hasta aquí la primera parte de la serie sobre CSS. Ahora podemos empezar a estilizar nuestro HTML, solo necesitamos marcar nuestros elementos HTML con clases o ID’s para poder referenciarlos desde nuestro CSS a través de selectores. Dentro de esos selectores declararemos propiedades con diferentes valores hasta conseguir aplicar al elemento el estilo que deseamos.

A medida que nuestros diseños vayan progresando en complejidad, nos será útil conocer cómo funciona el modelo de caja (en CSS todo son cajas y más cajas) y cómo posicionar los elementos en nuestra página. Usando las combinaciones adecuadas de selectores y propiedades, podemos llegar a implementar diseños complejos y robustos. Esto lo iremos viendo en las próximas publicaciones de la serie.

Compartir en:

Relacionados