0% encontró este documento útil (0 votos)
28 vistas64 páginas

Pseudoclases y Combinadores CSS

Este documento describe conceptos avanzados de CSS como selectores avanzados, pseudoclases, prefijos, transiciones, animaciones, transformaciones y responsive design. Explica selectores como el descendiente, hijo, hermano adyacente y universal, así como pseudoclases para enlaces como :link y :visited. También cubre temas como responsive design y el uso de media queries.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
28 vistas64 páginas

Pseudoclases y Combinadores CSS

Este documento describe conceptos avanzados de CSS como selectores avanzados, pseudoclases, prefijos, transiciones, animaciones, transformaciones y responsive design. Explica selectores como el descendiente, hijo, hermano adyacente y universal, así como pseudoclases para enlaces como :link y :visited. También cubre temas como responsive design y el uso de media queries.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Unidad 3 CSS

 Selectores avanzados de CSS


 Pseudoclases
 Prefijos de CSS
 Transiciones, Animaciones y Transformaciones
 Responsive Web Design (Desktop First - Mobile First)
 Introducción a MediaQueries básico
 CSS Grid
.Fuente: [Link] y [Link]

Selectores avanzados de CSS


Al margen de la selección «básica» de elementos a través de CSS, que suele realizarse mediante clases e
IDs, existe un amplio abanico de métodos para seleccionar elementos dependiendo de la estructura
del documento HTML denominados combinadores CSS:

Nombre Símbolo Ejemplo Significado

Agrupación de selectores , p, a, div { } Se aplican estilos a varios elementos.

Selector descendiente #page div { } Se aplican estilos a elementos dentro de otros.

Selector hijo > #page > div { } Se aplican estilos a elementos hijos directos.

Selector hermano + div + div { } Se aplican estilos a elementos que siguen a otros.
adyacente

Selector hermano general ~ div ~ div { } Se aplican estilos a elementos al mismo nivel.

Selector universal * #page * { } Se aplican estilos a todos los elementos.

En los siguientes apartados, veremos varios ejemplos gráficos sobre un supuesto ejemplo de documento
HTML, dibujado en forma de árbol esquemático. Así sabremos que elementos están dentro de otros y
nos será más fácil entender cada uno de los combinadores CSS.

Agrupación de selectores

