miércoles, 2 de noviembre de 2022

Entendiendo flexbox definitivamente

 


Esta es la documentación del minicurso para YouTube, Flexbox total.

Lo primero que vamos a hacer es crear una carpeta que llamaremos flexbox y en ella crearemos tres archivos, index.html, style.css y scripts.js por si llagamos a necesitar algún script de javascript:

Index.html

Desde del index vincularemos nuestra hoja de estilos externa style.ccs y nuestros scripts:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>FLEXBOX</title>
</head>
<body>
    <h1>CURSO FLEXBOX DESDE CERO</h1>
 
<script src="scripts.js"></script>  
</body>
</html>

 

En style.css haremos un sencillo reset:

html {
    box-sizing: border-box;
    font-size: 16px;
  }
 
  *, *:before, *:after {
    box-sizing: inherit;
  }
 
  body, h1, h2, h3, h4, h5, h6, p, ol, ul {
    margin: 0;
    padding: 0;
    font-weight: normal;
  }
 
  ol, ul {
    list-style: none;
  }
 
  img {
    max-width: 100%;
    height: auto;
  }

 

Y dejaremos preparado nuestro documento javascript para eventuales scripts:

scripts.js:

//Variables y constantes
 
//Funciones
 
//Inicializaciones

 

En nuestro index.html, vamos a crear una estructura muy sencilla que constará de una div contenedora a la llamaremos container y que contendrá cuatro div a las que daremos las clases; item-1, item-2…item-4:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>FLEXBOX</title>
</head>
<body>
    <h1>CURSO FLEXBOX DESDE CERO</h1>
    <br>
    <br>
 
    <div class="container">
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
    </div>
 
<script src="scripts.js"></script>  
</body>
</html>

Si abrimos nuestro navegador ahora mismo tendremos lo siguiente:


CONVIERTIENDO EL CONTENEDOR EN FLEXBOX:

Para convertir nuestra div contenedora en flexbox, lo único que necesitamos es darle la propiedad css:

  /* estilos */
 
  .container {
      display: flex
  }

 

Solo con añadir esta propiedad, veremos el siguiente cambio en los ítems:



Como puedes ver se han alineado en la horizontal. Si inspeccionamos en la consola nuestra div container, podremos ver una pequeña etiqueta donde indica que esa div es flex:


Más abajo en la pestaña estilos podremos ver un  pequeño recuadro al lado del cess display flex y si haceos click en él podremos ver de forma gráfica muchas delas características que flexbox nos ofrece:



Si hacemos click sobre ellas veremos como la distribución va cambiando, pero nostros vamos a hacerlo a nivel de código para aprender flex.

 

IMPORTANTE. Cuando aplicamos la propiedad flex, esta se aplica sólo a los hijos directos de ese contenedor, es decir que en nuestra div container, flex se está aplicando solo a los ítems:

    <div class="container">
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
    </div>

 

Si dentro de algún item queremos trabajar con flex, debemos aplicarle la propiedad flex al item también. Y así sucesivamente.

PROPRIEDADES.

1 Flex direction

Nos permite definir cómo se van a mostrar los elementos dentro del contenedor.

·        En fila : row

o   Row-reverse: invierte el orden de los ítems en la fila

·        En columna (aplilados): columna

o   Column-reverse: invierte el orden de los elementos en la columna

El valor por defecto es row.

  .container {
      display: flex;
      flex-direction: column;
  }


  .container {
      display: flex;
      flex-direction: column-reverse;
  }


  .container {
      display: flex;
      flex-direction: row;
  }

  .container {
      display: flex;
      flex-direction: row-reverse;
  }

Existen más propiedades para flex-direction, que aplicaremos cuando tengamos varias capas de flex.

2 flex-wrap

Para ilustrar la siguiente propiedad vamos a dar cierto cuerpo a nuestros ítems de forma que ocupuen más espacio y algo de color para poder verlos de manera correcta:

  .container {
      display: flex;
      min-height: 100px;
      background-color: #CCC;
 
  }
 
  .item-1 ,.item-2 ,.item-3 ,.item-4 {
    width: 200px;
    min-height: 50px;
    border: 1px solid blueviolet;
  }

Flex-wrap nos permite acomodar todos los elementos en una misma línea, o no:

Nowrap: si vamos añadiendo ítems a nuestra div contenedora, estos se irán haciendo más pequeños para dejar espacio a los nuevos ítems, sin crear una nueva fila

Wrap: Si vamos añadiendo ítems, cuando el espacio en la línea no sea suficiente para contenerlos se creará una nueva:

Wrap-reverse: invierte el orden en el que se crean las filas en caso de desbordamiento.

Añadimos 4 items más a nuestra div:

 

 

    <div class="container">
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
    </div>

 

