1. Web Design
  2. HTML/CSS
  3. HTML Templates

Alineación en Flexbox: Cuando usar márgenes automáticos en lugar de centrar en Flexbox

Las propiedades de alineación en Flexbox son soberbias y resuelven muchos problemas de maquetado, especialmente donde la habitual funcionalidad de "centrar verticalmente y horizontalmente" es necesaria. Sin embargo, en ocasiones cuando la alineación se hace con márgenes automáticos es más segura y más flexible. ¡Este tutorial te mostrará cuándo es mejor su aplicación!
Scroll to top

Spanish (Español) translation by Javier Salesi (you can also view the original English article)

Las propiedades de alineación en Flexbox son soberbias y resuelven muchos problemas de maquetado, especialmente donde la habitual funcionalidad de "centrar verticalmente y horizontalmente" es necesaria. Sin embargo, en ocasiones cuando la alineación se hace con márgenes automáticos es más segura y más flexible. ¡Este tutorial te mostrará cuándo es mejor su aplicación!

Empezar con Flexbox

Si estás dando tus primeros pasos en el mundo de flexbox, tenemos una serie de exhaustivos tutoriales para principiantes si quieres agilizar tu trabajo. Aprende los fundamentos de alinear, ordenar y dimensionar en flexbox ¡y estarás perfectamente preparado para más tutoriales dirigidos a los usuarios intermedios posteriormente!

El proyecto

Para esta demostración, asumiremos que estamos elaborando un sitio web minimalista para el blog de un cliente. El diseñador nos proporcionó el siguiente maquetado de página:

The page layoutThe page layoutThe page layout

Cuando se hace clic en el botón del menú, aparecerá el menú cubriendo toda la pantalla y lucirá así:

The menuThe menuThe menu

Presta atención a lo siguiente:

  • El encabezado estará fijo y permanecerá en su lugar mientras nos desplazamos hacia abajo.
  • El menú cubrirá toda la pantalla y estará fijo. Sus elementos estarán centrados vertical y horizontalmente. No obstante, si su altura total excede la altura del menú, aparecerá una barra de desplazamiento.

1. Definir el marcado HTML

Comencemos definiendo el marcado requerido:

1
<header class="page-header">
2
  <nav>
3
    <div class="page-header-inner">
4
      <a href="" class="logo">Brand</a>
5
      <button type="button" class="toggle-menu">MENU</button>
6
    </div>
7
8
    <div class="menu-wrapper">
9
      <ul>
10
        <li>
11
          <a href="">...</a>
12
        </li>
13
          
14
        <!-- more list items here -->
15
      </ul>
16
      
17
      <!-- helper buttons here -->
18
    </div>
19
  </nav>
20
</header>

Dentro del elemento nav, definiremos dos botones auxiliares que nos permitirán añadir o eliminar elementos cuando hagamos clic en ellos. Tres será el número mínimo de elementos, pero podemos agregar y eliminar elementos para hacer más clara nuestra demostración.

Helper buttons for adding or removing menu items

2. Especificar algunos estilos CSS

Esta es una parte de los estilos que utilizaremos:

1
/*CUSTOM VARIABLES HERE*/
2
3
.page-header,
4
.page-header .menu-wrapper {
5
  position: fixed;
6
  top: 0;
7
  left: 0;
8
  bottom: 0;
9
  right: 0;
10
}
11
12
.page-header .page-header-inner {
13
  display: flex;
14
  align-items: center;
15
  justify-content: space-between;
16
  height: 60px;
17
  padding: 0 20px;
18
  background: var(--beige);
19
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
20
}
21
22
.page-header .page-header-inner * {
23
  z-index: 1;
24
}
25
26
.page-header .menu-wrapper {
27
  display: none;
28
  align-items: center;
29
  justify-content: center;
30
  overflow-y: auto;
31
  background: var(--white);
32
}

Por defecto, el elemento .menu-wrapper estará oculto y recibirá display: flex tan pronto como hagamos clic en el botón conmutador.

Centrar en Flexbox

Para responder una pregunta clásica de maquetado, vamos a usar flexbox para centrar el menú tanto vertical como horizontalmente. Flexbox lo hace realmente sencillo: para alinear los elementos en el centro de la página utilizaremos justify-content: center y align-items: center.

