Introducción a Flex Box PDF

Title Introducción a Flex Box
Author luis gonzalez
Course Diseño de Interfaces
Institution Universidad de Caldas
Pages 69
File Size 3.2 MB
File Type PDF
Total Downloads 88
Total Views 153

Summary

modelo layout...


Description

Flexbox Es un modelo de diseño (layout) incorporado a CSS para definir cómo se despliegan los componentes en pantalla. CSS tiene varios modelos de despliegue: inline, inline-block, block, inline-table, inline-flex, inline-grid, flexbox y grid, aquí nos centraremos en FlexBox. Para empezar, suponga que se quiere el siguiente diseño inicial:

Se puede pensar en la siguiente estructura HTML:

Fundamentos de Flexbox

Prerrequisito para entender más adelante el tema Diseos Adaptables con las Utilidades Flexbox de los frameworks Tailwind CSS y Bootstrap

Carlos Cuesta



Para el diseño se requiere entonces una hoja de estilos con el siguiente código: body { margin: 0; padding: 0; font-family: sans-serif; }

h1 { text-align: center; color: steelblue; } div { width: 500px; height: 300px; background: lightblue; margin: auto; text-align: center; padding: 1em; display: flex; justify-content: center; /* por defecto flex-start */ align-items: center; /* por defecto flex-start */ } footer { padding-top: 3em; text-align: center; }

Se resaltan las instrucciones para centrar el div y para aplicar alineación centrada a los elementos de éste. Para mayor claridad, se define enseguida cómo actúan las propiedades justify-content y align-items. Se espera que realice pruebas con estos valores. La propiedad justify-content, sirve para colocar los ítems de un contenedor mediante una disposición concreta a lo largo del eje principal (por defecto el horizontal). Valores posibles:

Tomado de: https://lenguajecss.com/css/maquetacion-y-colocacion/flexbox/

La propiedad align-items es usada para alinear los ítems del eje secundario (por defecto, el vertical). Asume por defecto el valor stretch.

Tomado de: https://lenguajecss.com/css/maquetacion-y-colocacion/flexbox/

Veamos en la siguiente gráfica, la técnica con la que flexbox organiza los elementos:

Tomado de https://bit-multimedia.com/wp-content/uploads/2016/12/flexbox-diagrama-css.jpg

Lo primero es saber que flexbox define la orientación en la que van a aparecer los elementos (items) en un contenedor, dispuesto en un eje principal y un eje secundario o transversal. El eje principal puede estar en sentido horizontal (por defecto) o en sentido vertical.

Tomado de https://lenguajecss.com/css/maquetacion-y-colocacion/flexbox/

Según la figura anterior, para organizar los elementos en el ejemplo que se viene trabajando, se requiere de un contenedor flexbox, en el cual se colocan los ítem. Veamos un ejemplo inicial de un contenedor con tres hijos:

Fundamentos de Flexbox

1 2 3

Carlos Cuesta

body { margin: 0; padding: 0; font-family: sans-serif; } h1 { text-align: center; color: steelblue; } .flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; /* por defecto el eje principal es horizontal */ } .flex-item {

background: tomato; color: aliceblue; } .flex-item:nth-child(odd) { background: teal; } footer { padding-top: 3em; text-align: center; }

El div al cual se le aplicó la clase flex-container es el contenedor o contexto en el que se han colocado los tres divs hijos que vienen a ser los ítem. Puesto que, el eje principal es horizontal de izquierda a derecha, los tres elementos se han dispuesto de izquierda a derecha. Existe la propiedad flex-direction que permite cambiar la orientación del eje principal en los siguientes sentidos: ● ● ● ●

row: valor por defecto. Establece la dirección del eje principal en horizontal. row-reverse: etablece la dirección del eje principal en horizontal (invertido). column: establece la dirección del eje principal en vertical. column-reverse: establece la dirección del eje principal en vertical (invertido).

Por ejemplo se puede agregar a la clase .flex-container la propiedad flex-direction e indicar que los elementos van en columna: .flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; flex-direction: column; } De esta manera los elementos se apilan en una columna de arriba a abajo. Veamos:

Pruebe con los cuatro valores que puede tener la propiedad flex-direction y observe los resultados que obtiene: row, row-reverse, column y column-reverse. Debe quedar claro por ejemplo que si flex-direction se establece en column-reverse, el eje principal es el vertical y el inicio se ubica en la parte inferior. Importante: ●

Debe tenerse en cuenta que si se agrega al container un texto o cualquier otro elemento éste queda por defecto embebido en un ítem. Ejemplo:

Texto



