Tabla de Contenidos

5. CSS Avanzado

En este tema vamos a explicar principalmente el layout en CSS con flexbox y grid.

Flexbox

Flex se utiliza para colocar cosas de forma horizontal o vertical.

Vamos a explicar flex con el siguiente ejemplo:

<div class="container">
  <div>Item1</div>
  <div>Item2</div> 
  <div>Item3</div>
  <div>Item4</div> 
  <div>Item5</div> 
</div>

.container {
  display:flex;
  justify-content:flex-start;
  align-content:flex-start
  align-items:flex-start;
}




Como vemos hay dos tipos de elementos, el contenedor y los items que hay centro. El contenedor siempre tendrá la siguiente línea display:flex;.

Ahora veremos algunas de las opciones que permite flex.

flex-direction

Para hacer que los item se muestren de forma vertical u horizontal. Sus valores son

flex-wrap

Para hacer que si no caben en una línea, se pasen a la línea siguiente.

justify-content

Es como se distribuye el espacio sobrante en horizontal. Hacía la izquierda, derecha, ocupando todo el espacio, etc, etc.

Alguno de sus posibles valores son:

align-content

Es como se distribuye el espacio sobrante en vertical. Hacía arriba, abajo, ocupando todo el espacio, etc, etc.

Alguno de sus posibles valores son:

align-items

Si los elementos se justifican hacía arriba, abajo, ocupando todo el espacio, etc, etc.

Alguno de sus posibles valores son:

flex-grow

Permite que crezca el item si hay mas espacio.

Se usa entro de los "hijos"

flex

Es poner en una misma linea flex-grow, flex-shrink y flex-basis

Se usa entro de los "hijos"

Mas información en:

margin y auto

Una utilidad de flexbox es hacer menús pero a veces queremos mover algunos item hacia la derecha.El truco para hacerlo es usar margin-left: auto; En los siguientes páginas se indica como hacerlos.

<div style="display:flex">
  <div >Item1</div>
  <div >Item2</div>
  <div >Item3</div>  
  <div style="margin-left:auto">Item4</div> 
  <div >Item5</div> 
</div>

En el ejemplo, los items 1 , 2 y 3 estarán pegados a la izquierda y los items 4 y 5 estarán pegados a la derecha.

Mas información en:

Para aprender flexbox puede jugar a Flexbox Froggy - A game for learning CSS flexbox

Grid

Grid permite colocar cosas en dos dimensiones. Como si fuera una rejilla (un grid en inglés).

.container {
	display:grid;
  	grid-template-columns: 1fr 1fr 2fr;
  	grid-template-rows: 1fr 2fr;
}

.item {
	border:1px solid red;
}
<div class="container">
  <div class="item">Item1</div>
  <div class="item">Item2</div>
  <div class="item">Item3</div>  
  <div class="item">Item4</div> 
  <div class="item">Item5</div> 
  <div class="item">Item6</div>   
</div>

grid-template-columns

Indica el tamaño de cada columna

Las unidades pueden ser:

Ejemplos:

repeat

Si hay muchas columnas y todas del mismo tamaño en vez de

.container {
  grid-template-columns: 1fr 1fr  1fr  1fr  1fr  1fr;
} 
 
se puede escribir:
  grid-template-columns: repeat(6, 1fr);



o en vez de

.container {
  grid-template-columns: 100px 100px 100px 100px 100px 100px ;
} 
 
se puede escribir:
  grid-template-columns: repeat(6, 100px );

auto-fit

Si el tamaño de las columnas es fijo se puede hacer lo siguiente para no especificar el número de columnas y que sea variable según el ancho de la ventana:

.container {
  grid-template-columns: repeat(auto-fit, 100px );
} 
 
En ese caso ocupará todas las filas que sea necesario para poder poner ponerlo todo. Es una forma de hacer las cosas responsivas.



Por último se puede usar la función minmax de CSS para hacerlo de la siguiente forma

.container {
  grid-template-columns: repeat( auto-fit, minmax( 100px, 1fr ) );
}

Que hará que cada columna ocupe como mínimo 100px y si hay mas espacio crecerá hasta ocupar todo. Pero se crearán tantas filas como sea necesario. Mas información en repeat,auto-fit,minmax,1fr y en MinMax in CSS Grid — 3/3 Flexibility

La función minmax es similar a las propiedades css de:
  • min-width
  • min-height
  • max-width
  • max-height

Ejemplo

Veamos ahora un ejemplo de la diferencia entre repeat(4,1fr) , repeat(auto-fit,100px) y repeat( auto-fit, minmax( 100px, 1fr ) )

