Lograr la alineación vertical (¡Gracias, Subgrid!)
Nuestras herramientas para la alineación vertical han mejorado mucho últimamente. Mis primeros días como diseñador de sitios web implicaron diseñar diseños de páginas de inicio de 960 px de ancho y alinear cosas horizontalmente en una página usando una cuadrícula de 12 columnas. Surgieron consultas de los medios que requirieron un cambio mental serio. Resolvió algunos problemas importantes, por supuesto, pero introdujo otros nuevos, como lidiar con la alineación cuando los elementos se ajustan o se mueven de otra manera en el diseño.
Echemos un vistazo a un escenario particular: una “barra” con algunos botones. Hay dos grupos de estos botones, cada uno contenido dentro de un fieldset
con un legend
.
En una pantalla grande, ya estamos listos:
Y aquí hay un método CSS muy básico que logra ese diseño y también se divide en dos “filas” en un punto de interrupción móvil:
.accessibility-tools fieldset { width: 48%; float: left; margin-right: 1%;}
/* Mobile */@media only screen and (max-width: 480px) { .accessibility-tools fieldset { width: 100%; }}
En una pantalla pequeña, terminamos con esto:
Éste es el problema: la falta de alineación vertical. Digamos que queremos alinear esos botones en una disposición más agradable donde los bordes de los botones se alineen bien entre sí.
Para empezar, podríamos optar por soluciones CSS de ancho fijo basadas en píxeles para forzar que los elementos se alineen bien en varios puntos de interrupción, usando números mágicos como este:
/* Mobile */@media only screen and (max-width: 480px) { legend { width: 160px; } button { width: 130px; }}
Eso funciona.
Pero… ésta no es exactamente una solución flexible al problema. Aparte de los números mágicos (valores de píxeles fijos basados en contenido específico), también se basó en el uso de consultas de medios de las que estoy tratando de alejarme cuando puedo. Hablé de esto en una publicación llamada “Alejándose del Sass” en mi blog.
A medida que avanzamos hacia algunas de las características más modernas de CSS, se eliminó la necesidad de apuntar a tamaños de pantalla específicos con código único.
Lo que necesito es cada botón y etiqueta para responder a:
- el espacio disponible
- su contenido
¡ay!
- otros elementos a su alrededor.
Espacio disponible
El problema con el uso de consultas de medios es que no tienen en cuenta el espacio alrededor de los elementos que se están realineando, un punto perfectamente demostrado en esta imagen de “The Flexbox Holy Albatros” de Heydon Pickering:
Lo que realmente quiero es que el segundo fieldset
se envuelva debajo del primero solo cuando ya no puedan caber perfectamente en una fila.
¿Podemos hacer esto con flexbox?
Un punto de venta clave de flexbox es su capacidad para crear elementos que respondan al espacio que los rodea. Los componentes pueden “flexionarse” para llenar espacio adicional y encogerse para caber en espacios más pequeños.
Para esta situación, la flex-wrap
propiedad se establece en wrap
. Esto significa que tan pronto como ambos fieldset
elementos ya no quedarán en una línea, se ajustarán a una segunda línea.
.wrapper--accessibility-tools { display: flex; flex-wrap: wrap;}
La flex-wrap
propiedad tiene tres valores disponibles. El valor predeterminado es nowrap
, dejando los elementos en una línea. El wrap
valor permite que los elementos fluyan en varias líneas. Luego está wrap-reverse
, que permite que los elementos se ajusten pero, espere, a la inversa (es extraño verlo: cuando los elementos se ajustan, van por encima de la fila anterior en situaciones de izquierda a derecha).
El uso de flexbox evita que el diseño sea tan rígido, pero min-width
aún se necesita un valor para eliminar el problema de alineación vertical. Entonces: cerca pero sin cigarro.
¿Puede la red ayudarnos?
CSS Grid es el primer módulo CSS creado específicamente para resolver los continuos problemas de diseño que enfrentan los diseñadores y desarrolladores web. No es un reemplazo directo de flexbox; más bien, los dos módulos suelen funcionar bastante bien juntos.
Al igual que Flexbox, la cuadrícula se puede utilizar para permitir que cada uno fieldset
ocupe tanto o tan poco espacio como necesite. Para ir directo al grano, podemos aprovechar las palabras clave auto-fill
y auto-fit
(dentro de una repeat()
función) para permitir que los elementos de la cuadrícula fluyan en varias líneas sin la necesidad de consultas de medios. La diferencia es un poco sutil, pero está bien explicada en “Autodimensionamiento de columnas en CSS Grid: autocompletar versus ajuste automático” de Sara Soueidan. Usamos auto-fit
:
.wrapper--accessibility-tools { display: grid; grid-template-columns: repeat(auto-fit, 450px); grid-gap: 10px;}
Al igual que en el ejemplo de Flexbox, todavía necesito establecer un valor absoluto para el ancho de la etiqueta para alinear los fieldset
elementos a medida que se apilan.
Otro enfoque con parrilla.
CSS Grid también permite que los elementos respondan en función de su contenido mediante pistas de cuadrícula flexibles. Además de otros valores de longitud como porcentajes, unidades relativas o píxeles, CSS Grid acepta una unidad fraccionaria ( fr
), donde 1fr
ocupará una parte del espacio disponible, 2fr
ocupará dos partes del espacio disponible, y así sucesivamente. Configuramos dos columnas iguales aquí:
.wrapper--accessibility-tools { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 10px;}
También hay una minmax()
función que crea pistas de cuadrícula que se adaptan al espacio disponible, pero que tampoco se reducen más allá de un tamaño específico.
.wrapper--accessibility-tools { display: grid; grid-template-columns: minmax(auto, max-content) minmax(auto, max-content); grid-gap: 10px;}
Ambas demostraciones funcionan y están libres de valores absolutos o CSS específicos del dispositivo. Sin embargo, los resultados están lejos de ser ideales: cada cuadrícula ahora responde en diferentes puntos. Quizás no sea un gran problema, pero ciertamente no es un gran problema.
Esto sucede porque cuando se agrega display: grid
a un contenedor, solo los hijos directores de ese contenedor se convierten en elementos de la cuadrícula. Esto significa que las unidades de tamaño intrínsecas que utilizamos solo se relacionan con elementos de la misma cuadrícula.
Usando subcuadrícula
Para realmente lograr mi objetivo, necesito que los botones y las etiquetas reaccionen a los elementos en los contenedores de cuadrícula hermanos. CSS Grid Level 2 incluye la función de subcuadrícula. Aunque siempre hemos podido anidar grillas, los elementos dentro de cada contenedor de grillas han sido independientes. Con la subcuadrícula, podemos configurar cuadrículas anidadas (secundarias) que utilizan pistas de cuadrículas principales.
Esto hace que los patrones numéricos que antes eran difíciles sean mucho más fáciles, en particular el patrón de "tarjeta", que parece ser el ejemplo más popular para mostrar los beneficios de la subcuadrícula. Sin subcuadrícula, cada tarjeta se define como una cuadrícula independiente, lo que significa que el tamaño de la pista en la primera tarjeta no puede responder a un cambio de altura en la segunda. A partir de un ejemplo que usó Rachel Andrew, aquí hay un grupo simple de tarjetas:
Subgrid permite que las tarjetas utilicen las filas definidas en la cuadrícula principal, lo que significa que pueden reaccionar al contenido de las tarjetas circundantes.
Cada tarjeta en este ejemplo todavía abarca tres filas, pero esas filas ahora están definidas en la cuadrícula principal, lo que permite que cada tarjeta ocupe la misma cantidad de espacio vertical.
Para el ejemplo con el que hemos estado trabajando, no necesitamos usar filas. En lugar de ello, necesitamos dimensionar las columnas según el contenido de las cuadrículas hermanas. Primero, configuremos la cuadrícula principal para que contenga los dos fieldset
elementos. Esto es similar al código que vimos anteriormente en la auto-fit
demostración.
.wrapper--accessibility-tools { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); grid-gap: 10px;}
Luego colocamos cada subcuadrícula en la cuadrícula principal.
.sub-grid { display: grid; grid-column: span 3; grid-template-columns: subgrid; align-items: center;}
Todas las etiquetas y botones ahora están alineados con las pistas de su cuadrícula principal, manteniéndolas consistentes. Cada uno tendrá el mismo ancho según el espacio disponible. Si no hay suficiente espacio para cada cuadrícula anidada en una línea, la segunda se ajustará a una nueva línea.
Esta vez, los dos elementos de la cuadrícula anidados se alinean perfectamente. La grilla también es flexible, si introducimos un título más largo en uno de los botones, el resto de elementos responderán en consecuencia.
El soporte para subgrid no es excelente al momento de escribir este artículo. Sólo es compatible con Firefox 71+, aunque hay señales positivas de otros navegadores. Las consultas de funciones CSS se pueden utilizar para proporcionar estilos alternativos a Chrome y Edge.
Estos datos de soporte del navegador son de Caniuse, que tiene más detalles. Un número indica que el navegador admite la función en esa versión y superiores.
Escritorio
Cromo | Firefox | ES DECIR | Borde | Safari |
---|---|---|---|---|
117 | 71 | No | 117 | 16.0 |
Móvil/Tableta
androidcromo | Android Firefox | Androide | Safari en iOS |
---|---|---|---|
125 | 126 | 125 | 16.0 |
Tenga en cuenta que estoy usando un contenedor adicional alrededor de los conjuntos de campos en estas demostraciones. Esto es para combatir un error con elementos de formulario, cuadrícula y flexbox.
fieldset div/div/fieldset
El diseño CSS se aplica al contenedor con el conjunto de campos configurado en display: contents
.
.accessibility-tools fieldset { display: contents; border: 0;}
Otros escritos sobre el tema.
- “Subcuadrícula para mejores diseños de tarjetas” por Miriam Suzanne
- “CSS Grid Nivel 2: Aquí viene la subcuadrícula” por Rachel Andrew
- “El santo albatros del flexbox” de Heydon Pickering
Deja un comentario