Conceptos Básicos de flexbox
El Módulo de Caja Flexible, comúnmente llamado flexbox, fue diseñado como un modelo unidimensional de layout, y como un método que pueda ayudar a distribuir el espacio entre los Ãtems de una interfaz y mejorar las capacidades de alineación. Este artÃculo hace un repaso de las principales caracterÃsticas de flexbox, las que exploraremos con mayor detalle en el resto de estas guÃas.
Cuando describimos a flexbox como unidimensional destacamos el hecho que flexbox maneja el layout en una sola dimensión a la vez â ya sea como fila o como columna. Esto contrasta con el modelo bidimensional del Grid Layout de CSS, el cual controla columnas y filas a la vez.
Los dos ejes de flexbox
Cuando trabajamos con flexbox necesitamos pensar en términos de dos ejes â el eje principal y el eje cruzado. El eje principal está definido por la propiedad flex-direction, y el eje cruzado es perpendicular a este. Todo lo que hacemos con flexbox está referido a estos dos ejes, por lo que vale la pena entender cómo trabajan desde el principio.
El eje principal
El eje principal está definido por flex-direction, que posee cuatro posibles valores:
rowrow-reversecolumncolumn-reverse
Si elegimos row o row-reverse, el eje principal correrá a lo largo de la fila según la dirección de la lÃnea .
Al elegir column o column-reverse el eje principal correrá desde el borde superior de la página hasta el final â según la dirección del bloque.
El eje cruzado
El eje cruzado va perpendicular al eje principal, y por lo tanto si flex-direction (del eje principal) es row o row-reverse el eje cruzado irá por las columnas.
Si el eje principal es column o column-reverse entonces el eje cruzado corre a lo largo de las filas.
Entender cuál eje es cuál es importante cuando empezamos a mirar la alineación y justificación flexible de los Ãtems; flexbox posee propiedades que permiten alinear y justificar el contenido sobre un eje o el otro.
LÃneas de inicio y de fin
Otra área vital de entendimiento es cómo flexbox no hace suposiciones sobre la manera de escribir del documento. En el pasado, CSS estaba muy inclinado hacia el modo de escritura horizontal y de izquierda a derecha. Los métodos modernos de layout acogen la totalidad de modos de escritura asà que no es necesario asumir que una lÃnea de texto empezará arriba del documento y correrá de izquierda a derecha, con nuevas lÃneas dispuestas una abajo de la otra.
Puede leer más acerca de la relación que hay entre flexbox y la especificación de los Modos de Escritura en un artÃculo posterior, sin embargo la siguiente descripción deberÃa ayudar para explicar porqué no se habla de izquierda y derecha ni de arriba o abajo a la hora de describir la dirección en la que fluyen los Ãtems flex.
Si flex-direction es row y estoy trabajando en español, entonces el margen inicial del eje principal quedará a la izquierda, y el margen final a la derecha.
Si fuera a trabajar en árabe, entonces el margen inicial de mi eje principal quedarÃa a la derecha y el margen final a la izquierda.
En ambos casos el margen inicial del eje cruzado estará en el extremo superior del contenedor flex y el margen final en el extremo inferior, ya que ambos idiomas tiene un modo de escritura horizontal.
Después de un tiempo, pensar en inicial y final en vez de izquierda y derecha se hará natural, y será útil cuando interactúe con otros métodos de layout tales como el CSS Grid Layout que sigue los mismos patrones.
El contenedor flex
Un área del documento que contiene un flexbox es llamada contendedor flex. Para crear un contenedor flex, establecemos la propiedad del área del contenedor display como flex o inline-flex. Tan pronto como hacemos esto, los hijos directos de este contenedor se vuelven Ãtems flex. Como con todas las propiedades de CSS, se definen algunos valores iniciales, asà que cuando creemos un contenedor flex todos los Ãtems flex contenidos se comportarán de la siguiente manera.
- Los Ãtems se despliegan sobre una fila (la propiedad
flex-directionpor defecto esrow). - Los Ãtems empiezan desde el margen inicial sobre el eje principal.
- Los Ãtems no se ajustan en la dimensión principal, pero se pueden contraer.
- Los Ãtems se ajustarán para llenar el tamaño del eje cruzado.
- La propiedad
flex-basises definida comoauto. - La propiedad
flex-wrapes definida comonowrap.
El resultado es que todos los Ãtems se alinearán en una solo fila, usando el tamaño del contenedor como su tamaño en el eje principal. Si hay más Ãtems de los que caben en el contenedor, estos no pasarán más abajo si no que sobrepasarán el margen. Si hay Ãtems más altos que otros, todos los Ãtems serán ajustados en el eje cruzado para alcanzar al mayor.
Se puede ver en el ejercicio en vivo de abajo cómo luce. Intente editar el Ãtem o añadir Ãtems adicionales para asà probar el comportamiento inicial de flexbox.
Cambiar flex-direction
Al añadir la propiedad flex-direction en el contenedor flex nos permite cambiar la dirección de cómo los Ãtems son desplegados. Colocando flex-direction: row-reverse se mantendrá el despliegue a lo largo de la fila, sin embargo el inicio y final quedarán al revés del original.
Si cambiamos flex-direction a column el eje principal se cambiará y los Ãtems aparecerán en una columna. Colocando column-reverse las lÃneas de inicio y fin serán nuevamente puestas al revés.
El ejemplo en vivo de abajo tiene flex-direction puesto como row-reverse. Pruebe los otros valores â row, column y column-reverse â para ver qué sucede con el contenido.
Contenedores flex Multi-lÃnea con flex-wrap
Si bien flexbox es un modelo unidimensional, es posible lograr que nuestros Ãtems flex sean repartidos en varÃas lÃneas. Haciendo esto, se deberá considerar cada lÃnea como un nuevo contenedor flex. Cualquier distribución del espacio solo sucederá dentro de esa lÃnea, sin referenciar las lÃneas colaterales.
Para lograr repartirse en varias lÃneas añada la propiedad flex-wrap con el valor wrap. Cuando los Ãtems sean demasiados para desplegarlos en una lÃnea, serán repartidos en la lÃnea siguiente. El ejemplo en vivo de abajo contiene Ãtems que se les ha asignando un ancho, donde el ancho total de los Ãtems excede al del contenedor flex. Cuando flex-wrap se coloca como wrap, los Ãtems se repartirán. Al colocarlo como nowrap, el cual es el valor inicial, estos se contraerán para calzar con el contenedor ya que usan los valores iniciales de flexbox que permiten que los Ãtems se contraigan. Al usar nowrap los Ãtems podrÃan salirse del margen si estos no pudieran contraerse, o no contraerse lo suficiente para ser calzados.
La abreviatura flex-flow
Se pueden combinar las propiedades flex-direction y flex-wrap en la abreviatura flex-flow . El primer valor especificado es flex-direction y el segundo valor es flex-wrap.
En el ejemplo en vivo de abajo intente cambiar el primer valor por uno de los valores permitidos para flex-direction - row, row-reverse, column o column-reverse, y cambie también el segundo valor por wrap y nowrap.
Propiedades aplicadas a los Ãtems flex
Para obtener más control sobre los Ãtems flex podemos apuntarlos directamente. Hacemos esto a través de tres propiedades:
Daremos un breve vistazo a estas propiedades en este resumen, y en un próximo artÃculo ahondaremos sobre su comportamiento.
Antes de darle sentido a estas propiedades debemos considerar el concepto de espacio disponible. Lo que hacemos cuando cambiamos el valor de alguna de estas propiedades es cambiar la forma que se distribuye el espacio disponible entre nuestros Ãtems. Este concepto de espacio disponible es también importante cuando veamos la alineación de Ãtems.
Si tenemos tres Ãtems con un ancho de 100 pixeles en un contenedor de 500 pixeles de ancho, entonces el espacio que se necesita para colocar nuestros Ãtems es de 300 pixeles. Esto deja 200 pixeles de espacio disponible. Si no cambiamos los valores iniciales entonces flexbox colocará ese espacio después del último Ãtem.
Si en cambio quisiéramos que los Ãtems crecieran para llenar ese espacio, entonces necesitaremos un método para distribuir el espacio sobrante entre los Ãtems. Es justo lo que harán las propiedades flex que aplicaremos a dichos Ãtems.
La propiedad flex-basis
Con flex-basis se define el tamaño de un Ãtem en términos del espacio que deja como espacio disponible. El valor inicial de esta propiedad es auto â en este caso el navegador revisa si los Ãtems definen un tamaño. En el ejemplo de arriba, todos los Ãtems tienen un ancho de 100 pixeles asà que este es usado como flex-basis.
Si los Ãtems no tiene un tamaño entonces el tamaño de su contenido es usado como flex-basis. Y por eso, apenas declarado display: flex en el padre a fin de crear Ãtems flex, todos estos Ãtems se ubicaron en una sola fila y tomaron solo el espacio necesario para desplegar su contenido.
La propiedad flex-grow
Con la propiedad flex-grow definida como un entero positivo, los Ãtems flex pueden crecer en el eje principal a partir de flex-basis. Esto hará que el Ãtem se ajuste y tome todo el espacio disponible del eje, o una proporción del espacio disponible si otro Ãtem también puede crecer.
Si le damos a todos los Ãtems del ejemplo anterior un valor flex-grow de 1 entonces el espacio disponible en el contenedor flex será compartido igualitariamente entre estos Ãtems y se ajustarán para llenar el contenedor sobre el eje principal.
Podemos usar flex-grow apropiadamente para distribuir el espacio en proporciones. Si otorgamos al primer Ãtem un valor flex-grow de 2 y a los otros un valor de 1, entonces 2 partes serán dadas al primer Ãtem (100px de 200px en el caso del ejemplo de arriba) y 1 parte para cada uno de los restantes (cada uno con 50px de los 200px en total).
La propiedad flex-shrink
Asà como la propiedad flex-grow se encarga de añadir espacio sobre el eje principal, la propiedad flex-shrink controla como se contrae. Si no contamos con suficiente espacio en el contenedor para colocar los Ãtems y flex-shrink posee un valor entero positivo, el Ãtem puede contraerse a partir de flex-basis. Asà como podemos asignar diferentes valores de flex-grow con el fin que un Ãtem se expanda más rápido que otros â un Ãtem con un valor más alto de flex-shrink se contraerá más rápido que sus hermanos que poseen valores menores.
El tamaño mÃnimo del Ãtem tendrá que ser considerado cuando se determine un valor de contracción que pueda funcionar, esto significa que flex-shrink tiene el potencial de comportarse menos consistentemente que flex-grow . Por lo tanto, haremos una revisión más detallada de cómo este algoritmo trabaja en el artÃculo Controlling Ratios de los Ãtems sobre el eje principal.
Nota:
Nótese que los valores de flex-grow y flex-shrink son proporciones. TÃpicamente si pusiéramos todos los Ãtems flex: 1 1 200px y luego quisiéramos que un Ãtem creciera al doble, deberÃamos ponerlo con flex: 2 1 200px. Aunque igualmente podemos colocar flex: 10 1 200px y flex: 20 1 200px si quisiéramos.
Valores abreviados para las propiedades flex
DifÃcilmente veremos la propiedades flex-grow, flex-shrink y flex-basis usadas individualmente; si no que han sido combinadas en la abreviación flex . La abreviación flex permite establecer los tres valores en este orden: flex-grow, flex-shrink, flex-basis.
El ejemplo en vivo de más abajo permite probar los diferentes valores de la abreviación flex; recuerde que el primer valor es flex-grow. Dándole un valor positivo significa que el Ãtem puede crecer. El segundo es flex-shrink â con un valor positivo los Ãtems pueden contraerse. El valor final es flex-basis; este es el valor que los Ãtems usan como valor base para crecer y contraerse.
Hay además algunas abreviaturas de valores que cubren la mayorÃa de los casos de uso. Se ven con frecuencia utilizados en tutoriales, y en muchos casos es todo lo que necesitamos usar. Los valores predefinidos son los siguientes:
flex: initialflex: autoflex: noneflex: <positive-number>
Fijando flex: initial el Ãtem se restablece con los valores iniciales de Flexbox. Es lo mismo que flex: 0 1 auto. En este caso el valor de flex-grow is 0, asà que los Ãtems no crecerán más de su tamaño flex-basis . El valor flex-shrink es 1, asà que los Ãtems pueden contraerse si es necesario en vez de salirse de los márgenes. El valor de flex-basis es auto. Los Ãtems pueden definir un tamaño en la dimensión del eje principal, o bien obtener su tamaño por el contenido del los mismos.
Usar flex: auto es lo mismo que usar flex: 1 1 auto , es como con flex:initial pero en este caso los Ãtems pueden crecer y llenar el contendor asà como encoger si se requiere.
Al usar flex: none se crearán Ãtems flex totalmente inflexibles. Es como escribir flex: 0 0 auto. Los Ãtems no pueden ni crecer ni encoger pero serán colocados usando flexbox con flex-basis en auto.
Una abreviación que es común en tutoriales es flex: 1 o flex: 2 y más. Es como usar flex: 1 1 0. Los Ãtems pueden crecer o encoger con un flex-basis de 0.
Pruebe estas abreviaciones de valores en el ejemplo en vivo de abajo.
Alineación, justificación y distribución del espacio libre entre Ãtems
Una caracterÃstica clave de flexbox es la capacidad de alinear y justificar Ãtems sobre los ejes principal y cruzado, y distribuir el espacio entre los Ãtems flex.
align-items
La propiedad align-items alineará los Ãtems sobre el eje cruzado.
El valor inicial para esta propiedad es stretch razón por la cual los Ãtems se ajustan por defecto a la altura de aquel más alto. En efecto se ajustan para llenar el contenedor flex â el Ãtem más alto define la altura de este.
En cambio definimos align-items como flex-start para que los Ãtems se alineen al comienzo del contenedor flex, flex-end para alinearlos al final, o center para alinearlos al centro. Intente esto en el ejemplo en vivo â He definido en el contenedor flex una altura para que se aprecie que se pueden mover libremente dentro del contenedor. Vea lo que sucede si se coloca el valor align-items como:
stretchflex-startflex-endcenter
justify-content
La propiedad justify-content es usada para alinear los Ãtems en el eje principal, cuyo flex-direction define la dirección del flujo. El valor inicial es flex-start que alineará los Ãtems al inicio del margen del contenedor, pero también se podrÃa definir como flex-end para alinearlos al final, o center para alinearlos al centro.
También podemos usar space-between para tomar todo el espacio sobrante después de que los Ãtems hayan sido colocados, y distribuir de forma pareja los Ãtems para que haya un espacio equitativo entre cada Ãtem. O bien, usamos el valor space-around para crear un espacio equitativo a la derecha e izquierda de cada Ãtem.
Pruebe con los siguientes valores de justify-content en el ejemplo en vivo:
space-evenlyflex-startflex-endcenterspace-aroundspace-between
En un próximo artÃculo ahondaremos sobre estas propiedades, con el fin de obtener mejor entendimiento de cómo funcionan. Sin embargo, estos sencillos ejemplos serán útiles para la mayorÃa de los casos de uso.
Próximos pasos
Al final de este artÃculo usted deberÃa tener un entendimiento de las caracterÃsticas básicas de Flexbox. En el próximo artÃculo veremos cómo esta especificación encaja con las otras partes de CSS.