Sin embargo, hay un problema de desbordamiento. Si añadimos suficientes elementos para hacer que aparezca la barra de desplazamiento, notaremos que los que están arriba desparecieron completamente y no podemos llegar a ellos desplazando la barra.

The align-items: center crops the itemsThe align-items: center crops the itemsThe align-items: center crops the items

Prueba el demo para verlo por tú mismo; agrega unos 20 al menú:

Please accept marketing cookies to load this content.

La palabra reservada safe

Una manera de solucionar el problema es aprovechar una nueva palabra reservada en CSS que podemos utilizar cuando alineamos elementos: safe.

Esta es su definición exacta tomada de la documentación de la Red de Desarrolladores de Mozilla (MDN por sus siglas en inglés): 

"Usada junto con una palabra reservada para alineación. Si la palabra reservada elegida significa que el elemento se desborda del contenedor causando pérdida de datos, el elemento entonces se alinea como si el modo de alineación fuera start."

Para probar este nuevo valor remplazaremos align-items: center con align-items: safe center.

En inglés llano traduciríamos los valores de safe center de la siguiente manera:

"Los elementos serán centrados verticalmente, pero si su altura excede la del contenedor flex, el modo de alineación cambiará a start. Por supuesto, para ver todos los elementos, el contenedor flex debería tener un valor apropiado de overflow-y como auto".

Desafortunadamente, al momento de escribir este artículo, no se considera una solución estable. En la práctica, tiene un soporte de navegadores muy limitado y solo funciona en las versiones recientes de Firefox.

Consulta el siguiente demo para ver cómo funciona la palabra reservada safe (asegúrate de hacerlo en Firefox):

Please accept marketing cookies to load this content.

Márgenes automáticos

Por fortuna, existe otra solución segura que podemos utilizar: aprovecharemos los márgenes automáticos. En realidad esta no es una propiedad de flexbox, de hecho ya la has utilizado mediante la regla margin: 0 auto para centrar un elemento con anchura fija dentro de un contenedor padre.

En nuestro caso, el truco es eliminar las reglas align-items: center y justify-content: center del contenedor flex y mejor aplicar margin: auto al elemento flex.

Al establecer todos los márgenes en auto, todos los lados de nuestro elemento flex tratarán de ocupar cualquier espacio disponible. Si este espacio existe, lo empujarán al centro.

Esto resuelve nuestro problema específico porque los márgenes automáticos no corten partes del elemento flex en el caso de que exceda el tamaño del contenedor.

Nota: ten en cuenta que tan pronto como usemos esta técnica, las propiedades de la alineación en flexbox no tendrán efecto.

Este es el demo relacionado:

Please accept marketing cookies to load this content.

3. Alternar menú

Finalmente, utilizaremos algo de código JavaScript sencillo para alternar el menú:

1
const toggleMenu = document.querySelector(".toggle-menu");
2
const pageHeader = document.querySelector(".page-header");
3
4
toggleMenu.addEventListener("click", function () {
5
  pageHeader.classList.toggle("menu-opened");
6
  document.body.classList.toggle("overflow-y-hidden");
7
});

Los estilos correspondientes:

1
body.overflow-y-hidden {
2
  overflow-y: hidden;
3
}
4
5
.page-header.menu-opened .page-header-inner {
6
  box-shadow: none;
7
}
8
9
.page-header.menu-opened .menu-wrapper {
10
  display: flex;
11
}

Conclusión

¡Terminamos! Hoy discutimos el uso eficaz de los márgenes automáticos para controlar la alineación de un maquetado flex. Cubrimos solo un caso específico, pero ojalá hayas captado la idea y puedas aplicarla a tus propias situaciones.

Dos cosas que tienes que recordar:

  • A diferencia de las propiedades de alineación en flexbox, los márgenes automáticos deberían definirse en el elemento flex.
  • Los márgenes automáticos tienen prioridad sobre las propiedades de alineación de flexbox.

Como siempre, ¡muchas gracias por leer!

Más tutoriales de Flexbox

¡Tenemos muchos tutoriales prácticos para ayudarte a aprender flexbox ¡chécalos!