Nowrap:

  .container {
      display: flex;
      flex-wrap: nowrap;
      min-height: 100px;
      background-color: #CCC;

 Wrap:

  .container {
      display: flex;
      flex-wrap: wrap;
      min-height: 100px;
      background-color: #CCC;
  }


Wrap-reverse:

Camio la nomenclatura a los ítems, para poder identificarlos mejor:

    <div class="container">
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
        <div class="item-1">item 5</div>
        <div class="item-2">item 6</div>
        <div class="item-3">item 7</div>
        <div class="item-4">item 8</div>
    </div>


Wrap-reverse:

  .container {
      display: flex;
      flex-wrap: wrap-reverse;
      min-height: 100px;
      background-color: #CCC;
  }



3 Flex-flow

Esta es una propiedad para simplificar el uso de flex-direction y flex-flow, esta es flex-flow. Que nos permite especificar ambas propiedades en una sola línea:

.container {
flex-flow: [ flex-direction ] [ flex-wrap ];
}

  .container {
      display: flex;
      flex-flow: row wrap;
      background-color: #CCC;
  }


4 Propiedad justify-content

ALINEACIÓN DE ELEMENTOS EN EL MAIN AXIS

flex-start: alineamos los ítems a la izquierda:

  .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: flex-start;
      background-color: #CCC;
  }

flex-end: alineamos a la derecha:

  .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: flex-end;
      background-color: #CCC;
  }


center: alineamos al centro de forma horizontal:

  .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: space-between;
      background-color: #CCC;
  }


space-arround: Alineamos de forma uniforme los elementos, se añade un espacio entre los elementos.

  .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: space-around;
      background-color: #CCC;
  }

space-evenly: Alineamos de forma uniforme los elementos, se reparte de forma equitativa el espacio disponible.

  .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: space-evenly;
      background-color: #CCC;
  }


5 Propiedad align-items

ALINEACIÓN DE ELEMENTOS EN EL CROSS AXIS




El valor por defecto de la propiedad align-items es flex-start.

