09 CSS (Flex)
09 CSS (Flex)
09 CSS (Flex)
Python
Codo a Codo 4.0
CSS
Parte 5
Tradicionalmente, en CSS se ha utilizado el posicionamiento (static, relative, absolute...), los
elementos en línea o en bloque (y derivados) o los float, lo que a grandes rasgos no dejaba de ser
un sistema de creación de diseños bastante tradicional que no encaja con los retos que tenemos
hoy en día: sistemas de escritorio, dispositivos móviles, múltiples resoluciones, etc...
Flexbox es un sistema de elementos flexibles que llega con la idea de olvidar estos mecanismos y
acostumbrarnos a una mecánica más potente, limpia y personalizable, en la que los elementos
HTML se adaptan y colocan automáticamente y es más fácil personalizar los diseños. Está
especialmente diseñado para crear, mediante CSS, estructuras de una sola dimensión.
Fuente: lenguajecss.com
Flexbox | Conceptos
Para empezar a utilizar flexbox lo primero que debemos hacer es conocer algunos de los
elementos básicos de este nuevo esquema, que son los siguientes:
• Contenedor: Es el elemento padre que tendrá en su interior cada uno de los ítems
flexibles. Al contrario que muchas otras estructuras CSS, por norma general, en Flex
establecemos las propiedades al elemento padre.
o Eje principal: Los contenedores flexibles tendrán una orientación principal específica.
Por defecto, es en horizontal (en fila).
o Eje secundario: De la misma forma, los contenedores flexibles tendrán una
orientación secundaria, perpendicular a la principal. Si la principal es en horizontal, la
secundaria será en vertical, y viceversa.
• Ítem: Cada uno de los hijos flexibles que tendrá el contenedor en su interior.
Imaginemos el siguiente escenario:
Mediante la propiedad flex-direction podemos modificar la dirección del eje principal del
contenedor para que se oriente en horizontal (por defecto) o en vertical. Además, también
podemos incluir el sufijo -reverse para indicar que coloque los ítems en orden inverso.
Esto nos permite tener un control muy alto sobre el orden de los elementos en una página.
Veamos la aplicación de estas propiedades sobre el ejemplo anterior, para modificar el flujo
del eje principal del contenedor:
.container { flex-direction:
background: steelblue;
display: flex; row
flex-direction: column;
}
row-
reverse
.item {
background: grey;
}
column-
column reverse
Por otro lado, existe otra propiedad llamada flex-wrap con la que podemos especificar el
comportamiento del contenedor respecto a evitar que se desborde (nowrap, valor por defecto) o
permitir que lo haga, en cuyo caso, estaríamos hablando de un contenedor flexbox multilinea.
Teniendo en cuenta estos valores de la propiedad flex-wrap, podemos conseguir cosas como
la siguiente:
.container {
background: steelblue;
display: flex;
width: 200px;
flex-wrap: wrap; /* Comportamiento por defecto: nowrap */
}
.item {
background: grey;
width: 50%;
}
En el caso de especificar nowrap (u omitir la propiedad flex-wrap) en el contenedor, los 3 ítems
se mostrarían en una misma línea del contenedor. En ese caso, cada ítem debería tener un 50%
de ancho (o sea, 100px de los 200px del contenedor). Un tamaño de 100px por ítem, sumaría un
total de 300px, que no cabrían en el contenedor de 200px, por lo que flexbox reajusta los ítems
flexibles para que quepan todos en la misma línea, manteniendo las mismas proporciones.
Sin embargo, si especificamos wrap en la propiedad flex-wrap, lo que permitimos es que el
contenedor se pueda desbordar, pasando a ser un contenedor multilínea, que mostraría el ítem
1 y 2 en la primera línea (con un tamaño de 100px cada uno) y el ítem 3 en la línea siguiente,
dejando un espacio libre para un posible ítem 4.
flex-wrap:
nowrap
wrap-
wrap
reverse
Atajo: Dirección de los ejes
Recuerda que existe una propiedad de atajo (short-hand) llamada flex-flow, con la que
podemos resumir los valores de las propiedades flex-direction y flex-wrap, especificándolas
en una sola propiedad y ahorrándonos utilizar las propiedades concretas:
.container {
/* flex-flow: <flex-direction> <flex-wrap>; */
flex-flow: row wrap;
}
Flexbox | Propiedades de alineación
Ahora que tenemos un control básico del contenedor de estos ítems flexibles, necesitamos
conocer las propiedades existentes dentro de flexbox para disponer los ítems dependiendo
de nuestro objetivo. Vamos a echar un vistazo a 4 propiedades interesantes para ello, la
primera de ellas actúa en el eje principal, mientras que el resto en el eje secundario:
De esta pequeña lista, hay que centrarse en primer lugar en la primera y la tercera propiedad,
que son las más importantes (las otras dos son casos particulares que explicaremos más
adelante):
• justify-content: Se utiliza para alinear los ítems del eje principal (por defecto, el horizontal).
• align-items: Usada para alinear los ítems del eje secundario (por defecto, el vertical).
Sobre el eje principal
La primera propiedad, justify-content, sirve para colocar los ítems de un contenedor
mediante una disposición concreta a lo largo del eje principal:
Con cada uno de estos valores, modificaremos la disposición de los ítems del contenedor
donde se aplica, pasando a colocarse como se ve en el siguiente ejemplo (nótense los
números para observar el orden de cada ítem):
justify-content:
flex-start space-between
flex-end space-around
center space-evenly
Una vez entendido este caso, debemos atender a la propiedad align-content, que es un caso
particular del anterior. Nos servirá cuando estemos tratando con un contenedor flex multilinea,
que es un contenedor en el que los ítems no caben en el ancho disponible, y por lo tanto, el eje
principal se divide en múltiples líneas (por ejemplo, usando flex-wrap: wrap).
De esta forma, align-content servirá para alinear cada una de las líneas del contenedor
multilinea. Los valores que puede tomar son los siguientes:
Con estos valores, vemos como cambiamos la disposición en vertical (porque partimos de un
ejemplo en el que estamos utilizando flex-direction: row, y el eje principal es horizontal) de
los ítems que están dentro de un contenedor multilinea.
En el ejemplo siguiente, veremos que al indicar un contenedor de 200 píxels de alto con
ítems de 50px de alto y un flex-wrap establecido para tener contenedores multilinea,
podemos utilizar la propiedad align-content para alinear los ítems de forma vertical de modo
que se queden en la zona inferior del contenedor:
.container { align-content:
background: #CCC;
display: flex;
width: 200px; space-between
height: 200px;
flex-start
flex-wrap: wrap;
align-content: flex-end; flex-end
}
space-around
.item {
background: #777;
width: 50%;
height: 50px;
}
center stretch
Sobre el eje secundario
La otra propiedad importante de este apartado es align-items, que se encarga de alinear los
ítems en el eje secundario del contenedor. Hay que tener cuidado de no confundir align-
content con align-items, puesto que el primero actúa sobre cada una de las líneas de un
contenedor multilinea (no tiene efecto sobre contenedores de una sola línea), mientras que
align-items lo hace sobre la línea actual. Los valores que puede tomar son los siguientes:
.container {
display: flex;
place-content: flex-start flex-end;
/* Equivalente a... */
align-content: flex-start;
justify-content: flex-end;
}
Flexbox | Propiedades de hijos
A excepción de la propiedad align-self, todas las propiedades que hemos visto hasta ahora se
aplican sobre el elemento contenedor. Las siguientes propiedades, sin embargo, se aplican
sobre los ítems hijos:
En primer lugar, tenemos la propiedad flex-grow para indicar el factor de crecimiento de los
ítems en el caso de que no tengan un ancho específico. Por ejemplo, si con flex-grow
indicamos un valor de 1 a todos sus ítems, tendrían el mismo tamaño cada uno de ellos. Pero si
colocamos un valor de 1 a todos los elementos, salvo a uno de ellos, que le indicamos 2, ese ítem
será más grande que los anteriores. Los ítems a los que no se le especifique ningún valor,
tendrán por defecto valor de 0.
En segundo lugar, tenemos la propiedad flex-shrink que es la opuesta a flex-grow. Mientras
que la anterior indica un factor de crecimiento, flex-shrink hace justo lo contrario, aplica un
factor de decrecimiento. De esta forma, los ítems que tengan un valor numérico más grande,
serán más pequeños, mientras que los que tengan un valor numérico más pequeño serán más
grandes, justo al contrario de como funciona la propiedad flex-grow.
Por último, tenemos la propiedad flex-basis, que define el tamaño por defecto (de base) que
tendrán los ítems antes de aplicarle la distribución de espacio. Generalmente, se aplica un
tamaño (unidades, porcentajes, etc...), pero también se puede aplicar la palabra clave content
que ajusta automáticamente el tamaño al contenido del ítem, que es su valor por defecto.
Ejemplo interactivo sobre estas primeras 3 propiedades: clic aquí.
.item {
/* flex: <flex-grow> <flex-shrink> <flex-basis> */
flex: 1 3 35%;
}
Huecos (gaps)
Existen dos propiedades de flexbox que han surgido recientemente: row-gap y column-gap.
Dichas propiedades, permiten establecer el tamaño de un «hueco» entre ítems desde el
elemento padre contenedor, y sin necesidad de estar utilizando padding o margin en los
elementos hijos.
Ten en cuenta que sólo una de las dos propiedades tendrá efecto, dependiendo de si la
propiedad flex-direction está establecida en column o en row. Eso sí, es posible usar ambas si
tenemos la propiedad flex-wrap definida a wrap y, por lo tanto, disponemos de multicolumnas
flexbox. Ver ejemplo interactivo aquí.
Atajo: Huecos
En el caso de que queramos utilizar una propiedad de atajo para los huecos, podemos utilizar
la propiedad gap. Eso sí, ten en cuenta que estas propiedades de huecos en flexbox, aún no
tienen un soporte demasiado extendido entre navegadores:
.container {
/* gap: <row> <column> */
gap: 4px 8px;
Material multimedia
• Flexbox 1 – Introducción
• Flexbox 2 - Propiedades de elementos hijos
• Flexbox 3 - Sitio Web responsive (ejemplo explicado)
Ejemplos:
• flexbox1 (.html) y (.css)
• flexbox-responsive (.html) y (.css)