
Mozilla Firefox Quantum
Visual Studio
Code
Slack
El diseño web responsivo responde a las necesidades de los usuarios y los dispositivos que estén usando
Hoy en día es cada vez más impredecible el dispositivo, tamaño de pantalla y resolución con que los usuarios visiten nuestros sitios web
A partir de esto nace la necesidad de diseñar las intefaces de usuario de manera que éstas se adapten a potencialmente cualquier navegador y medio en que son usadas
No es solamente una manera de disponer elementos, sino que es una manera flexible de pensar y estructurar interfaces
Para crear sitios web responsivos tenemos múltiples herramientas, que constantemente se están ampliando y renovando, respondiendo a las necesidades actuales
Usamos Media Queries para definir puntos de quiebre, teniendo distintos estilos para distintos tamaños de pantalla
Podemos usar modulos CSS como Flexbox y CSS Grid, que nos permiten alinear, justificar y distribuir el espacio de elementos dependiendo de su contenedor, sin conocer el tamaño de éste, además de crear grillas complejas para disponer nuestros contenidos
Existen unidades de medida que se basan en valores dinámicos como porcentajes y medidas en función del tamaño de pantalla
Así como podemos condicionar estilos en función de la pantalla, también podemos tener diferentes estilos en función de la compatibilidad con los navegadores
El Viewport es el área visible por el usuario de una página web
Ésta área varía dependiendo del tamaño del dispositivo y del navegador y es en lo que nos basamos para disponer nuestros estilos responsivos
Antes de existir el diseño responsivo, las páginas web se hacían solo para pantallas de computadores
Inicialmente los celulares automáticamente generaban un Zoom para ver las páginas en formato Desktop y navegarlas por partes
Fue una solución momentánea que hoy en día no nos conviene, ya que diseñamos un layout específico y más cómodo para pantallas pequeñas
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<head>
Para evitar que esto suceda, HTML5 introdujo una etiqueta "meta" para controlar el viewport al cargarse la página
"width=device-width" Ajusta el ancho de la página al ancho del dispositivo
"initial-scale=1" Ajusta el zoom inicial a 100% al cargarse la página
Los Media Queries son condiciones que podemos poner en nuestro documento css, en función del ancho del viewport y tipo de dispositivo
Esto nos permite tener un solo documento HTML, que mostramos de disitntas maneras
Un Media Query está compuesto por un typo de medio (dispositivo: all, screen, print, speech) opcional y una carácterística de éste
Se pueden combinar varios queries usando operadres lógicos (and, not, only, ","). Los estilos contenidos en el query, solo se ocuparán si es que evalua verdadera la condición
Si es que no se especifica el dispositivo a mostrar, se asume que la característica aplica para todos
// Estilos para pantallas desde 600 pixeles de ancho
media@ (min-width: 600px) {
background: green;
}
// Estilos para pantallas hasta 1000 pixeles de ancho
media@ (max-width: 1000px) {
background: red;
}
// Estilos para pantallas entre 600 y 1000 pixeles de ancho
media@ (min-width: 600px) and (max-width: 1000px) {
background: blue;
}
Mobile First significa diseñar primero la versión mobile, con los elementos indispensables para pantallas chicas
Teniendo esto, vamos ampliando el diseño para versiones más grandes y complejas de la página web
En términos de estructura del documento CSS, podemos ir ordenando los media queries de la siguiente manera:
// Estilos para pantallas hasta 500 pixeles de ancho
media@ (max-width: 500px) {
background: green;
}
// Estilos para pantallas hasta 800 pixeles de ancho
media@ (max-width: 800px) {
background: red;
}
// Estilos para pantallas hasta 1200 pixeles de ancho
media@ (max-width: 1200px) {
background: blue;
}
Entra a tu navegador y abre ésta página
Selecciona en el menu de tu navegador "Herramientas">"Desarollador Web">"Modo de Diseño Responsivo"
Ahora podemos controlar el ancho del viewport, sabiendo los pixéles exactos. Experimenta con la página abierta
Crea un documento HTML y CSS, ordena el CSS de tal manera que las propiedades que no estén envueltas en un media query sean para las pantallas más chicas (hasta 600px)
Genera dos media queries, uno que contenga los estilo para pantallas medianas (desde 601px) y el otro para todas las pantallas grandes (desde 1000px)
Pon a prueba tu código usando el "Modo de Diseño Responsivo"
El patrón más común para las páginas web responsivas, es que las pantallas chicas tienen los elementos apilados uno sobre otro, de manera vertical
y las pantallas grandes tienen diseños más horizontales y complejos
La mayoría de las veces se necesitan un mínimo de 3 puntos de quiebre
Existen dos categorías principales de disposición de los elementos, que nos interesan para el diseño responsivo
La primera es una disposición (layout) "Fluid" y la otra "Fixed"
"Fluid" quiere decir que los elementos se estiran y encojen para ajustarse a la pantalla y "Fixed" quiere decir que los elementos tienen un ancho fijo, independiente del ancho de la pantalla
Es un error crear puntos de quiebre pensando en los dispositivos en particular, ya que éstos son demasiado variables
Los puntos de quiebre se elijen en función del contenido y necesidad
Crea la versión mobile y con el "Modo de diseño responsivo", se pueden ir creando puntos de quiebre a medida que sea necesario
Muchas veces es una buena idea crear un layout "Fixed" a partir de un tamaño grande, para que no se sigan estirando los elementos
Flexbox es un módulo CSS que nos permite decidir sobre la distribución espacial entre elementos
Permite alinear y centrar muy facilmente elementos
Los contenedores con la propiedad flex son tratados como columna o fila (una dimension)
// Contenedor con la propiedad flex
.container {
display: flex;
}
El eje principal lo definimos con "flex-direction" (row, column)
El eje secundario es perpendicular al eje principal
Trata al contenedor como una fila (no como columna)
// Contenedor con la propiedad flex
//Podemos usar la dirección "row" o "row-reverse"
.container {
display: flex;
flex-direction: row;
flex-direction: row-reverse;
}
Trata al contenedor como una columna (no como fila)
// Contenedor con la propiedad flex
//Podemos usar la dirección "column" o "column-reverse"
.container {
display: flex;
flex-direction: column;
flex-direction: column-reverse;
}
Crea un documento HTML y CSS, copia el siguiente código y revisa el resultado
<body>
<div class="page">
<div class="section menu">Menu</div>
<div class="section contenido">Contenido</div>
<div class="section sign-up">Sign-up</div>
<div class="section elemento-1">Uno</div>
<div class="section elemento-2">Dos</div>
<div class="section elemento-3">Tres</div>
</div>
</body>
.page {
display: flex;
//Revisaremos ésta propiedad mas adelante
flex-wrap: wrap;
}
.section {
width: 100%;
height: 300px;
}
.menu {
background: #4562f2;
height: 80px;
}
.header {
background: rgb(158, 234, 255);
}
.contenido {
background: rgb(245, 246, 248);
}
.sign-up {
background: rgb(192, 171, 255);
}
.elemento-1 {
background: #F5CF8E;
}
.elemento-2 {
background: #F09A9D;
}
.elemento-3 {
background: #C8C6FA;
}
Agrega los media queries para pantallas medianas y grandes y revisa el resultado
//Pantallas medianas
@media (min-width: 401px) {
.sign-up, .elemento-1, .elemento-2, .elemento-3 {
width: 50%;
}
}
//Pantallas grandes
@media (min-width: 961px) {
.page {
width: 960px;
margin: 0 auto;
}
//"order" nos permite agrupar todos los items con esta propiedad en un grupo y asignarles un orden
.sign-up {
width: 100%;
height: 160px;
order: 1;
}
.contenido {
order: 2;
}
.elemento-1, .elemento-2, .elemento-3 {
width: 33.3%;
}
header {
height: 400px;
}
}
Agrégale a ".section" las siguientes propiedades
display: flex;
justify-content: center;
align-items: center;
"justify-content" distribuye los contenidos en el eje principal y "align-items" los distribuye en el eje secundario
De esta manera logramos que todos los elementos dentro de nuestros contenedores estén centrados horizontal y verticalmente
Agrega los siguientes div de clase "elem-menu" a tu menu
<div class="menu flex">
<div class="elem-menu flex flex-center">1</div>
<div class="elem-menu flex flex-center">2</div>
<div class="elem-menu flex flex-center">3</div>
<div class="elem-menu flex flex-center">4</div>
</div>
Agrega las siguientes clases a tu css
.flex {
display: flex;
}
.flex-center {
align-items: center;
justify-content: center;
}
.elem-menu {
width: 40px;
margin: 0 10px;
background: #a0c3ff;
}
//Modifica la clase .menu
.menu {
flex-direction: row;
width: 100%;
background: #4562f2;
height: 80px;
padding: 20px;
}
Acabas de crear las clases ".flex" y ".flex-center" para tener estas propiedades específicas siempre disponibles y agregaste las dos juntas a los elemenots hijo de .menu para centrar los numeros automaticamente
Al contenedo ".menu" le diste la dirección "row", generando un contenedor en dirección horizontal
Intenta el valor "row-reverse" en la propiedad "flex-direction" en el menu
.menu {
flex-direction: row-reverse;
width: 100%;
background: #4562f2;
height: 80px;
padding: 20px;
}
Agrega a la clase ".menu" la propiedad "justify-content" y experimenta con "flex-start", "flex-end" y modifica la dirección a "row" y "row-reverse"
.menu {
flex-direction: row-reverse;
justify-content: flex-end;
width: 100%;
background: #4562f2;
height: 80px;
padding: 20px;
}
A "justify-content" también le podemos asignar los valores "space-evenly", "space-around" y "space-between"
Esto define como se va a ocupar el espacio en el sentido del contenedor (column-row)
Experimenta como se comportan los elementos del menu al asignarle a "justify-content" los valores: "space-around", "space-evenly" y "space-between"
Agrega elementos hijos al elemeto de clase ".header"
<div class="header flex">
<div class="elem-header flex flex-center">1</div>
<div class="elem-header flex flex-center">2</div>
<div class="elem-header flex flex-center">3</div>
</div>
Actualiza tu CSS con las siguentes clases
Experimenta con la dirección y disposición de espacio
.elem-header {
background: #4562F2;
height: 40px;
margin: 10px 0;
}
.header {
flex-direction: column;
justify-content: space-between;
background: rgb(158, 234, 255);
width: 100%;
height: 300px;;
padding: 20px;
}
Column funciona bajo los mismos principios que Row, solo que la dirección de su eje principal y secundario cambian como en la gráfica dos diapositivas atrás
Un contenedor "flex" por defecto fuerza a los elementos a mantenerse en una sola línea
Podemos modificar este comportamiento con la propiedad "flex-wrap", que nos permite disponer a los elementos en una sola línea, o en varias filas, dependiendo de su ancho
Agrega el siguiente código al elemento de clase "elemento-1"
<div class="section elemento-1 flex">
<div class="caja1"></div>
<div class="caja1"></div>
<div class="caja1"></div>
<div class="caja1"></div>
</div>
.elemento-1 {
background: #F5CF8E;
}
.caja1 {
background: rgb(220, 158, 53);
width: 100px;
height: 100px;
margin: 10px;
}
Experimenta agregandole a "elemento-1", la propiedad "flex-wrap", usa los valores "wrap" y "nowrap", revisando el resultado
Uno de los características más poderosas de Flexbox, es el poder que tiene de alinear elementos a lo largo del eje principal y secundario y de distribuir el espacio entre los elementos
Align-items se usa para alinear los elementos en el eje secundario. El valor por defecto es "stretch", haciendo que los elementos se "estiren", ocupando la altura total del contenedor
Podemos asignarle el valor "flex-start" y "flex-end" para alinearlos al inicio o al final del eje secundario o "center", que centra los elementos
Agrega el siguiente código y revisa el resultado
Experimenta con los valores "flex-start", "flex-end" y "center". Para que éstos funcionen, se requiere la dimensión "height" en la clase "caja2"
<div class="section elemento-2 flex">
<div class="caja2"></div>
<div class="caja2"></div>
<div class="caja2"></div>
<div class="caja2"></div>
</div>
.elemento-2 {
background: #F09A9D;
flex-wrap: nowrap;
align-items: stretch;
}
.caja2 {
background: rgb(222, 96, 100);
width: 50px;
margin: 10px;
}
La propiedad "justify-content" sirve para alinear los elementos sobre el eje principal
El valor inicial es "flex-start", pero acepta también "flex-end" y "center"
"Justify-content" nos permite además tomar desiciones sobre como usar el espacio libre del contenedor. Podemos usar los valores "space-around, "space-between" y "space-evenly"
Agrégale al código anterior la propiedad "justify-content" y experimenta con los distintos valores
Agrega el siguiente código a tu documento HTML y genera a través de CSS el resultado en la imagen
<div class="section elemento-3 flex">
<div class="caja3">Lorem20</div>
<div class="caja3">Lorem20</div>
</div>
La propiedad "flex-grow" se puede agregar a los elementos hijo del contenedor "flex" y sirve para disponer los tamaños de los elementos
Si todos los elementos hijo tienen asignado el valor "flex-grow: 1", serán del mismo tamaño, si a uno le diéramos el valor "flex-grow: 2", éste cubrirá el doble de espacio que los otros y asi sucesivamente
Agrega el siguiente código y revisa el resultado. Experimenta con la propiedad "flex-grow", viendo el cambio de comportamiento
<div class="section sign-up flex">
<div class="sign1"></div>
<div class="sign2"></div>
</div>
.sign-up {
background: rgb(192, 171, 255);
flex-direction: row;
align-items: stretch;
}
.sign1 {
background: rgb(114, 85, 201);
flex-grow: 1;
margin: 10px;
}
.sign2 {
background: rgb(114, 85, 201);
flex-grow: 3;
margin: 10px;
}
Crea tu propio código para lograr la disposición en la siguiente imagen dentro de ".contenido", tendrás que transformar un elemento hijo de ".contenido" en un contenedor flex también
CSS nos entrega algunas unidades de medida relativas, es decir que cambian según un punto de referencia
La más simple y conocida es porcentaje (%), que nos permite definir dimensiones en relación al contenedor más cercano
También tenemos algunas en relación al viewport, que son fundamentales para el diseño responsivo, ya que se ajustan constantemente al ancho o altura de la pantalla
vw: "view-with", 1vw representa el 1% del ancho del viewport
vh: "view-height" 1vh representa el 1% de la altura del viewport
vmax: "view-max" 1vmax representa el 1% del lado mas grande del viewport
vmin: "view-min" 1vmin representa el 1% del lado mas pequeño del viewport
CSS Grid es una poderosa herramienta que nos permite crear disposiciones más complejas y concretas que CSS Flex
A diferencia de Flex, nos permite crear disposiciones en dos dimensiones (columnas y filas al mismo tiempo), es decir definir una grilla
Para definir un contenedor Grid, asignamos la propiedad "display: grid"
Crea un nuevo documento HTML y CSS
Copia el siguiente código y reivsa el resultado
<body>
<div class="grid contenedor">
<div class="elemento1"></div>
<div class="elemento2"></div>
<div class="elemento3"></div>
<div class="elemento4"></div>
</div>
</body>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid {
display: grid;
}
.contenedor {
width: 100vw;
height: 100vh;
}
.elemento1 {
background: rgb(255, 90, 90);
}
.elemento2 {
background: rgb(70, 70, 255);
}
.elemento3 {
background: rgb(255, 255, 80);
}
.elemento4 {
background: rgb(207, 129, 255);
}
Un contenedor grid nos permite definir cuantas columnas y filas queramos, dándonos la libertad de elegir las medidas de cada una de éstas
Estas medidas pueden ser valores absolutos o relativos
CSS Grid tiene su propia medida relativa, llamada "fr"
"fr" viene de "fraction", esta unidad considera el espacio utilizable y lo divide en la cantidad de elementos que lo ocupan
Si tenemos dos elementos en un contenedor y queremos que cada uno de éstos ocupe la mitad del contendor, podemos definirlo como una fila que tiene dos columas de "1fr" cada una
Para definir la grilla usamos las propiedades "grid-template-columns" y "grid-template-rows"
La primera nos permite definir las columnas y la segundas las filas
Como valores simplemente damos las medidas que queremos para cada columna o fila, separadas de un espacio
.contenedor-grid {
display: grid;
//Define dos columnas, la primera de 100px y la segunda de 200px de ancho
grid-template-columns: 100px 200px;
//Define tres filas, cada una de 30% de altura
grid-template-rows: 30% 30% 30%;
}
Agrega el siguiente código al ejercicio anterior y revisa el resultado
Experimenta cambiandole los valores a "fr", y define grillas con columnas y filas distinas usando valores absolutos y relativos
.contenedor {
width: 100vw;
height: 100vh;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
En la imagen podemos ver la grilla que se genera al asignar las filas y columnas
Cada separador que se genera en la grilla tiene asignado un índice, partiendo del 1, es decir, cada división de la grilla está numerada
Usando la numeración de los separadores de la grilla definida, podemos decidir desde que separador a que separador va a ocupar cada elemento
Ésto lo hacemos asignandole a los elementos de la grilla la propiedad "grid-row" y "grid-column", especificando como valor los índices del separador inicial y final, separados por un "/"
.elemento1 {
//Ocupa una columna que va desde el primer
//separador vertical, hasta el tercero
grid-column: 1 / 3;
//Ocupa una fila que va desde el segundo
//separador horizontal, hasta el tercero
grid-row: 2 / 3;
}
Lo anterior nos permite elegir el orden de como se mostrarán los elementos, independientemente del orden en el documento HTML
Copia el siguiente código y experimenta posicionando los elementos de distintas maneras usando "grid-row" y "grid-column"
Intenta asignarle a algún elemento el valor "1 / 3". Ten presente que tendrás que generar una columna o fila más para que funcione
.elemento1 {
background: rgb(255, 90, 90);
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.elemento2 {
background: rgb(70, 70, 255);
grid-column: 1 / 2;
grid-row: 1 / 2;
}
.elemento3 {
background: rgb(255, 255, 80);
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.elemento4 {
background: rgb(207, 129, 255);
grid-column: 1 / 2;
grid-row: 2 / 3;
}
Imita la siguiente imagen usando CSS Grid
Tendrás que expandir un elemento más allá de solo un separador y agregarle una columna
Puedes inspeccionar una grilla para ver sus columnas y filas usando Firefox Developer Edition
Abre tu inspector y selecciona el botón "grid" para ver como está construida la grilla
CSS Grid nos permite ser aun más específicos con la construcción de nuestra grilla
"grid-template-areas" nos permite definir de manera gráfica nuestras grillas y nombrar de manera simple nuestros elementos y las posiciones de éstos
Cada vez que abrimos unas comillas, estamos definiendo una nueva fila y dentro de esta fila, designamos las columnas separando los elementos con un espacio
Poner en un espacio un punto, significa que queremos que esté vacío
"grid-area" nos permite nombrar a los elementos
.grid {
display: grid;
grid-template-areas:
"caja1 caja2"
". caja3";
grid-gap: 10px;
}
.caja1 {
grid-area: caja1;
}
.caja2 {
grid-area: caja2;
}
.caja3 {
grid-area: caja3;
}
Vamos a construir una grilla responsiva con elementos "flotando" en puntos específicos usando "grid-template-areas"
El siguiente código es la estructura básica. Hemos creado un contenedor grid y asignado un nombre a cada uno de sus elementos
<body>
<div class="grid contenedor">
<div class="elemento1">Disfruta</div>
<div class="elemento2">Unas Buenas</div>
<div class="elemento3">Vacaciones</div>
</div>
</body>
.grid {
display: grid;
}
.elemento1 {
grid-area: ele1;
}
.elemento2 {
grid-area: ele2;
color: white;
}
.elemento3 {
grid-area: ele3;
}
Ahora definiremos las áreas
Esta vez hacemos los media queries con "max-width", ya que partimos con una disposición de tamaño grande y nos vamos achicando (desktop first)
Crea un tercer media query para tamaños pequeños
.contenedor {
width: 100vw;
height: 100vh;
grid-template-areas:
". . . . . ."
". . ele1 . . ."
". . . . . ."
". ele2 . . . ."
". . . . ele3 ."
". . . . . .";
align-items: center;
background: url('caribe_baja.jpg');
background-size: cover;
background-position: center;
}
@media (max-width: 1000px) {
.contenedor {
background-position: left;
grid-template-areas:
". . . . . ."
". . ele1 . . ."
". ele2 . ele3 . ."
". . . . . ."
". . . . . ."
". . . . . .";
}
}
Con "grid-template-areas" también podemos ocupar más de un espacio, ésto simplemente repitiendo un elemento a través de múltiples espacios
.contenedor-grid {
display: grid;
grid-template-areas:
"caja1 caja1"
"caja3 caja2";
}
Genera una grilla responsiva con "grid-template-areas", imitando las imágenes
Usa además "grid-template-columns" y "grid-template-rows", para definir las dimensiones de la grilla. No está permitido asignarle alturas propias a los elementos
Tendrás que crear además una grilla anidada dentro del elemento central "main", de cuatro elementos
Lo que en última instancia queremos lograr con el diseño responsivo, es que nuestras páginas web se vean bien, independientemente del navegador en donde se muestren
Que nuestra página se vea bien en todos los navegadores, no significa que se vea siempre igual. La idea es tener distintos estilos dependiendo de donde y como se está mostrando nuestra página web. Asi tendremos distintas experiencias, pero siempre buenos resultados
Una de las herramientas que nos permite hacer esto es "@supports", que nos permite condicionar estilos dependiendo de la compatibilidad con determinadas propiedades
@supports (display: grid) {
.contenedor {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
}
Curiosamente "@supports" es un módulo bastante nuevo de CSS y por lo tanto no es compatible con varios navegadores más antiguos
Si bien ésto puede parecer inútil, no lo es, ya que podemos aprovecharnos de las reglas de cascada y poner la condición después de los estilos aceptados por los navegadores más antiguos
Recuerda que cuando algo no es compatible con el navegador, el intérprete de CSS simplemente lo ignora y continúa interpretándo el código
.contenedor {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
@supports (display: grid) {
.contenedor {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
}
Ocupa el ejercicio 14 (donde se vio "grid-template-areas") y encapsula el código "grid" en un "@supports"
Crea un código para navegadores que no acepten la propiedad "display:grid" con otros recursos y experimenta el resultado, apagando desde el inspector las propiedades grid
Ten presente que se pueden anidar "@supports" y "@media" sin importar el orden
Hemos visto como escribir código CSS para distintas pantallas, navegadores y compatibilidades con múltiples recursos, generando varias experiencias posibles de una misma página web
Podríamos contentarnos con ésta información, pero ¿Qué pasa cuando no hay CSS?
Hoy en día hay distintos casos en los que se elimina por completo o gran parte del código CSS, algunos navegadores permiten ver las páginas en modo "lectura", existen lectores de pantalla que solo reproducen el contenido HTML y distintas aplicaciones que permiten descargar las páginas para verlas después (muchas veces sin los estilos)
Lo que debemos hacer para estos casos, es antes que nada, tener una sólida estructura HTML. Revisa tus páginas deshabilitando todo docuemnto CSS y estructuralas de tal manera que tenga sentido por si sola, solo en términos de contenido y estructura, esto asegurará que en todos los casos tu página va a tener sentido, incluso si no se ve "bonita"
Y luego puedes, con los recursos aprendidos, re-estructurar todos los elementos visualmente como gustes, sin modificar la estructura HTML