Margin: auto; Distribución equitativa por grupos de los ítems del flexbox sin marcado extra 8.9.15
Tienes un menú y quieres formar varios grupos separados con sus ítems. Y a la vez distribuirlos unos a la izquierda, otros a la derecha y alguno centrado. Y sin añadir marcado Html extra. ¿Lo vemos?
Margin: auto; Distribución equitativa por grupos de los ítems del flexbox sin marcado extra
Caso: Tienes un grupo de ítems y quieres distribuirlos en grupos. Esto es, uno o varios alineados a la izquierda y el resto a la derecha y entre ambos un espacio de separación que los diferencie claramente.
Y todo ello como es obligado en estos tiempos de forma responsive
y sin necesidad de cálculos o conocer de antemano el número de ítems.
Hasta no hace mucho la solución pasaría por añadir marcado Html extra para crear los dos grupos y flotarlos. Pero no queremos eso. Además de ser vieja escuela
nos obligaría a tener que modificar el marcado en el documento si deseásemos cambiar el número de items que componga cada grupo.
Como a estas alturas ya deberías estar en modo flexbox
(y si no lo estás ya llegas tarde), vamos a aprovecharnos de algunas de sus particularidades.
Pero mejor que la intro textual, un poco de código. Tengamos un grupo de enlaces (los ítems) en un elemento nav
. Podría ser una lista y sus elementos li
´s los ítems, a efectos de la demo es indiferente:
<nav>
<a href=''></a>
<a href=''></a>
<a href=''></a>
<a href=''></a>
<a href=''></a>
</nav>
La intención es, sin tocar este html
, presentar estos enlaces formando varios grupos y que cada grupo esté separado del resto. Tal como en este pen:
See the Pen MYzWJo by Kseso (@Kseso) on CodePen.
Un poco de Css teórico
En el flexbox
se define la propiedad justify-content
como la encargada de distribuir los ítems en el eje principal.
En función de su valor se alinearan a un lado u otro o se distribuirán de forma uniforme a lo largo de toda la caja flexible (distribuyendo el espacio vacío del padre según el valor declarado).
A su vez, la propiedad margin
sigue siendo efectiva y similar a como actúa en el modelo Css de caja tradicional.
Uno de los valores admitido por la propiedad margin
es auto
y su valor computado depende del tipo de caja que sea.
En los ítems del flexbox
el valor auto
en los márgenes del eje principal (main axis
) es similar a lo que ocurre en el modelo tradicional con las cajas de bloque no reemplazadas. Pero añade alguna particularidad por las características intrínsecas de sus ítems.
De entrada si un ítem del flexbox tiene declarado al menos uno de sus márgenes laterales como auto
hace que la propiedad justify-content
deje de actuar.
Y a continuación lo que ocurre es que dicho valor computado (el valor final) es todo el espacio del flexbox no ocupado por sus items.
Y dependiendo qué ítem tenga el valor de auto
y si es a uno o los dos márgenes laterales en el eje principal tendremos dos o más grupos de ítems separados del resto y alineados a un lado, al otro o al centro del eje principal del flexbox.
Tal como en los diferentes nav
´s de la demo del pen anterior. Nota que el eje principal del flexbox en la demo es horizontal de izquierda a derecha. Eso se traduce en la demo en que margin: auto
aplica al margen izquierdo y al derecho. Pero si distribuyésemos los ítems en la vertical flex-direction: column
los márgenes afectados serían el superior e inferior.
Si el tamaño en el eje secundario o transversal (cross axis) del flexbox no estuviese ocupado en su totalidad por el ítem, margin: auto;
realiza un centrado doble en el ítem que lo tiene declarado. Eso supone que también pierde la alineación en el eje principal con el resto de ítems.
See the Pen bNQEpo by Kseso (@Kseso) on CodePen.
A todo lo anterior, a algún ítem del flexbox con uno o los dos márgenes laterales en auto, puedes añadirle alguna otra propiedad del flexbox y ver qué ocurre. Prometo diversión. Como por ejemplo, jugar con el orden de alguno de ellos como en la última declaración del primer pen que he dejado comentada.
Artículo publicado originalmente el 14 de Marzo de 2015.
Kseso
the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso
Hola, estuve probando esto y está genial, mi pregunta es: Podria con flex armar el layout de un header en el cual el first-child de li lo usaría con margin-right: auto, y con background el logo, y el resto serian los items del menu? Es una practica aceptable?
ResponderEliminarhttp://codepen.io/gustavoalias/pen/meJgLB
Hola Unknown
EliminarAntes de nada, incluyo el pen que compartes para evitar el paseo hasta allá xD
[pen]data-height="350" data-theme-id="299" data-slug-hash="meJgLB" data-default-tab="result" data-user="gustavoalias" class='codepen'[/pen]
La única observación que te haría sería sobre la inclusión del logo como fondo.
La opinión generalizada es que el logo es un elemento relevante, así que lo apropiado es incluirlo como imagen vía src (<:img src=.../>).
Además que seguro que tendrás que convertirlo en un enlace para regresar al índex y posíblemente también será un h1 en el home de la web o h2 en otras páginas.
Un saludo
Hola Kseso, me logueé con Google+, pense que aparecería mi nombre (Gustavo). Muchas gracias por tu opinion y muchisimas gracias por el blog, sin dudas el mejor y mas completo sobre CSS en castellano.
EliminarNah! Gustavo. No hay quebranto ;-)
EliminarCosas de Blogger, te bautizó como "unknown y aunque el enlace iba a tu perfil de Blogger redirecciona al de G+.
Pero pese a estas particularidades (o por ellas) le seguiremos dando el cariñito xD
Me alegra si de cuando en vez encontráis algo de ayuda en estas páginas.
Un saludo
Paso por aquí, para agradecer y guardar en "favoritos" y saludar, ya que últimamente ando perdido en el tiempo.
ResponderEliminar