Para ejemplificar estas propiedades voy a darle más altura al contenedor y una altura máxima los ítems, también eliminaré 4 items ya que para los ejemplos con 4 items se verá mejor:

  .container {
      display: flex;
      flex-flow: row wrap;
      height: 70vh;
      justify-content: space-evenly;
      background-color: #CCC;
  }
 
  .item-1 ,.item-2 ,.item-3 ,.item-4 {
    width: 200px;
    max-height: 50px;
    border: 1px solid blueviolet;
  


flex-start: los elementos se alinean verticalmente en la parte de arriba:

  .container {
      display: flex;
      flex-flow: row wrap;
      align-items: flex-start;
      height: 70vh;
      justify-content: space-evenly;
      background-color: #CCC;
  }

 

flex-end: los elementos se alinean verticalmente en la parte de abajo:

  .container {
      display: flex;
      flex-flow: row wrap;
      align-items: flex-end;
      height: 70vh;
      justify-content: space-evenly;
      background-color: #CCC;
  }



center: se alinean en la parte central:

  .container {
      display: flex;
      flex-flow: row wrap;
      align-items: center;
      height: 70vh;
      justify-content: space-evenly;
      background-color: #CCC;
  }


strectch: Logramos que los elementos ocupen todo el alto disponible: (elimina el max-width de los ítems para poder ver el efecto)

  .container {
      display: flex;
      flex-flow: row wrap;
      align-items: stretch;
      height: 70vh;
      justify-content: space-evenly;
      background-color: #CCC;
  }
 




Baseline: es una propiedad para controlar la línea donde arrancan nuestros ítems en la horizontal sea la misma para todos los ítems. En este caso si le damos a align-items la propiedad baseline, no cambiará nada, pero imaginemos que tenemos uno de nuestros ítems, a un nivel más bajo que los demás, por ejemplo si le aplico un margin-top de 30px, y que tenemos el align-items a flex-start:

  .container {
      display: flex;
      flex-flow: row wrap;
      align-items: flex-start;
      height: 70vh;
      justify-content: space-evenly;
      background-color: #CCC;
  }
 
  .item-1 ,.item-2 ,.item-3 ,.item-4 {
    width: 200px;
    border: 1px solid blueviolet;
  }
  .item-2 {
    margin-top: 30px;
  }


Si yo cambio align-items a baseline:


6 Propiedad align-content

Esta propiedad trabaja sobre el eje Y o cross axis. Para que pueda funcionar deben darse dos requerimientos que se deben cumplir:

·        El primero es que nuestro flex-flow sea wrap o wrap-reverse

·        El segundo es que los ítems ya hayan desbordado y exista mas de una línea.

Con estas características podemos asignar los siguientes valores a align-content:

Vamos a añadir 4 ítems más, de nuevo a nuestro contenedor:

    <div class="container">
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
        <div class="item-1">item 5</div>
        <div class="item-2">item 6</div>
        <div class="item-3">item 7</div>
        <div class="item-4">item 8</div>
    </div>

 También haremos nuestro contenedor más alto para poder ver los resultados:

      min-height: 50vh;

Flex-start: Alineamos todo a la parte superior:

  .container {
      display: flex;
      align-content: flex-start;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;

Flex-end: alineamos a la parte inferior:           

  .container {
      display: flex;
      align-content: flex-end;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }

Flex-center: alineamos al centro:

  .container {
      display: flex;
      align-content: center;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }


Stretch: ocupan todo el alto disponible de cada línea

  .container {
      display: flex;
      align-content: stretch;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }


Space-between: distribuidos de forma equitativa sin dejar espacio sen los lados (top y bottom)

  .container {
      display: flex;
      align-content: space-between;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }


Space-arround: distribuidos de forma equitativa dejando espacio entre top y bottom

  .container {
      display: flex;
      align-content: space-around;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }


 

7 Propiedad Gap

En los últimos navegadores modernos tenemos disponible ya la propiedad Gap, que nos permite poder añadir espacio entre los elementos o ítems de nuestro contenedor.

Volvamos a unestado inicial de nuestro ejemplo:

  /* estilos */
 
  .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }
 
  .item-1 ,.item-2 ,.item-3 ,.item-4 {
    width: 200px;
    border: 1px solid blueviolet;
  }


Si ahora le añado un gap de 10px:
  .container {
      display: flex;
      gap: 10px;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }


Vemos como nos agrega esos 10px entre ítems, pero no a los lados.

8. APLICANDO PROPIEDADES A ITEMS POR SEPARADO

Una vez que ya conocemos las principales propiedades que podemos aplicar a un contenedor flex-box en su conjunto, veamos algunas propiedades que pueden ser aplicadas a los ítems de un contenedor de forma individual.

8.1 Propiedad order

Con order podemos posicionar los elementos con un orden específico que nostros le indiquemos. Cunando en el html creamos elementos estos se renderizan ene le orden que ha sido creados, con order podmos variar ese orden de renderizado, la primera posición empieza siempre en 0.


    <div class="container">
        <div class="item-1">item 1</div>
        <div class="item-2">item 2</div>
        <div class="item-3">item 3</div>
        <div class="item-4">item 4</div>
    </div>

8.2 Propiedad flex-grow

Flex-grow nos permite definir una unidad relativa al tamaño de nuestros elementos dentro de nuestro contenedor, para que ese elemento crezca.

Si no se define esta propiedad en ninguno de los elementos, todos intentarán adquirir el ancho o el alto respecto de su propio contenido, imagen, vídeo, input etc.

Si especificamos flex-grow a sólo uno d ellos elementos, flexbox intentará asignarle a este elemento el mayor espacio posible de entre todos.

  .container {
      display: flex;
      align-content: space-around;
      min-height: 50vh;
      flex-flow: row wrap;
      justify-content: center;
      background-color: #CCC;
  }
 
  .item-1 ,.item-2 ,.item-3 ,.item-4 {
    width: 200px;
    border: 1px solid blueviolet;
  }
 
  .item-1 {
    flex-grow: 1;
  }



  .item-1 {
    flex-grow: 1;
  }
  .item-4 {
    flex-grow: 2;
  }


El 1 o el 2 no son píxeles si no una unidad relativa.

Si todos los elementos tienen el mismo flex-grow se repartirán de forma equitativa dentro de nuestro contenedor.

 

 

 

8.3 Propiedad flex-shrink

Podríamos definir esta propiedad como la opuesta a flex-grow con la particularidad de que por defecto todos los elementos de un contenedor flexbox, tienen por defecto asignado el valor 1 de flex-shrink. Esto supone que cuando nuestro contenedor se contraiga todos los elementos van a intentar contraerse a la misma proporción o con el mismo ratio.

Podemos cambiar este ratio asignando a cada ítem una propieda flex-shrink distienta:
  .item-1 {
    flex-shrink: 1;
  }
  .item-2 {
    flex-shrink: 10;
 }
 .item-3{
   flex-shrink: 3;
 }
 .item-4 {
   flex-shrink: 2;
 }

 

Cada uno menguará con un ratio distinto, a pesar de que todos tienen el mismo tamaño.

8.4 Propiedad flex-basis

Esta propiedad nos permite asignar un tamaño a cada uno de nuestros elementos antes de que empiecen a ocupar el tamaño disponible del contenedor ene el que se encuentran.

Para las tresultimas propiedades tenemos una forma de simplificar la sintaxis:

.item {
flex: [ flex-grow ][ flex-shrink ][ flex-basis ]
}