Las propiedades de flex no se heredan, pero lo que sí se puede hacer es anidar flex dentro de ítems. Para el siguiente ejemplo se anidó un flex dentro de los ítems con el fin de poder aplicar la propiedad justify-content a los hijos de los ítems: .flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; } .flex-item {

background: tomato; color: aliceblue; width: 100px; height: 100px; display: flex; /* centra sobre el eje principal: */ justify-content: center; /* centra sobre el eje secundario: */ align-items: center; } .flex-item:nth-child(odd) { background: teal; } Como resultado los números de cada ítem aparecen centrados tanto en su eje principal (en este caso horizontal) como en su eje secundario:



Para lograr el efecto de la figura siguiente, se ha indicado que el tipo de justificado del contenido es space-between:

.flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; justify-content: space-between; /* espacio entre elementos */ }



Aplicando justify-content: space-around; el efecto sería un espacio igual alrededor de los elementos:



Una prueba cambiando la dirección del eje principal:

.flex-container { width: 500px; height: 400px; background: lightblue; margin: auto; display: flex; flex-direction: column; justify-content: space-around; } ●

Suponga que al contenedor se le ha incorporado una imagen:



Además se tiene el siguiente código CSS: .flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; flex-direction: column; justify-content: space-around; } .flex-item { background: tomato; color: aliceblue; display: flex; justify-content: center; align-items: center; } El resultado es una imagen que ocupa todo el ancho, dado que la dirección del eje principal es column y no se ha especificado la propiedad align-items, por lo tanto se asume, para el eje secundario, stretch por defecto:

Si se elimina de la clase flex-direction, ésta queda por defecto en row: .flex-container {

width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; justify-content: space-around; } El resultado es una imagen que ocupa toda la altura, dado que la dirección del eje principal si no se especifica es row y también si no se especifica la propiedad alignitems, se asume stretch por defecto para el eje secundario,:

De igual manera se pueden probar para la propiedad align-items, los valores flex-start, flexend, center, stretch, baseline. Observe por ejemplo el efecto para align-items: center: .flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; justify-content: center; align-items: center; } Ahora supongamos que el contenedor incluye los siguientes tres elementos:

1 2

Los estilos se han establecido como se muestra: .flex-container {

width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; justify-content: space-around; align-items: baseline; } .flex-item { background: tomato; color: aliceblue; display: flex; justify-content: center; justify-content: center; } .flex-item:nth-child(2) { font-size: 3em; } .flex-item:nth-child(odd) { background: teal; } Ahora se puede ver que todos los elementos se han alineado con respecto a la línea base:

Puede realizar otras comprobaciones, por ejemplo lo que sucede al especificar como flexdirection: column y como align-items: center. Importante: existe la propiedad align-self que actúa exactamente igual que align-items, pero sobre un ítem hijo específico y no sobre el elemento contenedor.

Para dar un ejemplo sobre align-self, considere el siguiente cambio en el CSS, utilizando los últimos componentes HTML: .flex-container { width: 500px; height: 300px; background: lightblue; margin: auto; display: flex; justify-content: space-around; align-items: flex-start; } .flex-item { background: tomato; color: aliceblue; display: flex; justify-content: center; } .flex-item:nth-child(2) { font-size: 3em; align-self: center; } .flex-item:nth-child(odd) { background: teal; } De esta manera se sobreescribe, para un único elemento, el valor de la propiedad align-items, especificada en el contenedor. Por lo tanto el resultado es el siguiente:

De igual manera se puede especificar que la imagen que se incluyó dentro del contenedor, quede ubicada en la parte inferior: .flex-container > img { align-self: flex-end; } Con lo cual el resultado que se obtiene es el siguiente:

Creación de una cabecera Se requiere una cabecera de página como la que se muestra enseguida:

Dicho encabezado puede crearse mediante la siguiente estructura HTML:

item 1 item 2 item 3 item 4 item 5

Además se requieren los siguientes elementos en la hoja de estilos: header { height: 140px; background: #333333; display: flex; /* distribuye en todo el ancho del eje principal (horizontal por defecto): */

justify-content: space-between; /* centrar elementos en el eje secundario (vertical por defecto): */

align-items: center; } header > ul { list-style: none; color: aliceblue; padding: 0; margin: 0; margin-bottom: 0.7em; margin-right: .5em; /* los hijos de la ul se ubican en el eje principal (horizontal) */

display: flex; /* Sólo este elemento (ul) se ubica en la parte inferior */

align-self: flex-end; } header > ul li { background: #eeeeee; color: #333333; border-radius: 5px;

margin-left: 10px; font-size: 1.3em; padding: 0 .5em; line-height: 2; } .logo { margin-left: .5em; /* formato circular */ border-radius: 50%; }

Con unas pocas variaciones que se resaltan en el código siguiente, se puede lograr la siguiente presentación:

header { height: 140px; background: #333333; display: flex; align-items: center; } header > ul { list-style: none; color: aliceblue; padding: 0; margin: 0; margin-right: .5em; display: flex; } .logo { margin-left: .5em; margin-right: auto; /* usa todo lo disponible y empuja la ul a la derecha */ border-radius: 50%; }

Diseño de un menú responsive, tipo “mobile first” Suponga que se tiene el siguiente código fuente que servirá de base para la creación de un menú:

Interfaces 2020-2

Contáctenos

Si se inspeccionan los elementos de la página (Ctrl+Mayús+C), se observa que, por defecto, el navegador aplica algunos estilos que generan márgenes al lado izquierdo (40 px) y en la parte superior e inferior (16px):

Lo que se hará enseguida es aplicar una clase que “limpie” de estilos la lista del menú: /* conserve los elementos de lista ... */

body { margin: 0; padding: 0; font-family: sans-serif; } .menu { padding-left: 0; margin-top: 0; margin-bottom: 0; list-style: none; } Continuando, ahora lo que se quiere es: ● ●

que por defecto las opciones permanezcan en forma vertical en cualquier dispositivo y agregar un fondo.

.menu { padding-left: 0; margin-top: 0; margin-bottom: 0; list-style: none; background: steelblue; display: flex; flex-direction: column; }

También se quiere aplicar un borde inferior a cada opción, representadas por los elementos de la lista del menú, menos a la última: .menu li { border-bottom: 2px solid rgba(0, 0, 0, 0.2); } .menu li:last-child { /* la última opción no tendrá bordes */ border: none; }

Aquí puede encontrar una guía sobre las seudoclases utilizadas en este tutorial. Para los enlaces es necesario especificar algunos estilos, entre ellos el que da otro color al fondo de la opción seleccionada. Veamos:

.menu a { color: #eeeeee; text-decoration: none; display: block; padding: 1em; font-weight: bold; font-size: 0.9em; } .menu a:hover { /* se da un poco de sombra a la opción seleccioanda */ background: rgba(0, 0, 0, 0.2); } Con los estilos aplicados el resultado conseguido hasta ahora es el de un menú vertical que resalta la opción seleccionada:

Lo que sigue es hacer que el menú se adapte a diferentes tipos de pantalla, cambiando a un formato horizontal en pantallas grandes y a un menú vertical en pantallas pequeñas. Esto se consigue aplicando Media Queries en determinados punto de ruptura. “¿Qué es un punto de ruptura CSS? – Los puntos de ruptura CSS son puntos en los que el contenido del sitio web responde de acuerdo con el ancho del dispositivo, lo que le permite mostrar el mejor diseño posible al usuario... [...] La opción ideal para decidir los puntos de ruptura se basa en el contenido del sitio. Este método permite simplemente agregar puntos de interrupción donde el contenido necesita ajustarse al diseño. Esto hará que las Media Queries sean mucho más simples y manejables.” Saber más...

Para el caso que nos ocupa, el menú deberá cambiar a formato horizontal a partir de los 768 pixeles, así que el código que se requiere es el siguiente: @media screen and (min-width: 768px) { .menu { flex-direction: row; } .menu > li { text-align: center; border-right: 2px solid rgba(0, 0, 0, 0.2); border-bottom: none; /* La propiedad flex indica en su orden flex-grow, flex-shrink y flex-basis. Establecida en auto indica que los ítems pueden crecer o reducirse en igual proporción para ocupar el espacio disponible. */

flex: auto; } } Las instrucciones que se han dado a la condición del punto de ruptura son las siguientes: ●

El menú debe cambiar a horizontal: flex-direction: row



Los textos de las opciones se centran cada uno en el espacio que ocupan: text-align: center



A la derecha de cada opción se mostrará un borde: border-right: 2px solid rgba(0, 0, 0, 0.2); Sin embargo la última opción no tendrá bordes porque antes se especificó de manera general que: .menu li:last-child { border: none; }



El ancho de las opciones puede crecer o reducirse cuando se cambie de tamaño, para ocupar el espacio que le corresponde por igual a cada una: flex: auto. Así, el resultado que se obtiene en pantallas de más de 767 píxeles es le siguiente:

Veamos un poco más en detalle la propiedad flex aplicada a los ítems del menú cuando están dispuestos de forma horizontal: En realidad la propiedad flex de los hijos de un contenedor sirve de atajo para especificar valores a tres propiedades de dichos ítems: flex-grow, flex-shrink y flex-basis. Veamos en qué consisten: flex-grow

0|#

Factor de crecimiento del ítem respecto al resto. El valor por defecto de flex-grow: 0, lo que quiere decir que el elemento no puede crecer. Si todos los ítems de una caja tienen el mismo valor de flex-grow, por ejemplo flexgrow:1; quiere decir que todos los ítems tienen que crecer en igual proporción, hasta ocupar todo el espacio disponible. Si a uno de ellos, se le indica 2, dicho ítem será más grande que los anteriores.

flex-shrink

1|#

Factor de reducción del ítem respecto al resto. El valor por defecto de flexshrink: 1, lo que quiere decir que los elementos de una caja flex disminuirán en igual proporción, por tal de acomodarse dentro de la caja.

flex-basis

0 | content

Especifica el valor inicial del tamaño principal de un elemento flex, antes de que esté redimensionado con flex-grow o flex-shrink. El tamaño principal de un elemento flex es la anchura en contenedores horizontales, cuando flex-direction es row; o la altura en contenedores verticales, cuando flexdirection es column. Vea aquí los tipos de valores aceptados. Ejemplo: flex: 1 3 35%;

En conclusión la instrucción flex: auto, es equivalente a: flex-grow: 1; flex-shirink: 1; flex-basis: auto; Al llegar aquí debería probar que efectivamente en dispositivos pequeños el menú se dispone verticalmente y en dispositivos grandes, horizontalmente. Lo que se quiere ahora es que el menú aparezca siempre desplegado en dispositivos grandes y oculto, pero con la posibilidad de desplegarse, en dispositivos pequeños. Algo así como lo que se muestra enseguida:

Despliegue en dispositivos grandes

Despliegue inicial en dispositivos pequeños

En primer lugar se agregará el div que muestra la opción menú en dispositivos pequeños, por lo tanto el código HTML queda finalmente así:

Interfaces 2020-2

Menú Inicio Acerca de Productos Servicios Clientes Contáctenos

Puesto que la técnica responsive utilizada es “mobile first”, para que el menú no se despliegue inicialmente en dispositivos pequeños, simplemente se oculta (display: none:): .menu { padding-left: 0; margin-top: 0; margin-bottom: 0; list-style: none; background: steelblue; display: none; } En lugar del menú se muestra el nuevo elemento Menú, con estilos apropiados: #toggle-menu { background: rgb(48, 105, 151); line-height: 2.9; color: #ffffff; padding-left: 1em; font-weight: bold; font-size: 0.9em; cursor: pointer; } Sin embargo este botón no se debe mostrar para dispositivos grandes, en su lugar debe mostrarse el menú: @media screen and (min-width: 768px) {

#toggle-menu { display: none; } .menu { display: flex; flex-direction: row; } ... } Puesto que las opciones del menú no se muestran inicialmente en los dispositivos pequeños es necesario indicar que cuando se pulse clic sobre “Menú”, la lista de opciones pase de tener asignada la propiedad display: none, a tener asignada la siguiente clase: .flex-column { display: flex; flex-direction: column; } En conclusión, la hoja de estilos completa para este menú es como sigue: body { margin: 0; padding: 0; font-family: sans-serif; } .menu { padding-left: 0; margin-top: 0; margin-bottom: 0; list-style: none; background: steelblue; display: none; /* Inicialmente menú oculto en pantallas pequeñas */ } .menu li { border-bottom: 2px solid rgba(0, 0, 0, 0.2); }

.menu li:last-child { border: none; }

.menu a { color: #eeeeee; text-decoration: none; display: block; padding: 1em; font-weight: bold; font-size: 0.9em; } .menu a:hover { background: rgba(0, 0, 0, 0.2); } #toggle-menu { background: rgb(48, 105, 151); line-height: 2.9; color: #ffffff; padding-left: 1em; font-weight: bold; font-size: 0.9em; cursor: pointer; } /* Inicialmente esta clase no se aplica. Sólo si "Menú" está visible y se pulsa sobre dicho div, se conmuta entre asignar la clase o quitarla para hacer que el menú vertical sea visible o no */ .flex-column { display: flex; flex-direction: column; } /* A partir 768 el menú será horizontal */ @media screen and (min-width: 768px) { #toggle-menu { display: none; } .menu { display: flex; flex-direction: row; } .menu > li { text-align: center; border-right: 2px solid rgba(0, 0, 0, 0.2); border-bottom: none;

/* Establecida en auto indica que los items pueden crecer o reducirse para ocupar el espacio disponible. Asigna flex-grow: 1, flex-shrink: 1 y flex-basis: auto */ flex: auto; } } Si prueba hasta aquí verá que efectivamente el menú se muestra en una fila para dispositivos grandes y no es visible para dispositivos pequeños. Resta entonces hacer que cuando la pantalla sea pequeña, al pulsar clic sobre “Menú”, se despliegue u oculte la lista de opciones. Para esto, ...


Similar Free PDFs