soy Kseso y esto EsCSS

Sobreponer elementos sin absolute. Con CSS Grid Layout y el mismo grid-area para todos

Sobreponer elementos sin absolute. Con CSS Grid Layout y el mismo grid-area para todos

·Por Kseso ✎ 0
Sobreponer elementos sin absolute. Con CSS Grid Layout y el mismo grid-area para todos

Hay numerosas ocasiones (incluso en producción) en las que es necesario colocar un elemento sobre otro. EL caso típico sería una imagen y sobre ella un texto o leyenda.

La solución casi universal y única si descartamos el que sea una imagen y la colocamos como background (sólo indicado cuando es ornamental y no parte de la información del documento) es recurrir a declarar position: absolute al menos a un elemento de los implicados.

Pero esta solución lleva aparejada una serie de inconvenientes que hay que solventar en cada caso. Inconvenientes derivados la mayoría de sacar del flujo del documento al elemento.

Y la solución óptima no es fácil. Muchas veces la composición termina fallando en algún momento o situación.

¡Hasta hoy!

CSS Grid Layout al recate

En el artículo de este blog "CSS Grid Layout: guía básica para comenzar a usarlo", y más concretamente en el capítulo Ubicando los ítems del CSS Grid Layout por "template areas tienes explicada la base para ubicar los ítems del Grid Layout en él. Y si lo quieres en profundidad tienes el post "Guía exhaustiva de colocación de elementos en el Grid Layout"

A nivel práctico esta forma de distribución la puedes ver usadas en varias demos que he publicado últimamente. Entre otras en las tabs o pestañas de la demo del post "Viejas demos con CSS Grid Layout inside" uso la propiedad grid-area que es la que he elegido para la ubicar elementos unos encima de otros en vez de la tradicional position: absolute

Pero perféctamente puedes optar por cualquiera de las otras formas posibles en tus juegos CSS o derivados de este post.

grid-arrea: miArea

Normalmente la razón de estructurar el elemento al que declaramos display: grid es colocar cada uno de sus ítems en su "zona" correspondiente. Esto es lo normal y lógico.

Sin embargo el CSS Grid layout esconde una particularidad que si ya has jugado con él seguro que ya te has topado con ella:

En el CSS Grid layout es posible que 2 o más ítems ocupen el mismo espacio al mismo tiempo. Tal como ocurre con dos elementos posicionados en el mismo punto.

Pero con una gran diferencia: los ítems del Grid Layout están dentro del flujo del documento. Incluso si comparten el mismo área.

Elementos sobrepuestos con CSS Grid Layout

Después de toda la parrafada previa ya va siendo hora de verlo en funcionamiento con una demo. Porque recuerda que hasta no ver la demo es un dragón.

En primer lugar un caso simple. En la demo uso elementos textuales para evitar tener añadir código para extra para lidiar con tamaños y relación de aspectos si la base fuese una imagen (<img src='...' />) responsive.

See the Pen Overlapping elements without "position: absolute" by Kseso (@Kseso) on CodePen.

Las ventaja más significativa respecto a usar posiciones absolutas es que la caja padre no necesita tener declaradas medidas para adaptarse a su contenido y a la ventana o viewport en la que se dibuja. Puedes verlo reescalando la ventana y modificando los textos.

El CSS más relevante consiste en habilitar en el elemento padre (el 'section') el Grid Layout:

section { background: rgba(0,0,0,.5); display: grid; grid-template-areas: 'soloyo'; justify-items: center; }

Y a continuación colocar todos y cada uno de sus hijos en área que hemos creado en él. Área que es una y sólo una que ocupará todo el tamaño del 'section'.

img, header, article, footer { grid-area: soloyo; }

Pero si hiciésemos sólo esto tendríamos un problema: los elementos de este caso simple son textuales aparecerían tan sobrepuestos unos encimados sobre otros que sería imposible leer nada.

Así que recurrimos, una vez más: por ser textos, a recolocarlos de forma que siempre y en todas las circunstancias sean legibles:

article { grid-area: soloyo; align-self: stretch; display: block; /* hacemos sitio para el header y el footer */ padding: 15vh 0rem; } header { /* en la parte superior */ align-self: flex-start; } footer { /* en la parte inferior */ align-self: flex-end; } img { align-self: center; /* doble centrado */ margin-right: auto; /* desplazada al lado izquierdo */ z-index: -1; /* bajo el fondo negro */ }

Texto sobre imagen

Y para terminar el caso paradigmático de elementos sobrepuestos: textos sobre imagen. Varias demos.

Esta primera demo simula una página en las que sobre las imágenes se muestra algún tipo de información. El tamaño de las imágenes (tanto su altura como anchura) están configurados para que quepan en el viewport manteniendo su aspect ratio natural y así puedan ser vistas en su totalidad sin tener que hacer scroll.

Resumiendo, las imágenes no sobrepasan del viewport, mantienen su relación de aspecto y su tamaño final (tanto la anchura como altura) está tanto función de las medidas naturales de cada imagen y de la ventana donde se muestran.

See the Pen JJXWOK by Kseso (@Kseso) on CodePen.

El siguiente es un caso sencillo de una imagen supuestamente informativa vía src con un encabezado y pie de foto, ambos textos colocados sobre la imagen:

See the Pen Overlapping elements without "position: absolute" by Kseso (@Kseso) on CodePen.

Y para terminar el caso paradigmático de elementos sobrepuestos: textos sobre imagen. La demo siguiente va con una imagen responsive que he complicado algo más para mantener el aspect ratio o relación de aspecto con ayuda de las CSS custom properties acotadas y polivalentes que aunque no son variables molan.

See the Pen Overlapping elements without "position: absolute by Kseso (@Kseso) on CodePen.

Uso una imagen de unsplash vía unsplash.it para que si quieres puedas modificar el tamaño natural de la misma (ancho y alto) vía su src y asignarle la relación de aspecto oportuna vía el valor del atributo class='' de figure

Eso sí, no he afinado ni probado exhaustivamente el tema de los tamaños y la relación de aspecto así que lo más seguro es que en determinadas circunstancias falle el tamaño con el que se muestra, la relación de aspecto o ambas.

avatar del Editor del blog

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