En muchas ocasiones nos ocurrirá que tenemos varios bloques CSS con selectores diferentes pero con
los mismos estilos exactamente, algo que generalmente no es apropiado. Si esto ocurre a menudo, el
tamaño del documento CSS ocupará más y tardará más en descargarse:
.container-logo {

border-color: red;

background: white;

}
.container-alert {

border-color: red;

background: white;

.container-warning {

border-color: red;

background: white;

Una buena práctica es ahorrar texto y simplificar nuestro documento CSS lo máximo posible, por lo
que podemos hacer uso de la agrupación CSS utilizando la , (coma).

De esta forma, podemos pasar de tener el ejemplo anterior, a tener el siguiente ejemplo (que es
totalmente equivalente), donde hemos utilizado la agrupación para decirle al navegador que aplique
dichos estilos las diferentes clases:
.container-logo, .container-alert, .container-warning {

border-color: white;

background: red;

Al margen de esto, dos buenas prácticas que podríamos aplicar en esta situación serían las siguientes:

■ Simplifica por responsabilidades: .container-alert y .container-warning parecen tener un


concepto muy similar: alertas o mensajes de advertencia. Es posible que estos selectores tengan
la misma funcionalidad y sean sinónimos. Si es así, lo ideal sería refactorizar y simplificarlos a
uno: .container-warning, haciendo desaparecer el otro.

■ Legibilidad por delante: CSS por si sólo puede ser difícil de leer y mantener. Aunque a priori
puede parecer que es mejor poner la lista de selectores uno detrás de otro, la experiencia nos
dicta que deberíamos separarlos en una línea diferente cada selector. Esto lo hace
tremendamente más legible a la hora de revisar código CSS.
.container-logo,

.container-warning {

border-color: white;

background: red;

}
Consejo: Esto puede parecer poco importante a priori, pero a medida que avanzamos con nuestro
diseño, los documentos CSS se hacen tremendamente grandes y difíciles de mantener, por lo que cuanto
más sencillos sean, mejor.

Selector descendiente

En CSS podemos utilizar lo que se llama el selector descendiente, que no es más que una forma de
seleccionar ciertos elementos que están dentro de otros elementos. Esto

puede parecer sencillo, pero cuidado, ya que puede ser una fuente de problemas si no se entiende bien.

Su sintaxis se basa en colocar los elementos uno a continuación de otro, separado por un espacio:
div#pagina div {

background-color: blue;

En el ejemplo anterior, aplicamos los estilos CSS (color azul de fondo) a todos los elementos <div> que
estén dentro de un <div> con ID pagina. De esta forma, si existe un elemento <div> fuera del <div>
con id pagina, no se aplicarán los estilos indicados:

Repasemos varios detalles importantes respecto a este combinador CSS:

■ Se están seleccionando todos los elementos <div> que están dentro de <div> con ID pagina.

■ Observa que se seleccionan independientemente del nivel al que estén (hijos, abuelos, ...)
■ En este caso, el div de div#pagina es innecesario, ya que habíamos dicho que los IDs no se
pueden repetir. Si ya existe un elemento con ID pagina, no hace falta diferenciarlo también por
etiqueta. Si se tratase de una clase, si podría usarse.

Se pueden construir selectores muy complejos con tantos elementos como se quiera, pero una buena
práctica es mantenerlos simples. Cuántos más elementos descendientes existan en un selector, más
complejo será el procesamiento de dicha regla por los navegadores. Lo recomendable es ser despierto y
utilizar sólo los necesarios.
<div class="menu">

<div class="options">

<ul>

<li><a href="/one">Option 1</a></li>

<li><a href="/two">Option 2</a></li>

<li><a href="/three">Option 3</a></li>

</ul>

</div>

</div>

Observando el fragmento de código HTML anterior, veamos las siguientes 2 formas de aplicar estilos CSS a los enlaces <a>:

/* Forma 1 */

.menu .options ul li a {

color: orange;

/* Forma 2 */

.menu a {

color: orange;

Mientras que la primera es mucho más específica, es una muy buena práctica en CSS mantener los
selectores lo menos específicos posibles para evitar problemas de Especificidad (a.k.a. CSS Peter
Griffin):

Selector hijo

Aunque el selector descendiente es bastante interesante, nos puede interesar hacer la misma operación,
pero en lugar de seleccionar todos los elementos descendientes, seleccionar sólo los descendientes
directos del elemento con el símbolo >, descartando así nietos y sucesivos.
#pagina > div {

background-color: blue;
}

Veamos los elementos seleccionados en el documento de ejemplo para afianzar conceptos:

Al contrario que en el caso anterior, no se seleccionan todos los elementos <div> descendientes, sino
solo aquellos que son hijos directos del primer elemento especificado.

Selector hermano adyacente

Es posible también hacer referencia a los elementos hermanos, es decir, aquellos elementos que están
directamente a continuación del elemento especificado. Mediante el símbolo + del selector hermano
adyacente, se pueden seleccionar aquellos elementos hermanos que están seguidos el uno de otro (en el
mismo nivel):
[Link] span + span {

color: blue;

Cómo se podrá ver en este nuevo ejemplo, este combinador CSS hará que se seleccionen los elementos
span que estén a continuación de un [Link] span:
Obsérvese que el primer elemento <span> no es seleccionado, puesto que es el que estamos tomando de
base. Una buena forma para entenderlo es leerlo de la siguiente forma: «todo elemento <span> que esté
inmediatamente precedido de un <span>».

Selector hermano general

Si pensamos otras opciones en el ejemplo anterior, es posible que necesitemos ser menos específicos y
en lugar de querer seleccionar los elementos hermanos que sean adyacentes, queramos seleccionar
todos los hermanos en general, sin necesidad de que sean adyacentes. Esto se puede conseguir con el
selector hermano general, simbolizado con el carácter ~:
Como se ve en el ejemplo, no es necesario que el elemento strong se encuentre adyacente al primero,
sino que basta con que sean hermanos en el mismo nivel.

Selector universal

Por último, el selector universal se simboliza con un asterisco * y es la forma de aplicar ciertos estilos
en TODOS Y CADA UNO de los elementos HTML correspondientes.
Este ejemplo selecciona todos los elementos dentro de div#menu. Es importante recalcar la diferencia
de seleccionar #menu, a seleccionar todos los elementos dentro de #menu, que es lo que estamos
haciendo en este caso.

El selector universal puede ser muy útil en algunos casos para resetear ciertas propiedades de todo un
documento, como en el siguiente ejemplo, donde se eliminan los márgenes de todos los elementos del
documento HTML, puesto que algunos navegadores ponen márgenes diferentes y esto puede producir
ciertas inconsistencias en los diseños:
/* Elimina márgenes y rellenos de todos los elementos de un documento HTML */

*{

margin: 0;

padding: 0;

Las pseudoclases se utilizan para hacer referencia a ciertos comportamientos de los elementos HTML.
Así como los combinadores CSS se utilizan para dar estilos dependiendo de donde estén colocados en la
estructura del HTML, las pseudoclases se utilizan para dar estilos a elementos respecto al
comportamiento que experimentan en determinado momento.

Volvamos a recordar el esquema general de sintaxis de CSS:


Las pseudoclases se definen añadiendo dos puntos antes de la pseudoclase concreta. En el caso de
existir selectores de etiqueta, id o clases, estas se escribirían a su izquierda.

Pseudoclases de enlaces

Existen algunas pseudoclases orientadas a los enlaces o hipervínculos. En este caso, permiten cambiar
los estilos dependiendo del comportamiento del enlace:

Pseudoclase Descripción

:link Aplica estilos cuando el enlace no ha sido visitado todavía.

:visited Aplica estilos cuando el enlace ha sido visitado anteriormente.

A continuación veremos un ejemplo donde seleccionamos mediante un simple selector a los enlaces que
aún no han sido visitados, cambiando el color de los mismos o su formato, lo que mostrará dichos
enlaces de color verde y en negrita:
a:link {

color: green;

font-weight: bold

Por otro lado, la pseudoclase :visited puede utilizarse para dar estilo a los enlaces que hayan sido
visitados previamente en el navegador del usuario:
a:visited {

color: purple;

font-weight: bold

Pseudoclases de ratón

Originalmente, las siguientes pseudoclases se utilizaban solamente en enlaces (Internet Explorer no los
soportaba en otros elementos). Sin embargo, actualmente pueden ser utilizadas con seguridad en
cualquier otro elemento, sin necesidad de ser <a>.

Pseudoclase Descripción
:hover Aplica estilos cuando pasamos el ratón sobre un elemento.

:active Aplica estilos cuando estamos pulsando sobre el elemento.

La primera de ellas, :hover, es muy útil e interesante, ya que permite aplicar estilos a un elemento justo
cuando el usuario está pasando el ratón sobre él. Es una de las pseudoclases más utilizadas:
/* Usuario mueve el ratón sobre un enlace */

a:hover {

background-color: cyan;

padding: 2px

/* Usuario mueve el ratón sobre un div y resalta todos los enlaces que contiene */

div:hover a {

background-color: steelblue;

color: white;

Obsérvese que podemos realizar acciones un poco más específicas, como el segundo ejemplo anterior,
donde al movernos sobre un elemento div (div:hover), aplicaremos los estilos a los enlaces (a) que están
dentro del mencionado div.

Por otro lado, la segunda pseudoclase, :active, permite resaltar los elementos que se encuentran activos,
donde el usuario está pulsando de forma activa con el ratón:
a:active {

border: 2px solid #FF0000;

padding: 2px

Nota: Aunque las pseudoclases anteriores se inventaron para interactuar con un ratón en un sistema de
escritorio, pueden funcionar en dispositivos táctiles. Aún así, ten en cuenta que, por ejemplo, el :hover
no tiene mucho sentido en dispositivos móviles, ya que, aunque podría hacerlo, un usuario no navega
por móvil arrastrando el dedo por la pantalla.

Pseudoclases de interacción
Existen pseudoclases orientadas principalmente a los campos de formulario de páginas webs y la
interacción del usuario con ellos, veamos otro par interesante:

Pseudoclase Descripción

:focus Aplica estilos cuando el elemento tiene el foco.

:checked Aplica estilos cuando la casilla está seleccionada.

Cuando estamos escribiendo en un campo de texto de un formulario de una página web, generalmente
pulsamos TAB para cambiar al siguiente campo y SHIFT+TAB para volver al anterior. Cuando estamos
posicionados en un campo se dice que ese campo tiene el foco, mientras que al pulsar TAB y saltar al
siguiente, decimos que pierde el foco.

El comportamiento de «ganar el foco» puede gestionarse mediante la pseudoclase :focus:


/* El campo ha ganado el foco */

input:focus {

border: 2px dotted #444

Nota: Aunque estas pseudoclases suelen utilizarse con elementos de formularios como <input>,
también pueden utilizarse con otros elementos, como por ejemplo los enlaces <a>. Esta es una excelente
oportunidad para personalizar el estilo de los campos de texto de un formulario (<input> y <textarea>)
mientras el usuario escribe y se mueve por ellos.

Por otro lado, la pseudoclase :checked permite aplicar el estilo especificado a los elementos <input>
(casillas de verificación o botones de radio) u <option> (la opción seleccionada de un <select>).
Por ejemplo, se podría utilizar el siguiente fragmento de código:

input:checked + span {

color: green;

Este ejemplo añade el selector hermano + para darle formato al <span> que contiene el texto y se
encuentra colocado a continuación de la casilla <input>. De esta forma, los textos que hayan sido
seleccionados, se mostrarán en verde.

Pseudoclases de activación
Por norma general, los elementos de un formulario HTML están siempre activados, aunque se pueden
desactivar añadiendo el atributo disabled (es un atributo booleano, no lleva valor) al elemento HTML
en cuestión. Esto es una práctica muy utilizada para impedir al usuario escribir en cierta parte de un
formulario porque, por ejemplo, no es aplicable.

Existen varias pseudoclases para detectar si un campo de un formulario está activado o desactivado:

Pseudoclase Descripción

:enabled Aplica estilos cuando el campo del formulario está activado.

:disabled Aplica estilos cuando el campo del formulario está desactivado.

:read-only Aplica estilos cuando el campo es de sólo lectura.

:read-write Aplica estilos cuando el campo es editable por el usuario.

Utilizando las dos primeras pseudoclases, bastante autoexplicativas por si solas, podemos seleccionar
elementos que se encuentren activados (comportamiento por defecto) o desactivados:
/* Muestra en fondo blanco las casillas que permiten escribir */

input:enabled {

background-color: white;

/* Muestra en fondo gris las casillas que no permiten escribir */

input:disabled {

background-color: grey;

Por otro lado, las pseudoclases read-only y read-write nos permiten seleccionar y diferenciar
elementos que se encuentran en modo de solo lectura (tienen especificado el atributo readonly en el
HTML) o no:
input:read-only {

background-color: darkred;

color: white

}
En el ejemplo anterior, la pseudoclase :read-only le da estilo a aquellos campos <input> de un
formulario que están marcados con el atributo de sólo lectura readonly. La diferencia entre un campo
con atributo disabled y un campo con atributo readonly es que la información del campo con readonly
se enviará a través del formulario, mientras que la del campo con disabled no se enviará. Aún así,
ambas no permiten modificar el valor.

Nota: Ten en cuenta que :read-only aplicará los estilos a todos los elementos HTML que no puedan ser
modificados por el usuario.

Por otro lado, la pseudoclase :read-write es muy útil para dar estilos a todos aquellos elementos que
son editables por el usuario, sean campos de texto <input> o <textarea>.
input:read-write {

background-color: green;

color: white

Nota: La pseudoclase read-write da estilo también a elementos HTML que contengan el atributo
contenteditable, como por ejemplo un párrafo editable por el usuario con dicho atributo.

Pseudoclases de validación

En HTML5 es posible dotar de capacidades de validación a los campos de un formulario, pudiendo


interactuar desde Javascript o incluso desde CSS. Con estas validaciones podemos asegurarnos de que el
usuario escribe en un campo de un formulario el valor esperado que debería. Existen algunas
pseudoclases útiles para las validaciones, como por ejemplo las siguientes:

Pseudoclase ¿Cuándo aplica estilos?

:required Cuando el campo es obligatorio, o sea, tiene el atributo required.

:optional Cuando el campo es opcional (por defecto, todos los campos).

:invalid Cuando los campos no cumplen la validación HTML5.

:valid Cuando los campos cumplen la validación HTML5.

:out-of-range Cuando los campos numéricos están fuera del rango.


:in-range Cuando los campos numéricos están dentro del rango.

En un formulario HTML es posible establecer un campo obligatorio que será necesario rellenar para
enviar el formulario. Por ejemplo, el DNI de una persona que va a matricularse en un curso, o el nombre
de usuario de alta en una plataforma web para identificarse. Campos que son absolutamente necesarios.

Para hacer obligatorios dichos campos, tenemos que indicar en el HTML el atributo required, al cuál
será posible darle estilo mediante la pseudoclase :required:

input:required {

border: 2px solid blue;

Por otra parte, los campos opcionales (no obligatorios, sin el atributo required) pueden seleccionarse
con la pseudoclase :optional:
input:optional {

border: 2px solid grey;

Las validaciones en formularios HTML siempre han sido un proceso tedioso, hasta la llegada de
HTML5. HTML5 brinda un excelente soporte de validaciones desde el lado del cliente, pudiendo
comprobar si los datos especificados son correctos o no antes de realizar las validaciones en el lado del
servidor, y evitando la latencia de enviar la información al servidor y recibirla de vuelta.

Ojo: Ten en cuenta que la validación de cliente es apropiada solo para reducir la latencia de
envío/recepción al servidor, pero nunca como estrategia para evitar problemas de seguridad o similares,
para la cuál se debe tener validación en el servidor siempre. Las validaciones utilizadas en frontend, es
posible falsearlas o saltárselas.

Imaginemos un campo de entrada en el que queremos obtener la edad del usuario. Nuestra intención es
que solo se puedan introducir números. Para ello hacemos uso de la expresión regular [0-9]+, que
significa «una o más cifras del 0 al 9»:
<input type="text" name="age" pattern="[0-9]+" />
Sin embargo, el atributo pattern permite expresiones regulares realmente complejas, como por ejemplo,
una expresión regular para validar el formato de un DNI, ya sea en el formato nacional de España
(12345678L) o en formato NIE (X1234567L), aceptando guiones si se indican:
<input type="text" name="dni"

pattern="(([X-Z]{1})([-]?)(\d{7})([-]?)([A-Z]{1}))|((\d{8})([-]?)([A-Z]{1}))" />

Se pueden aplicar ciertos estilos dependiendo de si se cumple o no el patrón de validación, utilizando las
siguientes pseudoclases:
input:invalid {

background-color: darkred;

color: white;

input:valid {

background-color: green;

color: white;

Sin embargo, en la validación numérica que vimos anteriormente, un usuario podría escribir 500, que es
una edad imposible, porque en el patrón de validación indicamos «una o más cifras del 0 al 9». Lo ideal
sería establecer un rango, algo que se suele hacer muy a menudo si tenemos campos numéricos de
formulario:
<input type="number" name="age" min="18" max="100" />

Este campo permite al usuario especificar su edad, utilizando los atributos de validación min y max,
que sólo permiten valores entre 18 y 100 años. Los valores fuera de este rango, no serán válidos.

De la misma forma que antes, es posible aplicar estilos para los valores fuera de rango, como dentro de
rango:
input:out-of-range {

background-color: darkred;

color: white;

input:in-range {

background-color: green;

color: white;

}
Pseudoclases de negación

Existe una pseudoclase muy útil, denominada pseudoclase de negación. Permite seleccionar todos los
elementos que no cumplan los selectores indicados entre paréntesis.

Veamos un ejemplo:
p:not(.general) {

border: 1px solid #DDD;

padding: 8px;

background: #FFF;

Este pequeño fragmento de código nos indica que todos los párrafos (elementos <p>) que no
pertenezcan a la clase general, se les aplique el estilo especificado.

Consejo: Las reglas de negación pueden ser complejas, ineficientes y poco escalables. Intenta utilizarlas
sólo en los casos que sea absolutamente necesario.

Otras pseudoclases

Para finalizar el apartado de pseudoclases, quiero mencionar algunas que no encajan en los apartados
anteriores, pero que pueden ser muy útiles en algunos casos:

Pseudoclase Significado

:lang(es) Aplica estilo a los elementos con el atributo lang="es".

:target Aplica estilo al elemento que coincida con el ancla de la URL.

:root Aplica estilo al elemento raíz (padre) del documento.

:default Experimental. Aplica estilo al elemento por defecto. Útil en formularios.

:dir(A) Experimental. Aplica estilo al elemento que coincide con la dirección ltr o rtl.

:indeterminate Experimental. Aplica estilo a la casilla checkbox o al elemento <progress> sin definir.
:fullscreen Experimental. Aplica estilo si la página está en el modo de pantalla completa.

:scope Experimental. Aplica estilo a los elementos en el ámbito indicado.

:any(A) Experimental. Aplica estilo si coincide con algún elemento indicado en A.

Otras pseudoclases como :first, :left, :right o :blank las mencionamos en el capítulo de medios
paginados.

Existen varias pseudoclases que permiten hacer referencias a los elementos del documento HTML
según su posición y estructura de los elementos hijos. A continuación muestro un pequeño resumen
de estas pseudoclases:

Pseudoclase Descripción

:first-child Primer elemento hijo (de cualquier tipo).

:last-child Último elemento hijo (de cualquier tipo).

:nth-child(n) N-elemento hijo (de cualquier tipo).

:nth-last-child(n) N-elemento hijo (de cualquier tipo) partiendo desde el final.

Para ello, volvamos a utilizar una estructura en forma de árbol para ver cómodamente la ubicación de
cada uno de los elementos.

Las dos primeras pseudoclases, :first-child y :last-child hacen referencia a los primeros y últimos
elementos (al mismo nivel) respectivamente.
strong:first-child {

background-color:cyan;

strong:last-child {

background-color:green;

}
Sin embargo, si no queremos quedarnos en los primeros o últimos elementos y necesitamos más
potencia para elegir, podemos hacer uso de la pseudoclase :nth-child(A), que permite especificar el
elemento deseado, simplemente estableciendo su número en el parámetro A:

Número Equivalente a la pseudoclase Significado

strong:nth-child(1) strong:first-child {} Primer elemento hijo, que además es un <strong>

strong:nth-child(2) Segundo elemento hijo, que además es un <strong>

strong:nth-child(3) Tercer elemento hijo, que además es un <strong>

strong:nth-child(n) Todos los elementos hijos que son <strong>

strong:nth-child(2n) Todos los elementos hijos pares <strong>

strong:nth-child(2n-1) Todos los elementos hijos impares <strong>

A continuación puedes comprobar los valores de la tabla anterior de un modo más visual y práctico,
estableciendo en el campo de texto valores como n, n+2, 2n, 2n-1 (o similares) y observando los
resultados.

:nth-child()

Veamos además un ejemplo gráfico:


Como se aprecia en el ejemplo, en el caso :nth-child(2) se puede ver como el segundo elemento lo
ocupa un elemento span, por lo que sólo se selecciona el elemento strong del segundo caso, donde si
existe.
Elementos del mismo tipo

En los casos anteriores, seleccionamos elementos independientemente de que elemento sea.


Simplemente, hacemos caso a la posición donde está ubicado. Si queremos hacer referencia sólo a
elementos del mismo tipo, utilizaremos los selectores siguientes, análogos a los anteriores, pero
haciendo referencia sólo a elementos del mismo tipo:

Pseudoclase Descripción

:first-of-type Primer elemento hijo (de su mismo tipo).

:last-of-type Último elemento hijo (de su mismo tipo).

:nth-of-type(n) N-elemento hijo (de su mismo tipo).

:nth-last-of-type(n) N-elemento hijo (de su mismo tipo) partiendo desde el final.

Las pseudoclases :first-of-type y :last-of-type son las equivalentes a :first-child y :last-child pero sólo
teniendo en cuenta elementos del mismo tipo. Por otro lado, la pseudoclase :nth-of-type(A) es la
equivalente a :nth-child(A) y :nth-last-of-type(A) es la equivalente a :nth-last-child(A). Veamos un
ejemplo sobre el ejercicio anterior:

En este ejemplo, se puede ver como :nth-of-type(2) selecciona el segundo elemento strong en ambos
casos, a pesar de que en el primero ocupa la tercera posición. En este caso se selecciona porque es el
segundo elemento de su mismo tipo (<strong>).

Por otro lado, :nth-last-of-type(A) hace una selección de forma inversa, empezando por el último
elemento.

Hijos únicos

Existen también varias pseudoclases para la gestión de hijos únicos. Son las siguientes:

Pseudoclase Descripción

:only-child Elemento que es hijo único (de cualquier tipo).

:only-of-type Elemento que es hijo único (de su mismo tipo).


:empty Elemento vacío (sin hijos, ni texto).

La propiedad :only-child nos proporciona un método para aplicar estilo a aquellos elementos que sean
el único hijo de su elemento padre. Además, como ha ocurrido anteriormente, también existe la
pseudoclase :only-of-type que es equivalente al anterior pero sólo para elementos del mismo tipo, es
decir, que puede ser que no sea el único elemento hijo, pero sí el único de su tipo.

Muy relacionada está también la pseudoclase :empty, que permite seleccionar los elementos que estén
vacíos. Ojo con esto, ya que un elemento que contenga comentarios HTML <!-- --> la pseudoclase
:empty lo detectará como vacío, pero si contiene espacios en blanco, no.

Al igual que las pseudoclases, los pseudoelementos son otra de las características de CSS que permiten
hacer referencias a «comportamientos virtuales no tangibles», o lo que es lo mismo, se le puede dar
estilo a elementos que no existen realmente en el HTML, y que se pueden generar desde CSS.

Recordemos la sintaxis de los pseudoelementos, que está precedida de dos puntos dobles (::) para
diferenciarlos de las pseudoclases, las cuales sólo tienen dos puntos (:). No obstante, este cambio surgió
posteriormente, por lo que aún hoy en día es frecuente ver fragmentos de código con pseudoelementos
con la sintaxis de pseudoclase con un solo par de puntos :.

Generación de contenido

Dentro de la categoría de los pseudoelementos CSS, como punto central, se encuentra la propiedad
content. Esta propiedad se utiliza en selectores que incluyen los pseudoelementos ::before o ::after,
para indicar que vamos a crear contenido antes o después del elemento en cuestión:

Propiedad/Pseudoelemento Descripción

content Propiedad para generar contenido. Sólo usable en ::before o ::after.

::before Aplica los estilos antes del elemento indicado.

::after Aplica los estilos después del elemento indicado.


La propiedad content admite parámetros de diverso tipo, incluso concatenando información mediante espacios. Podemos utilizar tres tipos de
contenido:

Valor Descripción Ejemplo

"string" Añade el contenido de texto indicado. content: "Contenido:";

attr(atributo) Añade el valor del atributo HTML indicado. content: attr(href);

url(URL) Añade la imagen indicada en la URL. content: url([Link]);

Por otro lado, los pseudoelementos ::before y ::after permiten hacer referencia a «justo antes del
elemento» y «justo después del elemento», respectivamente. Así, se podría generar información
(usualmente con fines decorativos) que no existe en el HTML, pero que por circunstancias de diseño
sería apropiado colocar:
q::before {

content: "«";

color: #888;

q::before {

content: "»";

color: #888;

Los ejemplos anteriores insertan el carácter « antes de las citas indicadas con el elemento HTML <q> y
el carácter » al finalizar la misma, ambas de color gris.

Atributos HTML

Es interesante recalcar la utilidad de la expresión attr(), que en lugar de generar el contenido textual que
le indiquemos, permite recuperar esa información del valor del atributo HTML especificado. Veamos
un ejemplo para clarificarlo, concatenándolo con texto:
a::after {

content: " ( " attr(href) " )";

}
Este pequeño ejemplo muestra a continuación de todos los enlaces la URL literalmente, dentro de dos
paréntesis. Esto puede ser realmente útil en una página de estilos que se aplica a una página en el
momento de imprimir, en los cuales se pierde la información del enlace al no ser un medio interactivo.

Truco: También se puede utilizar la expresión url() para añadir una imagen al contenido generado, tal y
como lo hacemos en la propiedad background, por ejemplo.

Primera letra y primera línea

También existen pseudoelementos con los que podemos hacer referencia a la primera letra de un texto.
Para ello utilizamos el pseudoelemento ::first-letter, así como el pseudoelemento ::first-line si
queremos hacer referencia a la primera línea de un texto. De esta forma, podemos dar estilo a esas
secciones concretas del texto:

Pseudoelemento Descripción

::first-letter Aplica los estilos en la primera letra del texto.

::first-line Aplica los estilos en la primera línea del texto.

Veamos un ejemplo en acción sobre un párrafo de texto:

p{

color: #333;

font-family: Verdana, sans-serif;

font-size: 16px;

p::first-letter {

color: black;

font-family: 'Times New Roman', serif;

font-size: 42px;

p::first-line {

color: #999;

}
Esto puede darnos la posibilidad de dar formato a un texto con ciertas propiedades, como cuentos
clásicos:

Signos de las listas (markers)

Existe también un pseudoelemento para hacer referencias a los signos o marcas de la listas (<ol> o
<ul>), en el caso de que queramos que tengan, por ejemplo, un color diferente al del texto de la lista.
Se aplican a los elementos <li> de los ítems de una lista. Veamos un ejemplo:

ul ::marker {

color: green;

Esto mostraría el texto de la lista con el color habitual que tenga (por ejemplo, negro), pero los signos
que preceden a cada ítem de la lista, aparecerían en color verde. Hay que tener cuidado, puesto que el
soporte de esta característica aún no es muy bueno.

Otros pseudoelementos

Existen otros pseudoelementos quizás menos conocidos:

Pseudoelemento Descripción Soporte

::backdrop Aplica estilos al fondo exterior de la ventana de diálogo mostrada.

::input-placeholder Aplica estilos a los textos de sugerencia de los campos de entrada. Soporte

::selection Aplica estilos al fragmento de texto seleccionado por el usuario. Soporte


Prefijos

Algunas de las propiedades que veremos no están definidas por completo, sólo son borradores o pueden
variar en la especificación definitiva, por lo que los navegadores las implementan utilizando una serie de
vendor prefixes (prefijos por navegador), que facilitan la segmentación de funcionalidades.

De esta forma, podemos utilizar varios prefijos para asegurarnos que aunque dichas funcionalidades
tengan un comportamiento o sintaxis diferente en cada navegador, podemos hacer referencia a cada una
de ellas por separado:
div {

transform: ... /* Navegadores que implementan especificación oficial */

-webkit-transform: ... /* Versiones antiguas de Chrome (Motor WebKit) */

-moz-transform: ... /* Versiones antiguas de Firefox (Motor Gecko) */

-ms-transform: ... /* Versiones antiguas de IE (Motor Trident) */

-o-transform: ... /* Versiones antiguas de Opera (Motor Presto) */

En el ejemplo anterior, la propiedad transform se refiere a los navegadores que tengan implementada la
especificación definitiva por completo e ignorará el resto de propiedades. Por otro lado, otro navegador
(o el mismo en una versión más antigua) puede tener implementada una versión anterior a la definitiva,
por lo que hará caso a las propiedades con un prefijo concreto.

Debido al ritmo y la rápida velocidad de Internet en estas cuestiones, es muy complicado obtener una
lista de funcionalidades implementadas en cada navegador, algo que puede variar incluso en cuestión de
semanas. Aconsejo utilizar la página Can I Use, una web colaborativa para saber el estado actual, previo
e incluso futuro de las propiedades CSS o elementos HTML en cada navegador.
En esta página se puede buscar, a través de un buscador y de forma rápida y cómoda, el estado de ciertas
características por parte de las diferentes versiones de los navegadores.

Actualmente, los vendor prefixes están en proceso de desaparecer. Las principales compañías de
navegadores han optado por favorecer el uso de flags en el navegador del usuario para activar o
desactivar opciones experimentales o crear especificaciones más pequeñas y breves que puedan ser
estables mucho más rápido. Por esta razón, se aconseja utilizar vendor prefixes solo cuando necesitas
soporte específico en navegadores muy antiguos.

En el caso de querer utilizar vendor prefixes*, recomiendo encarecidamente utilizar sistemas como
autoprefixer (el más popular, que forma parte de PostCSS) o prefix-free que añaden de forma
automática y transparente los prefijos, basándose en información de herramientas como Can I Use.
Busca extensiones en el editor que utilices o la opción para activarlas, ya que te ahorrará mucho tiempo
y te permitirá tener un código más legible y modular al no tener que repetir código.

En CSS aparecen uno de los aspectos más interesantes de la web interactiva: las transiciones. En
versiones anteriores de CSS sólo se podían utilizar ciertas funcionalidades interactivas con pseudoclases
como :hover o :focus. Sin embargo, dichas transiciones ocurrían de golpe, pasando de un estado inicial
a otro final. Mediante las transiciones, tenemos a nuestra disposición una gran flexibilidad que nos
permitirá dotar de atractivos y elegantes efectos de transición que multiplicarán por mil las posibilidades
de nuestros diseños.

Las transiciones se basan en un principio muy básico, conseguir un efecto suavizado entre un estado
inicial y un estado final. Las propiedades relacionadas que existen son las siguientes:
Propiedades Valor

transition-property all | none | propiedad css

transition-duration 0|

transition-timing-function ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(A, B, C, D)

transition-delay 0|

En primer lugar, la propiedad transition-property se utiliza para especificar la propiedad a la que que
afectará la transición. Podemos especificar la propiedad concreta (width o color, por ejemplo) o
simplemente especificar all para que se aplique a todos los elementos con los que se encuentre. Por otro
lado, none hace que no se aplique ninguna transición.

Nota: Debes saber que no todos los elementos permiten animación debido a su complejidad. Por
ejemplo, los background-image de gradientes no son animables actualmente.

Con la propiedad transition-duration especificaremos la duración de la transición, desde el inicio de


la transición, hasta su finalización. Se recomienda siempre comenzar con valores cortos, para que las
transiciones sean rápidas y elegantes.

Si establecemos una duración demasiado grande, el navegador realizará la transición con detención
intermitentes, lo que hará que la transición vaya a golpes. Además, transiciones muy largas pueden
resultar molestas a muchos usuarios.

Función de tiempo

La propiedad transition-timing-function permite indicar el ritmo de la transición que queremos


conseguir. Cuando estamos aprendiendo CSS, recomiendo utilizar linear, que realiza una transición a
un ritmo constante. Sin embargo, podemos utilizar otros valores para conseguir que el ritmo sea
diferente al inicio y/o al final de la transición.

Los valores que puede tomar la propiedad son los siguientes:

Valor Inicio Transcurso Final Equivalente en cubic-beizer

ease Lento Rápido Lento (0.25, 0.1, 0.25, 1)

linear Normal Normal Normal (0, 0, 1, 1)


ease-in Lento Normal Normal (0.42, 0, 1, 1)

ease-out Normal Normal Lento (0, 0, 0.58, 1)

ease-in-out Lento Normal Lento (0.42, 0, 0.58, 1)

cubic-bezier(A, B, C, D) - - - Transición personalizada

Una función de tiempo linear siempre es constante, mientras que ease comienza suavemente, continua
de forma más rápida y termina suavemente de nuevo. Ease-in y ease-out son variaciones que van más
lento al principio o al final, y ease-in-out una mezcla de las dos.

Cubic-Bezier()

La función de tiempo cubic-bezier() es una función personalizada, donde podemos darle unos valores
concretos depediendo de la velocidad que queramos que tenga la transición. En la última columna de la
tabla anterior podemos ver los valores equivalentes a cada una de las palabras clave mencionadas. En
principio, el formato de la función es cubic-bezier(A, B, C, D), donde:

Parámetro Valor Descripción Pertenece a

A X1 Eje X del primer punto que orienta la curva bezier. P1

B Y1 Eje Y del primer punto que orienta la curva bezier. P1

C X2 Eje X del segundo punto que orienta la curva bezier. P2

D Y2 Eje Y del segundo punto que orienta la curva bezier. P2


También puedes utilizar la página Cubic Bezier, donde puedes ver de forma interactiva la velocidad de
las transiciones dependiendo de los parámetros utilizados.

Por último, la propiedad transition-delay nos ofrece la posibilidad de retrasar el inicio de la


transición los segundos especificados.

Veamos un pequeño ejemplo de todo ello:


a{

background: #DDD;

color: #222;

padding: 2px;

border: 1px solid #AAA;

a:hover {

background: #FFF;

color: #666;

padding: 8px 14px;

border: 1px solid #888;

transition-property: all;

transition-duration: 0.2s;

transition-timing-function: ease-in;

}
Truco: Si nos fijamos bien, este estilo se aplica sólo al mover el ratón sobre el enlace (transición de
entrada). Sin embargo, si movemos el ratón fuera del enlace, no se produce transición sino que realiza
el cambio de forma brusca. Si movemos las propiedades de transición al primer bloque, se aplicarán
tanto en las transiciones de entrada como en las de salida.

Atajo: Transiciones

Como siempre, podemos resumir todas estas operaciones en una propiedad de atajo denominada
transition. Los valores del ejemplo superior, se podrían escribir como se puede ver a continuación (si
no necesitas algún valor, se puede omitir):
div {

/* transition: <property> <duration> <timing-function> <delay> */

transition: all 0.2s ease-in;

Una vez conocemos las transiciones CSS, es muy fácil adaptarnos al concepto de animaciones de CSS,
el cual amplia el concepto de transiciones convirtiéndolo en algo mucho más flexible y potente.

Las transiciones son una manera de suavizar un cambio de un estado inicial a un estado final. La idea de
las animaciones CSS parte del mismo concepto, permitiendo añadir más estados, pudiendo realizar
cambios desde un estado inicial, a un estado posterior, a otro estado posterior, y así sucesivamente.
Además, esto será posible de forma automática, sin que el usuario tenga que realizar una acción
concreta.

El primer paso para crear animaciones es tener dos cosas claras. Por un lado, utilizaremos la regla
@keyframes, que incluye los fotogramas de la animación. Por otro lado, tendremos que utilizar las
propiedades de las animaciones, que definen el comportamiento de la misma.

Propiedades de animación CSS

Para definir dicho comportamiento necesitamos conocer las siguientes propiedades, que son una
ampliación de las transiciones CSS:

Propiedades Valor

animation-name none | nombre

animation-duration 0|

animation-timing-function ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(A, B, C, D)


animation-delay 0|

animation-iteration-count 1 | infinite |

animation-direction normal | reverse | alternate | alternate-reverse

animation-fill-mode none | forwards | backwards | both

animation-play-state running | paused

La propiedad animation-name permite especificar el nombre del fotograma a utilizar, mientras que las
propiedades animation-duration, animation-timing-function y animation-delay funcionan
exactamente igual que en el tema anterior de transiciones.

La propiedad animation-iteration-count permite indicar el número de veces que se repite la animación,


pudiendo establecer un número concreto de repeticiones o indicando infinite para que se repita
continuamente. Por otra parte, especificando un valor en animation-direction conseguiremos indicar el
orden en el que se reproducirán los fotogramas, pudiendo escoger un valor de los siguientes:

Valor Significado

normal Los fotogramas se reproducen desde el principio al final.

reverse Los fotogramas se reproducen desde el final al principio.

alternate En iteraciones par, de forma normal. Impares, a la inversa.

alternate-reverse En iteraciones impares, de forma normal. Pares, normal.

Por defecto, cuando se termina una animación que se ha indicado que se reproduzca sólo una vez, la
animación vuelve a su estado inicial (primer fotograma). Mediante la propiedad animation-fill-mode
podemos indicar que debe mostrar la animación cuando ha finalizado y ya no se está reproduciendo; si
mostrar el estado inicial (backwards), el estado final (forwards) o una combinación de ambas (both).

Por último, la propiedad animation-play-state nos permite establecer la animación a estado de


reproducción (running) o pausarla (paused).

Atajo: Animaciones
Nuevamente, CSS ofrece la posibilidad de resumir todas estas propiedades en una sola, para hacer
nuestras hojas de estilos más específicas. El orden de la propiedad de atajo sería el siguiente:
div {

/* animation: <name> <duration> <timing-function> <delay>

<iteration-count> <direction> <fill-mode> <play-state> */

animation: changeColor 5s linear 0.5s 4 normal forwards running;

Consejo: Mucho cuidado al indicar los segundos en las propiedades de duración. Al ser una unidad
diferente a las que solemos manejar (px, em, etc...) hay que especificar siempre la s, aunque sea un
valor igual a 0.

Fotogramas (keyframes)

Ya sabemos como indicar a ciertas etiquetas HTML que reproduzcan una animación, con ciertas
propiedades. Sin embargo, nos falta la parte más importante: definir los fotogramas de dicha animación.
Para ello utilizaremos la regla @keyframes, la cuál es muy sencilla de utilizar y se basa en el siguiente
esquema:

En primer lugar elegiremos un nombre para la animación (el cuál utilizamos en el apartado anterior, para hacer referencia a la animación, ya
que podemos tener varias en una misma página), mientras que podremos utilizar varios selectores para definir el transcurso de los
fotogramas en la animación.

Veamos algunos ejemplos:


@keyframes changeColor {

from { background: red; } /* Primer fotograma */

to { background: green; } /* Último fotograma */


}

.anim {

background: grey;

color: #FFF;

width: 150px;

height: 150px;

animation: changeColor 2s ease 0 infinite; /* Relaciona con @keyframes */

En este ejemplo nombrado changeColor, partimos de un primer fotograma en el que el elemento en


cuestión será de color de fondo rojo. Si observamos el último fotograma, le ordenamos que termine con
el color de fondo verde. Así pues, la regla @keyframes se inventará la animación intermedia para
conseguir que el elemento cambie de color.

Los selectores from y to son realmente sinónimos de 0% y 100%, así que los modificaremos y de esta
forma podremos ir añadiendo nuevos fotogramas intermedios. Vamos a modificar el ejemplo anterior
añadiendo un fotograma intermedio e indentando, ahora sí, correctamente el código:
@keyframes changeColor {

0% {

background: red; /* Primer fotograma */

50% {

background: yellow; /* Segundo fotograma */

width: 400px;

100% {

background: green; /* Último fotograma */

Las transformaciones es uno de los elementos más interesantes que se introducen en CSS3 para
convertir el lenguaje de hojas de estilo en un sistema capaz de realizar todo tipo de efectos visuales,
incluido 2D y 3D. Las propiedades principales para realizar transformaciones son las siguientes:

Propiedades Formato Significado

transform función1, función2, ... Aplica una o varias funciones de transformación sobre un elemento.
transform-origin Cambia el punto de origen del elemento en una transformación.

transform-style flat | preserve-3d Modifica el tratamiento de los elementos hijos.

Comencemos por la propiedad transform, mediante la cual podemos indicar una o varias
transformaciones para realizar sobre un elemento, ya sean 2D (sobre dos ejes) o 3D (sobre tres ejes).

Funciones 2D

Existen múltiples propiedades CSS que ofrecen diferentes funcionalidades de transformación en dos
dimensiones, que veremos a continuación:

Translaciones

Las funciones de translación son aquellas que realizan una transformación en la que mueven un
elemento de un lugar a otro. Si especificamos un valor positivo en el eje X (horizontal), lo moveremos
hacia la derecha, y si especificamos un valor negativo, lo moveremos hacia la izquierda. Lo mismo con
el eje Y (vertical):

Funciones Significado

translateX(x) Traslada el elemento una distancia de x horizontalmente.

translateY(y) Traslada el elemento una distancia de y verticalmente.

translate(x, y) Propiedad de atajo de las dos anteriores.

Por ejemplo, transform: translate(20px, -30px) traslada el elemento 20 píxeles a la derecha y 30


píxeles hacia arriba, que es equivalente a utilizar transform: translateX(20px) translateY(-30px).

Escalado

Las funciones de escalado realizan una transformación en la que aumentan o reducen el tamaño de un
elemento, basándose en el parámetro indicado, que no es más que un factor de escala:
Funciones Significado

scaleX(fx) Reescala el elemento a un nuevo tamaño con un factor fx horizontal.

scaleY(fy) Reescala el elemento a un nuevo tamaño con un factor fy vertical.

scale(fx, fy) Propiedad de atajo de las dos anteriores.

En este ejemplo, transform: scale(2, 2) realiza una transformación de escalado del elemento,
ampliándolo al doble de su tamaño original. Si utilizamos scale() con dos parámetros iguales, estamos
manteniendo la proporción del elemento, pero si utilizamos diferentes valores, acabaría deformándose.

Rotaciones

Las funciones de rotación simplemente giran el elemento el número de grados indicado:

Funciones Significado

rotateX(xdeg) Establece una rotación 2D en xdeg grados sólo para el eje horizontal X.

rotateY(ydeg) Establece una rotación 2D en ydeg grados sólo para el eje vertical Y.

rotate(deg) Establece una rotación 2D en deg grados sobre si mismo.

Con transform: rotate(5deg) realizamos una rotación de 5 grados del elemento sobre si mismo.
Utilizando rotateX() y rotateY() podemos hacer lo mismo respecto al eje X o el eje Y respectivamente.

Deformaciones

Por último, las funciones de deformación establecen un ángulo para torcer, tumbar o inclinar un
elemento en 2D:

Funciones Significado

skewX(xdeg) Establece un ángulo de xdeg para una deformación 2D respecto al eje X

skewY(ydeg) Establece un ángulo de ydeg para una deformación 2D respecto al eje Y


Aunque la función skew() existe, no debería ser utilizada, ya que está marcada como obsoleta y serán
retiradas de los navegadores en el futuro. En su lugar deberían utilizarse skewX() o skewY().

Funciones 3D

Sin embargo, esto no es todo. A las funciones anteriores, también podemos añadir las funciones
equivalentes de CSS para hacer uso del eje Z, o lo que es lo mismo, las tres dimensiones o 3D. Basta
con utilizar el eje Z o las funciones específicas de 3D para poner estas animaciones en práctica.

Recordar siempre que el eje X es el eje horizontal, el eje Y es el eje vertical y el eje Z es el eje de
profundidad.

Las propiedades de transformación que completarían la colección de transformaciones 2D que vimos


anteriormente, son las siguientes:

Funciones Significado

translateZ(z) Traslada el elemento una distancia de z en el eje de profundidad.

translate3d(x, y, z) Establece una translación 3D, donde aplica los parámetros de a cada eje.
scaleZ(fz) Reescala el elemento a un nuevo tamaño con factor fz de profundidad.

scale3d(fx, fy, fz) Establece un escalado 3D, donde aplica los factores a cada eje.

rotateZ(zdeg) Establece una rotación 2D en zdeg grados sólo para el eje de profundidad Z.

rotate3d(x, y, z, deg) Establece una rotación 3D, aplicando un vector [x, y, z] y el ángulo en deg.

perspective(n) Establece una perspectiva 3D de n

matrix3d(n, n, ...) Establece una matriz de transformación 3D (16 valores)

Veamos un ejemplo con rotate3d():


@keyframes rotation {

0% {

transform: rotate3d(1, 0, 0, 5deg);

100% {

transform: rotate3d(1, 1, 0, 220deg);

.anim {

background: #000;

color: #FFF;

width: 100px;

animation: rotation 2s ease-in-out 0 infinite alternate none running;

Finalmente, se puede utilizar la función matrix() y matrix3d() para obtener transformaciones


personalizadas más complejas y específicas. Tienes más información sobre ellas en el artículo
Understanding the CSS Transforms Matrix de los desarrolladores del navegador Opera.

Transformaciones múltiples
Recuerda que si estableces varias propiedades transform en el mismo elemento con diferentes
funciones de transformación, la segunda propiedad de transformación sobreescribirá a la anterior, como
lo haría cualquier propiedad de CSS:
div {

transform: rotate(5deg);

transform: scale(2,2); /* Sobreescribe la anterior */

Para evitar este comportamiento, una forma sencilla se basa en emplear múltiples transformaciones
separándolas mediante un espacio. En el siguiente ejemplo, aplicamos una función de rotación, una
función de escalado y una función de traslación de forma simultánea:
div {

transform: rotate(5deg) scale(2,2) translate(20px, 40px);

Si lo que queremos hacer no es posible realizarlo de esta forma, probablemente lo más apropiado sería
guardar los valores en atributos de metadatos como data-tx, data-ty, data-sx, data-sy y data-rz o
similares y manipulándolos desde Javascript.

El soporte de estas propiedades es muy bueno en el ecosistema de navegadores actual, por lo que puede
utilizarse con seguridad:

.anim {

background: grey;

color: #FFF;

width: 150px;

height: 150px;

animation: changeColor 2s ease 0 infinite; /* Relaciona con @keyframes */

Truco: Si tienes fotogramas que van a utilizar los mismos estilos que uno anterior, siempre puedes
separarlos con comas, por ejemplo: 0%, 75% { ... }, que utilizarían dichos estilos al inicio de la
animación y al 75% de la misma.

Encadenar animaciones
Es posible encadenar múltiples animaciones, separando con comas las animaciones individuales y
estableciendo un tiempo de tardo a cada animación posterior:
.animated {

animation:

moveRight 5s linear 0, /* Comienza a los 0s */

lookUp 2.5s linear 5s, /* Comienza a los 5s */

moveLeft 5s linear 7.5s, /* Comienza a los 7.5s (5 + 2.5) */

dissapear 2s linear 9.5s; /* Comienza a los 9.5s (5 + 2.5 + 2) */

En este caso, lo que hemos hecho es aplicar varias animaciones a la vez, pero estableciendo un retardo
(cuarto parámetro) que es la suma de la duración de las animaciones anteriores. De esta forma,
encadenamos una animación con otra.

En la actualidad, el uso de todo tipo de dispositivos móviles se ha disparado, no sólo de «smartphones»,


sino también de tablets, «smartwatchs», lectores de ebooks y múltiples tipos de dispositivos con
capacidad de conexión a Internet.
Cada vez es más frecuente acceder a Internet con diferentes tipos de dispositivos, que a su vez tienen
diferentes pantallas y resoluciones, con distintos tamaños y formas, que hacen que se consuman las
páginas webs de formas diferentes, apareciendo por el camino también diferentes necesidades,
problemas y soluciones.

Por lo tanto, en la actualidad, cuando diseñamos una web, esta debe estar preparada para verse
correctamente en diferentes resoluciones, cosa que, a priori no es sencilla. Antiguamente, se llegó al
punto de preparar una web diferente dependiendo del dispositivo o navegador que utilizaba el usuario,
pero era algo que se terminó descartando, ya que no era práctico.
Por suerte, esos tiempos han quedado atrás, y la máxima que se sigue hoy es diseñar una sola web, que
se adapte visualmente al dispositivo utilizado.
Hoy en día se le denomina Responsive Web Design (o RWD) a los diseños web que tienen la capacidad
de adaptarse al tamaño y formato de la pantalla en la que se visualiza el contenido, respecto a los
diseños tradicionales en los que las páginas web estaban diseñadas sólo para un tamaño o formato
específico, y no tenían esa capacidad de adaptación.

Aunque en principio el concepto de web adaptativa es muy sencillo de comprender, aplicarlo puede ser
todo un quebradero de cabeza si no se conocen bien las bases y se adquiere experiencia. En
[Link] puedes encontrar algunos ejemplos de páginas que utilizan Responsive Web Design para
tener clara la idea.
Conceptos básicos

En el excelente artículo 9 basic principles of responsive web design, de Froont, hay una estupenda
explicación visual de algunos conceptos básicos necesarios para entender correctamente el Responsive
Web Design. Son los siguientes:
El primero de ellos es la diferencia entre diseño responsivo y diseño adaptativo. Como se puede ver en
la imagen a continuación, un diseño responsive responde (valga la rebuznancia) en todo momento a las
dimensiones del dispositivo, mientras que un diseño adaptable es aquel que se adapta, pero no
necesariamente responde en todo momento:

Veremos que esto puede ser la diferencia entre aplicar correctamente conceptos como media queries,
porcentajes y propiedades de ancho máximo y mínimo, que veremos más adelante.

Por otro lado, para trabajar correctamente en diseños responsive hay que tener en cuenta que debemos
trabajar con unidades relativas e intentar evitar las unidades fijas o estáticas, las cuales no responden a la
adaptación de nuestros diseños flexibles:

Otra forma interesante de trabajar esa respuesta de los diseños responsive es utilizar propiedades como
min-width o max-width, donde definimos tamaños mínimos o máximos, para que los elementos de
nuestra página puedan ampliar o reducirse según sea necesario dependiendo de la pantalla del
dispositivo utilizado.
Con estas propiedades podemos crear diseños que aprovechen al máximo toda la pantalla de
dispositivos pequeños (como móviles o tablets), mientras que establecemos unos máximos en pantallas
de dispositivos grandes, para crear unos espacios visuales que hacen que el diseño sea más agradable:
Otro concepto, que a la misma vez es una característica muy atractiva en nuestros diseños responsive es
la de mantener el flujo de los elementos cuando cambian de tamaño y evitar que estos se solapen unos
con otros.
Si estamos habituados a trabajar en diseños más estáticos que no están preparados para móviles, suele
ser duro hacer ese cambio. Sin embargo, una vez lo conseguimos, todo resulta mucho más fácil y
conseguiremos transmitir una buena respuesta y fluidez visual:

Esto último va muy de la mano del sistema habitual de recolocación de elementos que se suele seguir en
los diseños Responsive Design. Como se puede ver en la siguiente imagen, en un diseño responsive se
utilizan ciertos «puntos de control».
Por ejemplo, se suele pensar que en una resolución de escritorio queremos mostrar la información
dentro de una cuadrícula (grid) de 4 ó 5 celdas de ancho, mientras que en la versión de tablet será sólo
de 3 celdas de ancho (el resto se desplazará a la siguiente fila) y en móviles será una sola celda de
ancho, mostrándose el resto de celdas haciendo scroll hacia abajo:
Esta forma de trabajar nos proporciona múltiples ventajas:

■ Es mucho más sencillo mostrar la misma información desde diseños de pantalla grande.

■ Ayuda a evitar la mala práctica de ocultar bloques de información en dispositivos móviles.

■ Incentiva a diseñar siguiendo buenas prácticas para facilitar la creación responsive.


Preparación previa

Antes de comenzar a crear un diseño web preparado para móviles, es importante tener claro ciertos
detalles:

■ A priori, ¿Cuál es tu público objetivo? ¿móvil o escritorio? ¿ambos?

■ Debes conocer las resoluciones más utilizadas por tu público potencial

■ Debes elegir una estrategia acorde a los datos anteriores


En primer lugar, es importante conocer los formatos de pantalla más comunes con los cuales nos
vamos a encontrar. Podemos consultar páginas como MyDevices, la cuál tiene un apartado de
comparación de dispositivos, donde se nos muestra un listado de dispositivos categorizados en
smartphones, tablets u otros dispositivos con las características de cada uno: dimensiones de ancho, alto,
radio de píxels, etc...
Una vez estés familiarizado con estos detalles, es importante conocer el público de tu sitio web.
¿Acceden más usuarios desde móvil o desde escritorio? ¿Predominan las tablets o los móviles? ¿Tu
objetivo es tener más usuarios de móvil o de escritorio?
Consulta con algún sistema de estadísticas como Google Analytics para comprobar que tipo de público
tienes actualmente. También es aconsejable echar un vistazo a información externa como las que nos
proporcionan estadísticas globales anónimas de Global StatCounter, para hacernos una idea de los
atributos más comunes.
Estrategias de diseño

Por último, es aconsejable decidirse por una estrategia de diseño antes de comenzar. Aunque existen
otras estrategias, las dos vertientes principales más populares son las siguientes:
Estrategia Descripción

Mobile first Primero nos enfocamos en dispositivos móviles y luego pensamos en otros.

Desktop first Primero nos enfocamos en dispositivos de escritorio, y luego pensamos en otros.

La estrategia Mobile-first es la que utilizan los diseñadores de sitios webs en las que su público
objetivo es mayoritariamente usuario de móvil. Ejemplos como una web para comprar billetes de
transporte, la web de un juego o aplicación móvil o una web para pedir cita en un restaurante podrían
ser, a priori, una buena elección para utilizar Mobile-first.
Esta estrategia hace que el desarrollo en escritorio sea muy sencillo, ya que se reduce a tener un diseño
de móvil en escritorio e ir añadiendo nuevas secciones o partes para «completar» el diseño en
resoluciones grandes.
Por otro lado, la estrategia Desktop-first suele interesar más a los diseñadores de sitios webs en las que
el público objetivo son usuarios de escritorio. Por ejemplo, una página de una aplicación para PC/Mac o
similares, podría ser una buena opción para la estrategia Desktop-first. En ella, hacemos justo lo
contrario que en la anterior, lo primero que diseñamos es la versión de escritorio, y luego vamos
descargando detalles o recolocando información hasta tener la versión para dispositivos móviles.

Como explicamos en el capítulo anterior, hay ciertos conceptos que hay que tener claros antes de
comenzar con el Responsive Design. En esta sección vamos a ver como llevarlos a la práctica con
código.

Diseño con porcentajes


El primer paso para crear un diseño que se adapte correctamente, es comenzar a familiarizarse con un
tipo de unidades relativas: los porcentajes. Recordemos que los porcentajes son relativos al contenedor
padre, por lo que si especificamos un porcentaje a un elemento, el navegador va a tomar dicho
porcentaje del contenedor.

Nota: Al comenzar, algunos diseñadores tienen una percepción incorrecta de que los porcentajes toman
el tamaño dependiendo de lo que mide la ventana del navegador. Realmente los porcentajes dependen
siempre del tamaño del elemento padre que los contiene. Si queremos basarnos en el tamaño del
navegador, hay que usar unidades de viewport.

Podemos comenzar usando porcentajes con las propiedades width en un ejemplo sencillo. Si
establecemos un ancho de 100% (valor por defecto en elementos de tipo block, no hace falta indicarlo)
a los elementos grises que vemos a continuación (#header, #page y #footer), un 30% al azul (#menu) y
un 70% al gris claro (#content) podríamos obtener este diseño:
El código utilizado sería algo parecido a lo siguiente:
<div id="header"></div>

<div id="page">

<div id="menu"></div>

<div id="content"></div>

</div>

<div id="footer"></div>

Nótese que los elementos #menu y #content se encuentran dentro de #page. Tengan en cuenta que,
estamos utilizando id en este ejemplo, aunque habíamos comentado que lo ideal quizás sería utilizar
clases.
Por su parte, el código CSS tendría esta pinta:
div {

/* Ponemos un alto mínimo, por defecto es 0 */

min-height: 200px;

/* Dibujamos un borde para ver límites */

border: 2px solid black;

#header, #page, #footer {

background: grey;

#menu, #content {

/* Necesario para que los elementos estén en horizontal */

display: inline-block;

#menu {

background: blue;

width: 30%;
}

#content {

background: lightgrey;

width: 70%;

Sin embargo, utilizar porcentajes no nos garantiza un diseño adaptativo de calidad, hay que comprender
otros detalles. El primer problema que encontraremos será que si sumamos el tamaño de los elementos
(70% + 30%) junto a los bordes (2px por cada lado), la suma es superior al 100% del contenedor padre,
por lo que no cabe en su interior y el segundo elemento se desplaza a la zona inferior, descuadrando
todo el diseño. Lo mismo puede ocurrir si intentamos añadir margin o padding. Esto es algo muy
habitual en CSS. Y frustrante al principio.
Hay varias formas de solucionar esto:

■ Eliminar los bordes y reducir los porcentajes hasta que quepan en el 100% del padre.

■ Usar box-sizing: border-box para cambiar el modo en el que se gestionan los tamaños.

■ Utilizar un sistema moderno como Flexbox o Grid (recomendado).


Una forma simple de solucionar el problema en el ejemplo anterior, es hacer los siguientes cambios en
el CSS del documento:
/* Eliminamos este bloque */

#menu, #content {

display: inline-block;

/* Añadimos este */

#page {

display: flex;

De esta forma, conseguimos que nuestro diseño se adapte de forma adecuada a la página, sin necesidad
de tener que ajustar los márgenes, rellenos, bordes o tamaño de los contenidos.

Tamaños máximos y mínimos


Si buscamos un cierto grado de control aún mayor, podríamos recurrir a las propiedades max-width y
min-width , con las que podemos indicar el ancho de un elemento como máximo y el ancho de un
elemento como mínimo respectivamente, consiguiendo así garantizar cierto control del diseño:
.picture {

min-height: 200px; /* Por defecto, height es 0 */

background: grey; /* Simplemente, para verlo visualmente */

max-width: 1024px;

min-width: 800px;

}
En este caso, el elemento tiene un tamaño máximo de 1024 píxeles, y un tamaño mínimo de 800 píxeles,
por lo que si ajustamos el ancho de la ventana del navegador, dicho elemento iría variando en un rango
de 800 a 1024 píxeles, nunca haciéndose más pequeño de 800 o más grande de 1024.

Nota: Es importante darse cuenta de que este ejemplo funciona porque no hay definido un width (por
omisión, es igual a width: 100%). Desde que exista un width, las otras propiedades pierden efecto
porque se está obligando a que tenga un tamaño fijo concreto.

Con las imágenes, videos y contenidos multimedia, se puede hacer lo mismo, consiguiendo así que las
imágenes se escalen y adapten al formato especificado o incluso al tamaño de pantalla de los diferentes
dispositivos utilizados:
img,

video,

object,

embed {

max-width: 100%;

height: auto;

El viewport
En muchos casos puede que oigas hablar del viewport del navegador. Esa palabra hace referencia a la
región visible del navegador, o sea, la parte de la página que está visualizándose actualmente en el
navegador. Los usuarios podemos redimensionar la ventana del navegador para reducir el tamaño del
viewport y simular que se trata de una pantalla y dispositivo más pequeño.
Si queremos editar ciertos comportamientos del viewport del navegador, podemos editar el documento
HTML para especificar el siguiente campo meta, antes de la parte del </head>:
<meta name="viewport" content="initial-scale=1, width=device-width">

Con esta etiqueta <meta>, estamos estableciendo unos parámetros de comportamiento para el viewport
del navegador. Veamos que significan y cuales más existen:

Propiedades Valor Significado

width device-width Indica un ancho para el viewport.

height device-height Indica un alto para el viewport.

initial-scale 1 Escala inicial con la que se visualiza la página web.

minimum-scale 0.1 Escala mínima a la que se puede reducir al hacer zoom.


maximum-scale 10 Escala máxima a la que se puede aumentar al hacer zoom.

user-scalable no/fixed | yes/zoom Posibilidad de hacer zoom en la página web.

Las propiedades initial-scale , minimum-scale y maximum-scale permiten valores desde el 0.1 al 10 ,


aunque ciertos valores se traducen automáticamente a ciertos números determinados:

■ yes = 1

■ no = 0.1

■ device-width = 10

■ device-height = 10
Por otra parte, user-scalable permite definir si es posible que el usuario pueda «pellizcar» la pantalla
para ampliar o reducir el zoom.

Ojo: Aunque es posible utilizar algunos de estos parámetros, es aconsejable revisar detalladamente las
consecuencias de especificar estos parámetros. Lo recomendable es utilizar sólo los que se mencionan
en el fragmento de código superior, para evitar problemas de accesibilidad que impidan ciertas acciones.

Una vez nos adentramos en el mundo del Responsive Design, nos damos cuenta en que hay situaciones
en las que determinados aspectos o componentes visuales deben aparecer en un tipo de dispositivos, o
deben existir ciertas diferencias.
Por ejemplo, una zona donde se encuentra el buscador de la página puede estar colocada en un sitio
concreto en la versión de escritorio, pero en móvil quizás nos interesa que ocupe otra zona (o que tenga
otro tamaño o forma) para aprovechar mejor el poco espacio que tenemos en la versión móvil de la
página.
Para ello, utilizaremos un concepto denominado media queries, con los que podemos hacer esas
excepciones para que sólo se apliquen a un tipo de diseño concreto.

¿Qué son las media queries?


Las reglas media queries (también denominadas MQ a veces) son un tipo de reglas de CSS que
permiten crear un bloque de código que sólo se procesará en los dispositivos que cumplan los criterios
especificados como condición:
@media screen and (*condición*) {

/* reglas CSS */

/* reglas CSS */

@media screen and not (*condición*) {

/* reglas CSS */

/* reglas CSS */
}

Con este método, especificamos que queremos aplicar los estilos CSS para tipos de medios concretos
(screen: sólo en pantallas, en este caso) que cumplan las condiciones especificadas entre paréntesis. De
esta forma, una estrategia aconsejable es crear reglas CSS generales (como hemos hecho hasta ahora)
aplicadas a todo el documento: colores, tipo de fuente, etc. y luego, las particularidades que se aplicarían
sólo en el dispositivo en cuestión.
Aunque suele ser menos habitual, también se pueden indicar reglas @media negadas mediante la
palabra clave not, que aplicará CSS siempre y cuando no se cumpla una determinada condición.
Tambien pueden separarse por comas varias condiciones de media queries.

Truco: Al igual que not, también existe una palabra clave only que, suele usarse a modo de hack. El
comportamiento por defecto ya incluye los dispositivos que encajan con la condición, pero con la
palabra clave only conseguimos que navegadores antiguos que no la entienden, no procesen la
información, dejándola sólo para navegadores modernos.

Existen los siguientes tipos de medios:

Tipo de medio Significado

screen Monitores o pantallas de ordenador. Es el más común.

print Documentos de medios impresos o pantallas de previsualización de impresión.

speech Lectores de texto para invidentes (Antes aural, el cuál ya está obsoleto).

all Todos los dispositivos o medios. El que se utiliza por defecto.

Otros tipos de medios como braille, embossed, handheld, projection, tty o tv aún son válidos, pero
están marcados como obsoletos a favor de utilizar tipos de medios de la lista anterior y restringir sus
características posteriormente.
Recordemos que con el siguiente fragmento de código HTML estamos indicando que el nuevo ancho de
la pantalla es el ancho del dispositivo, por lo que el aspecto del viewport se va a adaptar
consecuentemente:
<meta name="viewport" content="initial-scale=1, width=device-width">
Con esto conseguiremos preparar nuestra web para dispositivos móviles y prepararnos para la
introducción de reglas media query en el documento CSS.

Ejemplos de media queries


Veamos un ejemplo clásico de media queries en el que definimos diferentes estilos dependiendo del
dispositivo que estamos utilizando. Observese que en el código existen 3 bloques @media donde se
definen estilos CSS para cada uno de esos tipos de dispositivos.
El código sería el siguiente:
@media screen and (max-width: 640px) {

.menu {

background: blue;

@media screen and (min-width: 640px) and (max-width: 1280px) {

.menu {

background: red;

@media screen and (min-width: 1280px) {

.menu {

background: green;

El ejemplo anterior muestra un elemento (con clase menu) con un color de fondo concreto, dependiendo
del tipo de medio con el que se visualice la página:

■ Azul para resoluciones menores a 640 píxeles de ancho (móviles).

■ Rojo para resoluciones entre 640 píxeles y 1280 píxeles de ancho (tablets).

■ Verde para resoluciones mayores a 1280 píxeles (desktop).


El número de bloques de reglas @media que se utilicen depende del desarrollador web, ya que no es
obligatorio utilizar un número concreto. Se pueden utilizar desde un sólo media query, hasta múltiples
de ellos a lo largo de todo el documento CSS.
Hay que tener en cuenta que los media queries también es posible indicarlos desde HTML, utilizando
la etiqueta <link>:
<link rel="stylesheet" href="[Link]"

media="screen and (max-width: 640px)">

<link rel="stylesheet" href="[Link]"

media="screen and (min-width: 640px) and (max-width: 1280px)">

<link rel="stylesheet" href="[Link]"

media="screen and (min-width: 1280px)">

Estos estilos quedarán separados en varios archivos diferentes. Ten en cuenta que todos serán
descargados al cargar la página, sólo que no serán aplicados al documento hasta que cumplan los
requisitos indicados en el atributo media.

Tipos de características
En los ejemplos anteriores solo hemos utilizado max-width y min-width como tipos de características a
utilizar en condiciones de media query. Sin embargo, tenemos una lista de tipos de características que
podemos utilizar:

Tipo de característica Valores ¿Cuándo se aplica?

width Si el dispositivo tiene el tamaño indicado exactamente.

min-width Si el dispositivo tiene un tamaño de ancho mayor al indicado.

max-width Si el dispositivo tiene un tamaño de ancho menor al indicado.

aspect-ratio aspect-ratio Si el dispositivo encaja con la proporción de aspecto indicada.

orientation landscape | portrait Si el dispositivo está en colocado en modo vertical o apaisado.

Existen otras características minoritarias que en algunos casos límite pueden ser interesantes, como por
ejemplo scan, resolution, monochrome, grid, color-index, color, etc...

Condicionales CSS
Aunque no forman parte de las media queries en sí, podemos utilizar la regla @supports para establecer
condicionales y crear reglas similares a @media pero dependiendo de si el navegador del usuario
soporta una característica concreta.
@supports not (display: grid) and (display: flex) {

.content {

display: flex;

justify-content: center;

@supports not (display: flex) {

.content {

display: block;

Estas reglas son muy interesantes para casos particulares donde queremos dar soporte a navegadores
antiguos, pero hay que tener en cuenta que navegadores como Internet Explorer (quizás uno de los
más interesantes para utilizarlo) no tienen soporte para la regla @supports, aún ni en su versión 11.
Uno de los procesos más problematicos y frustrantes de CSS, sobre todo para novatos o principiantes, es
el proceso de colocar y distribuir los elementos a lo largo de una página. Mecanismos como
posicionamiento, floats o elementos en bloque o en línea, suelen ser insuficientes (o muy complejos)
para crear un layout o estructuras para páginas web actuales.
El sistema flexbox es una gran mejora, sin embargo, está orientado a estructuras de una sola dimensión,
por lo que aún necesitamos algo más potente para estructuras web más específicas o complejas. Con el
paso del tiempo, muchos frameworks y librerías utilizan un sistema grid donde definen una cuadrícula
determinada, y modificando los nombres de las clases de los elementos HTML, podemos darle tamaño,
posición o colocación.

Grid CSS nace de esa necesidad, y recoge las ventajas de ese sistema, añadiendole numerosas mejoras
y características que permiten crear rápidamente cuadrículas sencillas y potentes de forma prácticamente
instantánea.

Conceptos
Antes de comenzar con Grid CSS, quizás sería conveniente dominar el sistema Flexbox, ya que Grid
toma la filosofía y bases de él. Para utilizar Grid CSS necesitaremos tener en cuenta una serie de
conceptos que utilizaremos a partir de ahora y que definiremos a continuación:
■ Contenedor: El elemento padre contenedor que definirá la cuadrícula o rejilla.

■ Ítem: Cada uno de los hijos que contiene la cuadrícula (elemento contenedor).

■ Celda (grid cell): Cada uno de los cuadritos (unidad mínima) de la cuadrícula.

■ Area (grid area): Región o conjunto de celdas de la cuadrícula.

■ Banda (grid track): Banda horizontal o vertical de celdas de la cuadrícula.

■ Línea (grid line): Separador horizontal o vertical de las celdas de la cuadrícula.


Para utilizar cuadriculas Grid CSS, trabajaremos bajo el siguiente escenario:
<div class="grid"> <!-- contenedor -->

<div class="a">Item 1</div> <!-- cada uno de los ítems del grid -->

<div class="b">Item 2</div>

<div class="c">Item 3</div>

<div class="d">Item 4</div>

</div>

Para activar la cuadrícula grid hay que utilizar sobre el elemento contenedor la propiedad display y
especificar el valor grid o inline-grid. Este valor influye en como se comportará la cuadrícula con el
contenido exterior. El primero de ellos permite que la cuadrícula aparezca encima/debajo del contenido
exterior (en bloque) y el segundo de ellos permite que la cuadrícula aparezca a la izquierda/derecha (en
línea) del contenido exterior.

Tipo de elemento Descripción

inline-grid Establece una cuadrícula con ítems en línea, de forma equivalente a inline-block.

grid Establece una cuadrícula con ítems en bloque, de forma equivalente a block.
Una vez elegido uno de estos dos valores, y establecida la propiedad display al elemento contenedor,
hay varias formas de configurar nuestra cuadrícula grid. Comencemos con las propiedades que se
aplican al elemento contenedor (padre).

Grid con filas y columnas


Es posible crear cuadrículas con un tamaño explícito. Para ello, sólo tenemos que usar las propiedades
CSS grid-template-columns y grid-template-rows, que sirven para indicar las dimensiones de cada
celda de la cuadrícula, diferenciando entre columnas y filas. Las propiedades son las siguientes:

Propiedad Valor Descripción

grid-template-columns [c1] [c2] ... Establece el de cada columna (col 1, col 2...).

grid-template-rows [f1] [f2] ... Establece el de cada fila (fila 1, fila 2...).

Conociendo estas dos propiedades, asumamos el siguiente código CSS:


.grid {

display: grid;

grid-template-columns: 50px 300px;

grid-template-rows: 200px 75px;

Esto significa que tendremos una cuadricula con 2 columnas (la primera con 50px de ancho y la
segunda con 300px de ancho) y con 2 filas (la primera con 200px de alto y la segunda con 75px de
alto). Ahora, dependiendo del número de ítems (elementos hijos) que tenga el contenedor grid,
tendremos una cuadrícula de 2x2 elementos (4 ítems), 2x3 elementos (6 ítems), 2x4 elementos (8 ítems)
y así sucesivamente. Si el número de ítems es impar, la última celda de la cuadrícula se quedará vacía.

Unidad fracción restante (fr)


En el ejemplo anterior he utilizado píxels como unidades de las celdas de la cuadrícula, sin embargo,
también podemos utilizar otras unidades (o incluso combinarlas) como porcentajes, la palabra clave
auto (que obtiene el tamaño restante) o la unidad especial de Grid CSS fr (fraction), que simboliza una
fracción de espacio restante en el grid. Veamos un código de ejemplo en acción:
.grid {

display: grid;

grid-template-columns: 1fr 1fr;

grid-template-rows: 2fr 1fr;

Este nuevo ejemplo, se crea una cuadrícula de 2x2, donde el tamaño de ancho de la cuadrícula se divide
en dos columnas (mismo tamaño de ancho para cada una), y el tamaño de alto de la cuadrícula se
divide en dos filas, donde la primera ocupará el doble (2 fr) que la segunda (1 fr):

De esta forma, podemos tener un mejor control del espacio restante de la cuadrícula, y como utilizarlo.

Nota: Se pueden combinar varias unidades diferentes, pudiendo utilizar píxeles (px) y fracciones
restantes (fr), porcentajes (%) y fracciones restantes (fr) o combinaciónes similares.

Filas y columnas repetitivas


En algunos casos, en las propiedades grid-template-columns y grid-template-rows podemos necesitar
indicar las mismas cantidades un número alto de veces, resultando repetitivo y molesto. Se puede
utilizar la expresión repeat() para indicar repetición de valores, indicando el número de veces que se
repiten y el tamaño en cuestión.
La expresión a utilizar sería la siguiente: repeat([núm de veces], [valor o valores]):
.grid {

display: grid;

grid-template-columns: 100px repeat(2, 50px) 200px;

grid-template-rows: repeat(2, 50px 100px);

Asumiendo que tuvieramos un contenedor grid con 8 ítems hijos (o más), el ejemplo anterior crearía una
cuadrícula con 4 columnas (la primera de 100px de ancho, la segunda y tercera de 50px de ancho y la
cuarta de 200px de ancho). Por otro lado, tendría 2 filas (la primera de 50px de alto, y la segunda de
100px de alto). En el caso de tener más ítems hijos, el patrón se seguiría repitiendo.
El ejemplo anterior sería equivalente al código CSS siguiente:
.grid {

display: grid;

grid-template-columns: 100px 50px 50px 200px;

grid-template-rows: 50px 100px 50px 100px;;

Grid con líneas nombradas


Con Grid CSS también tenemos la posibilidad de usar «linenames», o lo que es lo mismo, ponerle
nombre a las líneas de nuestro sistema grid. Vamos a verlo con un ejemplo, donde probablemente se vea
mucho mejor. Partamos de esta estructura HTML:
<div class="grid">

<div class="header">Header</div>

<div class="sidebar">Sidebar</div>

<div class="content">Content</div>

<div class="footer">Footer</div>

</div>

Los nombres de las clases ya dan una idea del contenido que tendrán. Ahora, mediante Grid CSS lo que
haremos es darle una estructura definida. Para ello, vamos a considerar los siguientes nombres para las
lineas de nuestro grid, utilizando X para las posiciones en el eje X y utilizando Y para las posiciones en
el eje Y:

Teniendo esto en cuenta, lo único que tenemos que hacer es indicar estos nombres entre corchetes, justo
antes de la medida que establecimos como vimos en apartados anteriores. Obsérvese que también se
coloca un nombre de línea final sin medida a continuación, que representa la línea final:
.grid {

display: grid;

grid-template-columns: [x0] 1fr [x1] 1fr [x2] 1fr [x3];

grid-template-rows: [y0] 1fr [y1] 1fr [y2] 1fr [y3];

En este caso, los nombres utilizados son tan sólo un ejemplo didáctico. Si se considera más adecuado, se
podrían utilizar otros nombres quizás más amigables como top-line, top-medium-line, bottom-
medium-line y bottom-line, por ejemplo, en lugar de y0, y1, y2 y y3 respectivamente.
Ahora, teniendo los nombres, sólo quedaría delimitar que zonas del grid queremos que ocupe cada uno
de nuestros bloques <div> del grid. Para ello utilizaremos las propiedades grid-column-start, grid-
column-end y grid-row-start, grid-row-end. También podriamos utilizar sus propiedades de atajo
grid-column y grid-row.
.header {

background: darkred;

grid-column-start: x0;

grid-column-end: x3;

/* Equivalente a */

grid-column: x0 / x3;

.sidebar {

background: black;

grid-row: y1 / y2;

color: white;

.content {

background: orange;

grid-column: x1 / x3;

grid-row: y1 / y3;

.footer {

background: green;

grid-column: x0 / x3;

grid-row: y2;

Hemos aplicado la siguiente estructura:

■ Zona .header desde la columna x0 a x3.

■ Zona .sidebar desde la fila y1 a y2.

■ Zona .content desde la columna x1 a x3 y desde la fila y1 a y3.

■ Zona .footer desde la columna x0 a x3 en la fila y2.


Por lo que nuestra estructura grid quedaría así:
Un poco más adelante veremos más detalladamente estas últimas propiedades.

Nota: Ten en cuenta que sería necesario darle un tamaño de alto con height al contenedor padre para
que el navegador sepa cuanto ocupará la estructura completa. También podemos modificar las medidas
1fr para dar menos proporción, por ejemplo utilizando en grid-template-rows un [y0] 0.5fr y un [y2]
0.25fr.

Grid por áreas


Mediante los grids CSS es posible indicar el nombre y posición concreta de cada área de una
cuadrícula. Para ello utilizaremos la propiedad grid-template-areas, donde debemos especificar el
orden de las áreas en la cuadrícula. Posteriormente, en cada ítem hijo, utilizamos la propiedad grid-area
para indicar el nombre del área del que se trata:

Propiedad Descripción

grid-template-areas Indica la disposición de las áreas en el grid. Cada texto entre comillas simboliza una fila.

grid-area Indica el nombre del área. Se usa sobre ítems hijos del grid.

De esta forma, es muy sencillo crear una cuadrícula altamente personalizada en apenas unas cuantas
líneas de CSS, con mucha flexibilidad en la disposición y posición de cada área:
.grid {

display: grid;

grid-template-areas: "head head"

"menu main"

"foot foot";

.a { grid-area: head; background: blue }

.b { grid-area: menu; background: red }

.c { grid-area: main; background: green }

.d { grid-area: foot; background: orange }


Aplicando este código, conseguiríamos una cuadrícula donde:

■ El Item 1, la cabecera (head), ocuparía toda la parte superior.

■ El Item 2, el menú (menu), ocuparía el área izquierda del grid, debajo de la cabecera.

■ El Item 3, el contenido (main), ocuparía el área derecha del grid, debajo de la cabecera.

■ El Item 4, el pie de cuadrícula (foot), ocuparía toda la zona inferior del grid.

OJO: Ten en cuenta añadir contenido de texto en cada celda del grid, para que Grid CSS detecte que esa
celda no está vacía.

En la propiedad grid-template-areas, en lugar de indicar el nombre del área a colocar, también


podemos indicar una palabra clave especial:

■ La palabra clave none: Indica que no se colocará ninguna celda en esta posición.

■ Uno o más puntos (.): Indica que se colocará una celda vacía en esta posición.

Huecos en grid
Por defecto, la cuadrícula tiene todas sus celdas pegadas a sus celdas contiguas. Aunque sería posible
darle un margin a las celdas dentro del contenedor, existe una forma más apropiada, que evita los
problemas clásicos de los modelos de caja: los huecos (gutters).
Para especificar los huecos (espacio entre celdas) podemos utilizar las propiedades grid-column-gap
y/o grid-row-gap. En ellas indicaremos el tamaño de dichos huecos:

Propiedad Descripción

grid-column-gap Establece el de los huecos entre columnas (líneas verticales).

grid-row-gap Establece el de los huecos entre filas (líneas horizontales).


Tomemos el ejemplo anterior como base. En él, le indicamos estas propiedades para colocar huecos
entre las celdas de la cuadrícula. El código a añadir al ejemplo anterior sería el siguiente:
.grid {

grid-column-gap: 100px;

grid-row-gap: 10px;

Con esto, obtendríamos un resultado como el siguiente, indicando huecos entre columnas de 100px y
huecos entre filas de 10px:

Atajo: Grid con huecos


Existe una propiedad de atajo para las propiedades grid-column-gap y grid-row-gap, permitiéndonos
la posibilidad de no tener que indicarlas por separado.
La propiedad en cuestión sería grid-gap y se utilizaría de la siguiente forma:
.grid {

/* grid-gap: <row-gap> <column-gap> */

grid-gap: 20px 80px;

/* Equivalente a grid-gap: 40px 40px; */

/* grid-gap: <rowcolumn-gap> */

grid-gap: 40px;

Posición en el grid
Existen una serie de propiedades que se pueden utilizar para colocar los ítems dentro de la cuadrícula.
Con ellas podemos distribuir los elementos de una forma muy sencilla y cómoda. Dichas propiedades
son justify-items y align-items, que ya conocerás del módulo CSS flexbox:

Propiedad Valores Descripción

justify-items start | end | center | stretch Distribuye los elementos en el eje horizontal.

align-items start | end | center | stretch Distribuye los elementos en el eje vertical.
Estas propiedades se aplican sobre el elemento contenedor padre, pero afectan a los ítems hijos, por lo
que actuan sobre la distribución de cada uno de los hijos. En el caso de que queramos que uno de los
ítems hijos tengan una distribución diferente al resto, aplicamos la propiedad justify-self o align-self
sobre el ítem hijo en cuestión, sobreescribiendo su distribución.
Estas propiedades funcionan exactamente igual que sus análogas justify-items o align-items, sólo que
en lugar de indicarse en el elemento padre contenedor, se hace sobre un elemento hijo. Las propiedades
sobre ítems hijos las veremos más adelante.
También podemos utilizar las propiedades justify-content o align-content para modificar la
distribución de todo el contenido en su conjunto, y no sólo de los ítems por separado:

Propiedad Valores

justify-content start | end | center | stretch | space-around | space-between | space-evenly

align-content start | end | center | stretch | space-around | space-between | space-evenly

De esta forma, podemos controlar prácticamente todos los aspectos de posicionamiento de la cuadrícula
directamente desde los estilos CSS de su contenedor padre

Atajo de posiciones grid


Si vamos a crear estructuras grid donde necesitamos utilizar las cuatro propiedades anteriores, quizás
sería mejor utilizar un atajo donde simplificaríamos mucho el código resultante. Es el caso de las
siguientes propiedades:

Propiedad Valores Descripción

place-items [align-items] [justify-items] Propiedad de atajo para *-items

place-content [align-content] [justify-content] Propiedad de atajo para *-content

Con ellas conseguiremos que nuestro código sea menos verboso.

Ajuste automático de celdas


Es posible utilizar las propiedades grid-auto-columns y grid-auto-rows para darle un tamaño
automático a las celdas de la cuadrícula. Para ello, sólo hay que especificar el tamaño deseado en cada
una de las propiedades. Además, también podemos utilizar grid-auto-flow para indicar el flujo de
elementos en la cuadrícula, y especificar por donde se irán añadiendo. Las propiedades son las
siguientes:

Propiedad Valores Descripción


grid-auto-columns Indica el tamaño automático de ancho que tendrán las columnas.

grid-auto-rows Indica el tamaño automático de alto que tendrán las filas.

grid-auto-flow row | column | dense Utiliza un algoritmo de autocolocación (intenta rellenar huecos).

Un ejemplo de como se insertarían los elementos en una cuadrícula de 2x2 utilizando grid-auto-flow
por columnas o por filas:

Atajo: Grid
Por último, existe una propiedad grid que sirve de atajo para la mayoría de propiedades CSS relativas a
cuadrículas. Su esquema de utilización sería el siguiente, junto a algunos ejemplos:
.grid {

/* grid: <grid-template> <grid-auto-flow> <grid-auto-rows> / <grid-auto-columns> */

grid: 100px 20px;

grid: 200px repeat(2, 100px) 300px;

grid: row;

grid: column dense;

grid: row 200px;

grid: row 400px / 150px;

Propiedades para ítems hijos


Hasta ahora, salvo algunas excepciones como justify-self, align-self o grid-area, hemos visto
propiedades CSS que se aplican solamente al contenedor padre de una cuadrícula. A continuación,
vamos a ver ciertas propiedades que en su lugar, se aplican a cada ítem hijo de la cuadrícula, para alterar
o cambiar el comportamiento específico de dicho elemento, que no se comporta como la mayoría.
Algunas de las propiedades vistas hasta ahora son las siguientes:
Propiedad Descripción

justify-self Altera la justificación del ítem hijo en el eje horizontal.

align-self Altera la alineación del ítem hijo en el eje vertical.

grid-area Indica un nombre al área especificada, para su utilización con grid-template-areas.

Sin embargo, existen algunas propiedades más, referentes en este caso, a la posición de los hijos de la
cuadrícula donde va a comenzar o terminar una fila o columna. Las propiedades son las siguientes:

Propiedad Descripción

grid-column-start Indica en que columna empezará el ítem de la cuadrícula.

grid-column-end Indica en que columna terminará el ítem de la cuadrícula.

grid-row-start Indica en que fila empezará el ítem de la cuadrícula.

grid-row-end Indica en que fila terminará el ítem de la cuadrícula.

Con dichas propiedades, podemos indicar el siguiente código CSS sobre el primer ítem de una
cuadrícula de 4 ítems:
.grid {

display:grid;

.a {

grid-column-start: 1;

grid-row-end: 2;

De esta forma, tenemos una cuadrícula de 4 elementos, en el que indicamos la posición del ítem 1
(elemento con clase .a): comenzando en la columna 1 y acabando en el inicio de la columna 2:
Ese sería el funcionamiento normal. Donde se ve la utilidad de estas propiedades, es si variamos los
valores de forma que tomen posiciones diferentes, como por ejemplo, si indicamos que el ítem 1 debe
comenzar en la columna 1, pero acabar en la columna 3 (ocupando la hipotética primera y segunda
celda):

En este nuevo ejemplo, comenzamos el primer ítem en la columna 2 y lo acabamos al principio de la


columna 3, por lo que la celda permanecerá en la posición de la segunda columna. Además, añadimos la
propiedad grid-row-start que hace lo mismo que hasta ahora, pero con las filas. En este caso, le
indicamos que comience en la fila 3, por lo que el ítem 1 se desplaza a una nueva fila de la cuadrícula,
dejando en la anterior el ítem 4:

También es posible utilizar la palabra clave span seguida de un número, que indica que abarque hasta
esa columna o celda.

Atajo: grid-column y grid-row


El módulo grid de CSS proporciona las propiedades de atajo grid-column y grid-row donde se nos
permite escribir en un formato abreviado las propiedades anteriores. Su sintaxis sería la siguiente:
.grid {
display: grid;

.a {

/* grid-column: <grid-column-start> <grid-column-end> */

/* grid-row: <grid-row-start> <grid-row-end> */

grid-column: auto;

grid-column: 4 / 6;

grid-column: span 3;

grid-column: span 3 / 6;

También podría gustarte