Cómo utilizar CSS Grid para encabezados y pies de página fijos
CSS Grid es una colección de propiedades diseñadas para hacer que el diseño sea más fácil que nunca. Como todo, hay una pequeña curva de aprendizaje, pero honestamente es divertido trabajar con Grid una vez que lo dominas. Un área donde brilla es la de los encabezados y pies de página. Con un pequeño ajuste en nuestra forma de pensar, podemos lograr encabezados y pies de página que se comporten como si estuvieran fijos, o tener ese tratamiento "pegajoso" (no position: sticky
, sino el tipo de pie de página que abraza la parte inferior de la pantalla incluso si no hay suficiente contenido para impulsarlo allí, y se aleja con más contenido).
Esperemos que esto despierte un mayor interés en los diseños modernos y, si lo hace, no puedo recomendar lo suficiente el libro de Rachel Andrew, The New CSS Layout: cubre las dos principales técnicas de diseño modernas, grid y flexbox.
lo que estamos haciendo
Implementemos un diseño HTML bastante clásico que consta de un encabezado, contenido principal y pie de página.
Crearemos un pie de página verdaderamente fijo, uno que permanezca en la parte inferior de la ventana gráfica donde el contenido principal se desplaza dentro de sí mismo, según sea necesario, luego actualizaremos el pie de página para que sea un pie de página adhesivo más tradicional que comience en la parte inferior de la ventana gráfica. incluso si el contenido principal es pequeño, se desplaza hacia abajo según sea necesario. Además, para ampliar nuestra exposición a la cuadrícula, diseñemos nuestro soporte de contenido principal para que pueda abarcar todo el ancho de la ventana gráfica o ocupar una franja bien centrada en el medio.
Un pie de página fijo es un poco inusual. Los pies de página suelen estar diseñados para comenzar en la parte inferior de la ventana gráfica y ser empujados hacia abajo por el contenido principal según sea necesario. Pero un pie de página persistente no es algo inaudito. Charles Schwab lo hace en su página de inicio. De cualquier manera, ¡será divertido implementarlo!
Pero antes de continuar, siéntase libre de echar un vistazo al pie de página fijo implementado en el sitio de Charles Schwab. Como era de esperar, utiliza un posicionamiento fijo, lo que significa que tiene un tamaño codificado. De hecho, si abrimos DevTools, lo vemos de inmediato:
body #qq0 { border-top: 4px solid #133568; background-color: #eee; left: 0; right: 0; bottom: 0; height: 40px!important;}
No solo eso, sino que también existe el equilibrio entre asegurarse de que el contenido principal no quede oculto detrás de ese pie de página fijo, lo cual se logra estableciendo rellenos codificados (incluidos 15 px en la parte inferior del footer
elemento), márgenes (incluidos 20 px en ul
la parte inferior del elemento). el pie de página), e incluso saltos de línea.
Intentemos lograr esto sin ninguna de estas restricciones.
Nuestros estilos básicos
Esbocemos una interfaz de usuario mínima para comenzar y luego mejoremos nuestra cuadrícula para que coincida con nuestros objetivos. Hay un CodeSandbox a continuación, además de otros adicionales para los pasos posteriores que nos llevan al resultado final.
Primero, hagamos un poco de trabajo de preparación. Nos aseguraremos de utilizar toda la altura de la ventana gráfica, de modo que cuando agreguemos nuestra cuadrícula, será fácil colocar el pie de página en la parte inferior (y mantenerlo allí). Solo habrá un elemento dentro del documento body
con un ID de #app
, que contendrá los header
elementos main
y footer
.
body { margin: 0; /* prevents scrollbars */}
#app { height: 100vh;}
A continuación, configuremos nuestras secciones de encabezado, principal y pie de página, así como la cuadrícula en la que se ubicarán. Para ser claros, esto no funcionará de la manera que queremos desde el principio. Es sólo para empezar, con una base sobre la que construir.
body { margin: 0;}
#app { height: 100vh; /* grid container settings */ display: grid; grid-template-columns: 1fr; grid-template-rows: auto 1fr auto; grid-template-areas: 'header' 'main' 'footer';}
#app header { grid-area: header;}
#app main { grid-area: main; padding: 15px 5px 10px 5px;}
#app footer { grid-area: footer;}
Hemos creado un diseño simple de una columna, con un ancho de 1fr
. Si esto 1fr
es nuevo para usted, básicamente significa "tomar el espacio restante", que, en este caso, es todo el ancho del contenedor de la cuadrícula #app
.
También hemos definido tres filas:
#app { /* etc. */ grid-template-rows: auto 1fr auto; /* etc. */}
La primera y tercera filas, que serán nuestro encabezado y pie de página, respectivamente, tienen el tamaño automático, lo que significa que ocuparán tanto espacio como sea necesario. En otras palabras: ¡no hay necesidad de tamaños codificados! Este es un detalle súper importante y un ejemplo perfecto de cómo nos beneficiamos al usar CSS Grid.
La fila del medio es donde colocaremos nuestro contenido. Le hemos asignado un tamaño 1fr
que, nuevamente, solo significa que ocupa todo el espacio restante que queda de las otras dos filas. Si se pregunta por qué no lo hacemos auto
también, es porque toda la cuadrícula abarca toda la altura de la ventana gráfica, por lo que necesitamos una sección para crecer y llenar cualquier espacio no utilizado. Tenga en cuenta que no tenemos, ni necesitaremos en ningún momento, alturas, márgenes, rellenos fijos, ¡ni siquiera saltos de línea! – para poner las cosas en su lugar. ¡Así es la buena vida cuando se trabaja con grid
!
¿Probamos algún contenido?
Notarás en Sandbox que utilicé React para crear esta demostración, pero como esta no es una publicación sobre React, no profundizaré en esos detalles; React no tiene absolutamente nada que ver con el trabajo de CSS Grid en esta publicación. Sólo lo uso como una manera fácil de navegar entre diferentes fragmentos de marcado. Si odias React, está bien: con suerte puedes ignorarlo en esta publicación.
Tenemos componentes y Header
que representan los elementos y esperados , respectivamente. Y, por supuesto, todo esto se encuentra dentro de nuestro contenedor. Sí, en teoría, debería ser un elemento, semánticamente hablando, pero eso siempre me ha parecido extraño. Solo quería transmitir estos detalles para que todos estemos en la misma página a medida que avanzamos.Main
Footer
header
main
footer
#app
#app
article
Para el contenido real, tengo secciones de Facturación y Configuración entre las que puedes navegar en el encabezado. Ambos muestran contenido falso y estático y solo están destinados a mostrar nuestro diseño en acción. La sección de Configuración será el contenido que pongamos en una franja centrada en nuestra página, Facturación será la que abarque toda nuestra página.
Aquí está el Sandbox con lo que tenemos hasta ahora.
La sección Facturación se ve bien, pero la sección Configuración saca nuestro pie de página de la pantalla. No sólo eso, sino que si nos desplazamos, toda la página se desplaza, provocando que perdamos nuestro encabezado. Esto puede ser deseable en algunos casos, pero queremos que tanto el encabezado como el pie de página permanezcan visibles, así que arreglémoslo.
Encabezado fijo, pie de página fijo
Cuando configuramos inicialmente nuestra cuadrícula, le dimos una altura de 100vh, que es la altura total de la ventana gráfica. Luego asignamos a las filas del encabezado y pie de página una altura automática, y a la principal una altura de 1fr para ocupar el espacio restante. Desafortunadamente, cuando el contenido excede el espacio disponible, se expande más allá de los límites de la ventana gráfica, empujando nuestro pie de página hacia abajo y fuera de la vista.
La solución aquí es trivial: agregar overflow: auto
hará que nuestro main
elemento se desplace, mientras mantiene nuestros elementos header
and footer
en su lugar.
#app main { grid-area: main; overflow: auto; padding: 15px 5px 10px 5px;}
Aquí está la demostración actualizada que pone esto en práctica.
Sección principal de ancho ajustable
Queremos que nuestro main
elemento abarque todo el ancho de la ventana gráfica o esté centrado en un espacio de 600 píxeles. Se podría pensar que podríamos simplemente hacer main
un ancho fijo de 600 px, con márgenes automáticos en cada lado. Pero como esta es una publicación sobre grid, usemos más grid. (Además, como veremos más adelante, un ancho fijo no funcionará de todos modos).
Para lograr nuestro elemento centrado de 600 px, convertiremos el main
elemento en un contenedor de cuadrícula. Así es, ¡una cuadrícula dentro de una cuadrícula! Anidar cuadrículas es un enfoque totalmente legítimo e incluso será más fácil en el futuro cuando las subcuadrículas sean oficialmente compatibles en todos los navegadores. En este escenario, crearemos main
una cuadrícula con tres pistas de columnas de 1fr 600px 1fr
o, en pocas palabras, 600 px en el medio, con el espacio restante dividido equitativamente en los lados.
#app main { display: grid; grid-template-rows: 1fr; grid-template-columns: 1fr 600px 1fr;}
Ahora coloquemos nuestro contenido en la cuadrícula. Todos nuestros diferentes módulos se representan en un section
niño. Digamos que de forma predeterminada, el contenido ocupará la sección central, a menos que tenga una .full
clase, en cuyo caso abarcará todo el ancho de la cuadrícula. No usaremos áreas con nombre aquí y, en su lugar, especificaremos coordenadas de cuadrícula precisas de la forma [row-start] / [col-start] / [row-end] / [col-end]
:
#app section { grid-area: 1 / 2 / 1 / 3;}
#app section.full { grid-area: 1 / 1 / 1 / 4}
Es posible que le sorprenda ver un col-end
valor de 4
, dado que solo hay tres columnas. Esto se debe a que los valores de columnas y filas son líneas de cuadrícula de columnas y filas . Se necesitan cuatro líneas de cuadrícula para dibujar tres columnas de cuadrícula.
El nuestro section
siempre estará en la primera fila, que es la única fila. De forma predeterminada, abarcará las líneas de las columnas 2
hasta 3
, que es la columna del medio, a menos que la sección tenga una clase completa, en cuyo caso abarcará las líneas de las columnas 1
, 4
que son las tres columnas.
Aquí hay una demostración actualizada con este código. Probablemente se verá bien, dependiendo del diseño de CodeSandbox, pero todavía hay un problema. Si reduce la visualización a menos de 600 px, el contenido se trunca abruptamente. Realmente no queremos un ancho fijo de 600 px en el medio. Queremos un ancho de hasta 600 px. Resulta que grid tiene la herramienta perfecta para nosotros: la minmax()
función. Especificamos un ancho mínimo y un ancho máximo, y la cuadrícula calculará un valor que se encuentre dentro de ese rango. Así evitamos que el contenido se salga de la red.
Todo lo que tenemos que hacer es intercambiar ese 600px
valor con minmax(0, 600px)
:
main { display: grid; grid-template-rows: 1fr; grid-template-columns: 1fr minmax(0, 600px) 1fr;}
Aquí está la demostración del código terminado.
Un enfoque más: el tradicional pie de página fijo
Anteriormente, decidimos evitar que el pie de página saliera de la pantalla y lo hicimos estableciendo la propiedad main
del elemento en .overflow
auto
Pero, como señalamos brevemente, ese podría ser un efecto deseable. De hecho, es más bien un pie de página "pegajoso" clásico que resuelve ese molesto problema y coloca el pie de página en el borde inferior de la ventana gráfica cuando el contenido es muy corto.
¿Cómo podríamos conservar todo nuestro trabajo existente, pero permitir que el pie de página se empuje hacia abajo, en lugar de fijarse en la parte inferior en la vista persistente?
En este momento nuestro contenido está en una cuadrícula con esta estructura HTML:
div header / main section / /main footer //div
…donde main
hay un contenedor de cuadrícula anidado dentro del #app
contenedor de cuadrícula, que contiene una fila y tres columnas que usamos para ubicar el contenido de nuestro módulo, que va en la section
etiqueta.
Cambiémoslo a esto:
div header / main section / footer / /main/div
…e incorporar footer
a la main
grilla del elemento. Comenzaremos actualizando nuestra #app
cuadrícula principal para que ahora consta de dos filas en lugar de tres:
#app { /* same as before */
grid-template-columns: 1fr; grid-template-rows: auto 1fr; grid-template-areas: 'header' 'main';}
Sólo dos filas, una para el encabezado y otra para todo lo demás. Ahora actualicemos la cuadrícula dentro de nuestro main
elemento:
#app main { display: grid; grid-template-rows: 1fr auto; grid-template-columns: 1fr minmax(0, 600px) 1fr;}
Hemos introducido una nueva fila de tamaño automático. Eso significa que ahora tenemos una 1fr
fila para nuestro contenido, que contiene nuestro section
, y una auto
fila para el pie de página.
Ahora posicionamos nuestro footer
dentro de esta cuadrícula, en lugar de directamente en #app
:
#app footer { grid-area: 2 / 1 / 3 / 4;}
Dado que main
es el elemento que tiene desplazamiento, y dado que este elemento ahora tiene nuestro pie de página, ¡hemos logrado el pie de página fijo que queremos! De esta manera, si main
tiene contenido que excede la ventana gráfica, todo se desplazará, y ese contenido en desplazamiento ahora incluirá nuestro pie de página, que se encuentra en la parte inferior de la pantalla como esperábamos.
Aquí hay una demostración actualizada. Tenga en cuenta que, si es posible, el pie de página estará en la parte inferior de la pantalla; de lo contrario, se desplazará según sea necesario.
Hice algunos otros pequeños cambios, como ajustes menores a los acolchados aquí y allá; No podemos tener ningún relleno izquierdo o derecho main
, porque footer
ya no iría de borde a borde.
También hice un ajuste de último minuto durante las ediciones finales del section
elemento, en el que habilitamos el contenido de ancho ajustable. Específicamente, configuré su visualización en flex
, su ancho en 100% y su descendiente inmediato en overflow: auto
. Hice esto para que el section
contenido del elemento pueda desplazarse horizontalmente, dentro de sí mismo, si excede el límite de nuestra columna de cuadrícula, pero sin permitir ningún desplazamiento vertical.
Sin este cambio, el trabajo que hicimos equivaldría al enfoque de pie de página fijo que cubrimos anteriormente. Crear section
un contenedor flexible obliga a su hijo inmediato (el div
que contiene el contenido) a ocupar todo el espacio vertical disponible. Y, por supuesto, configurar ese div secundario para overflow: auto
permitir el desplazamiento. Si te preguntas por qué no configuré la sección overflow-x
en auto
y overflow-y
en visible, bueno, resulta que eso no es posible.
Pensamientos de despedida
No hemos hecho nada revolucionario en esta publicación y ciertamente nada que no se pudiera lograr antes de CSS Grid. Nuestro main
contenedor de ancho fijo podría haber sido un elemento de bloque con un max-width
valor de 600px
y márgenes automáticos a la izquierda y a la derecha. Nuestro pie de página fijo podría haberse creado con position: fixed
(solo asegúrese de que el contenido principal no se superponga con él). Y, por supuesto, hay varias formas de conseguir un "pie de página fijo" más tradicional.
Pero CSS Grid proporciona un mecanismo de diseño único y uniforme para lograr todo esto, y es divertido trabajar con él, honestamente, divertido. De hecho, la idea de mover el pie de página de fijo a fijo ni siquiera fue algo que planeé al principio. Lo incluí en el último minuto porque pensé que la publicación era demasiado liviana sin él. Fue trivial de lograr, básicamente mover filas de cuadrícula, no muy diferente a juntar bloques de Lego. Y nuevamente, estas UI eran triviales. ¡Imagínese lo intensamente que brillará la cuadrícula con diseños más ambiciosos!
Deja un comentario