.container {
    display:grid;
    grid-template-columns: repeat(4,1fr);
}
.container2 {
    display:grid;
    grid-template-columns: repeat(auto-fit,100px);	
}
.container3 {
    display:grid;
    grid-template-columns: repeat( auto-fit, minmax( 100px, 1fr ) );
}  
.item {
    border:1px solid red;
}
.item2 {
    border:1px solid green;
}
.item3 {
    border:1px solid blue;	
}

  <p>repeat(4,1fr)</p>
<div class="container">
  <div class="item">Item1</div>
  <div class="item">Item2</div>
  <div class="item">Item3</div>  
  <div class="item">Item4</div> 
  <div class="item">Item5</div> 
  <div class="item">Item6</div> 
  <div class="item">Item7</div>
  <div class="item">Item8</div>  
</div>
<br>
<p>repeat(auto-fit,100px)</p>
<div class="container2">
  <div class="item2">Item1</div>
  <div class="item2">Item2</div>
  <div class="item2">Item3</div>  
  <div class="item2">Item4</div> 
  <div class="item2">Item5</div> 
  <div class="item2">Item6</div> 
  <div class="item2">Item7</div>
  <div class="item2">Item8</div>  
</div>
<br>
<p>repeat( auto-fit, minmax( 100px, 1fr ) )</p>
<div class="container3">
  <div class="item3">Item1</div>
  <div class="item3">Item2</div>
  <div class="item3">Item3</div>  
  <div class="item3">Item4</div> 
  <div class="item3">Item5</div> 
  <div class="item3">Item6</div> 
  <div class="item3">Item7</div>
  <div class="item3">Item8</div>  
</div>

grid-template-rows

Es lo mismo que grid-template-columns pero referido a las filas.

gap

Indica la separación entre cada una de las celdas del grid.

.container {
  gap: 15px 10px;
}

La propiedad gap también funciona con flex

Bloque de Layout por columnas

Ejemplo de Layout con BEM por columnas.

.l-columns {
  display: grid;
  grid-template-columns: repeat(1, 1fr);
}

.l-columns--2 {
  grid-template-columns: repeat(2, 1fr);
}
.l-columns--3 {
  grid-template-columns: repeat(3, 1fr);
}
.l-columns--4 {
  grid-template-columns: repeat(4, 1fr);
}



<div class="l-columns l-columns--3">
  <div>
    <h2>Column A</h2>
  </div>
  <div >
    <h2>Column B</h2>
  </div>
  <div>
    <h2>Column C</h2>
  </div>
  <div>
    <h2>Column D</h2>
  </div>
  <div>
    <h2>Column E</h2>
  </div>
  <div>
    <h2>Column F</h2>
  </div>
</div>

span

Se puede hacer que un elemento ocupe más de una columna con grid-column: span x; siendo x el número de columnas que quieres que se expanda.

.l-columns {
  display: grid;
}

.l-columns--4{
  grid-template-columns: repeat(4, 1fr);
}  

.l-columns__area {

}
.l-columns__area--span-2 {
  grid-column: span 2;
}

  <div class="l-columns l-columns--4">
    <div class="l-columns__area"></div>
    <div class="l-columns__area"></div>
    <div class="l-columns__area"></div>
    <div class="l-columns__area"></div>
    <div class="l-columns__area"></div>
    <div class="l-columns__area l-columns__area--span-2"></div>
    <div class="l-columns__area"></div>                    
  </div>

Reglas BEM de Layout

Para hacer una clase de Layout hay que seguir las siguientes reglas:

.l-extremo {
  display:flex
  
  &__area-izquierda {
    margin-right: auto;
  }
  &__area-derecha {
    margin-left: auto;
  }  
}



.l-columns {
  display: grid;
  grid-template-columns: repeat(1, 1fr);

  @for $i from 1 to 12 {
    &--#{$i} {
      grid-template-columns: repeat($i, 1fr);
    }    
  } 
  
  &__area {
  }
}
  
  

<div class="l-extremo">
    <div class="l-extremo__area-izquierda">
        <div class="c-button">Pulsar Izquierda</div>
    </div>
    <div class="l-extremo__area-derecha">
        <div class="c-button">Pulsar Derecha</div>
    </div>    
</div>

<div class="l-extremo">
    <div class="l-extremo__area-izquierda c-button">Pulsar Izquierda</div>
    <div class="l-extremo__area-derecha c-button">Pulsar Derecha</div>    
</div>

Artículos en general sobre Layout

Ejercicios

Ejercicio 1

Modifica la página del tema anterior para usar ahora lo nuevo de grid y flex cuando sea necesario.