
Nuestras herramientas para la alineación vertical han mejorado mucho últimamente. Mis primeros días como diseñador de sitios web consistieron en diseñar diseños de página 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 en el diseño.
Echemos un vistazo a un escenario en 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, 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:
Este 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 entre sí muy bien.
Para empezar, podríamos optar por soluciones CSS de ancho fijo basadas en píxeles para obligar a los elementos a alinearse 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 hace el truco.
Pero… esta no es precisamente 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 “Alejarse de Sass” en mi blog.
A medida que avanzaba 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
¡y!
- 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 “El albatros santo de Flexbox” de Heydon Pickering:
Lo que realmente quiero es para el segundo <fieldset>
para envolver debajo del primero solo cuando ya no puedan caber perfectamente en una fila.
¿Podemos hacer esto con flexbox?
Un punto de venta clave para 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, el flex-wrap
la propiedad se establece en wrap
. Esto significa que tan pronto como ambos <fieldset>
los elementos ya no caben en una línea, se ajustarán a una segunda línea.
.wrapper--accessibility-tools {
display: flex;
flex-wrap: wrap;
}
El flex-wrap
La propiedad tiene tres valores disponibles. El valor predeterminado es nowrap
, dejando elementos en una línea. El wrap
El valor permite que los elementos fluyan en varias líneas. entonces hay wrap-reverse
, que permite que los elementos se ajusten pero, espérelo, al revés (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 un min-width
todavía se necesita valor para eliminar el problema de alineación vertical. Entonces: cerca pero sin cigarro.
¿Puede Grid 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 usar para permitir que cada <fieldset>
para ocupar tanto o tan poco espacio como necesiten. Yendo directo a ello, podemos aprovechar la auto-fill
y auto-fit
palabras clave (dentro de un repeat()
función) para permitir que los elementos de la cuadrícula fluyan en varias líneas sin necesidad de consultas de medios. La diferencia es un poco sutil, pero está bien explicada en “Auto-Sizing Columns in CSS Grid: auto-fill vs auto-fit” de Sara Soueidan. usemos auto-fit
:
.wrapper--accessibility-tools {
display: grid;
grid-template-columns: repeat(auto-fit, 450px);
grid-gap: 10px;
}
Al igual que el ejemplo de flexbox, todavía necesito establecer un valor absoluto para el ancho de la etiqueta para alinear el <fieldset>
elementos a medida que se apilan.
Otro enfoque con rejilla
CSS Grid también permite que los elementos respondan en función de su contenido utilizando 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. Configuremos dos columnas iguales aquí:
.wrapper--accessibility-tools {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
También hay un minmax()
función que crea pistas de cuadrícula que se adaptan al espacio disponible, pero que tampoco se reducen más de un tamaño especificado.
.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 cualquier valor absoluto o CSS específico del dispositivo. Sin embargo, los resultados están lejos de ser ideales, cada cuadrícula ahora responde en diferentes puntos. Tal vez no sea un gran problema, pero ciertamente no es genial.
Esto sucede porque al agregar display: grid
a un contenedor, solo los elementos secundarios directos de ese contenedor se convierten en elementos de cuadrícula. Esto significa que las unidades de tamaño intrínsecas que usamos solo se relacionan con elementos en la misma cuadrícula.
Usando subcuadrícula
Para lograr realmente mi objetivo, necesito que los botones y las etiquetas reaccionen a los elementos de los contenedores de rejilla hermanos. CSS Grid Level 2 incluye la característica de subcuadrícula. Aunque siempre hemos podido anidar cuadrículas, los elementos dentro de cada contenedor de cuadrícula han sido independientes. Con la subcuadrícula, podemos configurar cuadrículas anidadas (secundarias) que usan pistas de cuadrículas principales.
Esto hace que los patrones de números 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:
Crédito: Rachel Andrew
La subcuadrícula permite que las tarjetas usen las filas definidas en la cuadrícula principal, lo que significa que pueden reaccionar al contenido de las tarjetas circundantes.
Crédito: Rachel Andrew
Cada tarjeta en este ejemplo aún abarca tres pistas de fila, 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 su lugar, necesitamos cambiar el tamaño de las columnas en función del 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 el auto-fit
manifestació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éndolos 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 cuadrícula también es flexible si introducimos un título más largo en uno de los botones, los demás elementos responderán en consecuencia.
Compatibilidad del navegador
El soporte para subgrid no es excelente en el momento de escribir este artículo. Solo es compatible con Firefox 71+, aunque hay señales positivas de otros navegadores. Las consultas de características de CSS se pueden usar 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 en adelante.
Escritorio
Cromo | Firefox | ES DECIR | Borde | Safari |
---|---|---|---|---|
No | 71 | No | No | No |
Móvil / Tableta
Android cromo | android firefox | Androide | iOSSafari |
---|---|---|---|
No | 95 | No | No |
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 los elementos de forma y cuadrícula y flexbox.
<fieldset class="accessibility-tools__colour-theme">
<div class="wrapper"></div>
</fieldset>
El diseño CSS se aplica al envoltorio 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 Level 2: Here Comes Subgrid” por Rachel Andrew
- “El albatros santo flexbox” por Heydon Pickering