soy Kseso y esto EsCSS

Distribución de bloques en 1 sola fila y navegación horizontal sin declarar su ancho

Cómo distribuir elementos de bloque sin saber su número en una sola fila, y forzar el scroll-X (navegación horizontal) sin necesidad de fijar la anchura de la caja que los contiene.

Distribución de bloques en 1 sola fila y navegación horizontal sin declarar su ancho

·Por Kseso ✎ 11
Distribución y navegación horizontal sin anchuras definidas puro Css

Una de las características de Css en nuestro sistema de escritura es que los contenidos fuerzan el crecimiento de su caja padre en la vertical o altura. Esto supone que lo natural, si no se altera por declaración expresa, es que llegados a un punto aparece el scroll vertical para navegar por la página de arriba a aabajo.

Si deseas cambiar este comportamiento típico hay que declarar un Css para cada caso. Pero casi siempre eso supone tener que crear un sistema de al menos dos cajas enlazadas: La exterior de medidas contenidas (aunque sea en vw/vh) y overflow en X y para la interior (que contendrá la información) calcular su anchura para que quepan sus elementos en una línea sin que se quede ni corta ni larga. Como por ejemplo en este Slider RWD.

Esto no supone problema cuando el contenido (lo alojado en la caja hija anterior) es conocido de antemano. Pero el problema surge cuando ese contenido es variable de caso a caso o se genera dinámicamente.

Ahora imagina la siguiente situación: quieres mostrar un artículo principalmente textual. Por una cuestión de usabilidad y legibilidad de los textos sabes que la anchura ha de ser tal que quepan entre 10 y 15 palabras por línea.

Normalmente marcas una anchura acorde con lo anterior en el cuerpo del artículo para que las líneas no se hagan eternas. Lo que supone que en pantallas "grandes" quedan espacios libres en los laterales. Si el post es lo suficientemente largo genera un scroll vertical considerable.

Una forma de aprovechar esos espacios vacíos en los laterales y minificar el scroll (cambiando el vertical por el horizontal) es recurrir a las multicolumnas Css. Pero evitando que su altura fuerce el desplazamiento vertical.

Esta demo es una variación del post Multicolumnas Css en pestañas. En este caso no generamos ni pestañas ni tampoco necesitamos saber de antemano el contenido para calcular número de columnas ni anchura de cada una.

Nota del Editor. Esta demo en el momento de su publicación generó un interesante debate en los comentarios relativo al comportamiento del scroll al usar la rueda del ratón o flechas de navegación: la expectativa del usuario sería que al hacer "scroll down" o "scroll up" con su dispositivo se tradujese en un desplazamiento horizontal del contenido.
La respuesta a esta cuestión ha sido tripe:
Furoya & Js en el comentario 1.5 construyó una demo usando Javascript.
Jorge MG & Js aporta la suya también basada en Js en el comentario nº 3
Hecho en puro Css la tienes en el post On mouse wheel down... scroll right

En este caso aunque inserto la demo en el post es mejor que la ves a pantalla completa. Redimensiona la ventana para que aparezcan las columnas y su número varíe:

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

Ver Demo A Full

Marcado html

En este caso partimos de un marcado básico de lo más sencillo:

<body> <!-- cualquiera que sea o necesites --> </body>

Como ves no importa realmente. La razón está en que sólo necesitaremos actuar sobre el body vía Css para logarlo.

Declarando estilos y @medias queries

Toda la magia está en crear las columnas a partir de un tamaño mínimo de la pantalla:

html { height: 100%; box-sizing: border-box; } body { height: 100%; overflow: auto; }

En dispositivos pequeños no hay columnas, el scroll es el típico: vertical. Para que aparezcan 3 columnas de anchura igual a la mitad de la pantalla creamos una regla @media query. En la demo es arbitraria (800px). Las declaraciones más significativas son:

@media screen and (min-width: 800px) { body { columns: 3; column-gap: 2rem; } }

Y para pantallas "gigantes" y para que la línea no resulte demasiado larga, añadimos una segunda @media query. En el caso de la demo y para que pueda ser efectiva en pantalla más comedidas la seteo a 1150px:

@media screen and (min-width: 1150px) { body { columns: 4; } }

¿Cómo?

Lo que está ocurriendo es que al fijar la altura del elemento que crea las columnas (el body), en caso de que la información no quepa en el número de ellas indicadas, se fuerza su crecimiento en aquella dirección que no tiene tamaño indicado. En este caso la anchura.

Basta que anules la declaración height: 100% del body para que sea el scroll vertical el que aparece.

Variaciones

La propiedad columns es la forma acortada (shorthand) de otras dos: column-width (anchura de las columnas) y column-count (el número de ellas. El valor inicial o por defecto es auto.

En los códigos anteriores he fijado el número de columnas por anchura. En este caso, que la anchura de la caja (el body) no está fijada y se fuerza a crecer en función del contenido, para cálculos toma el valor del viewport que ocupa el body.

Así que en vez de indicar el número de columnas en el que se divide el body podemos marcar la anchura de cada columna y dejar su número como auto.

body { height: 100%; overflow: auto; columns: 250px auto; column-gap: 0px; }

Como en la demo siguiente:

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

Ver Demo

Sin embargo esta variación tiene una particularidad. La anchura declarada de las columnas actúa como anchura mínima. Esto es, el espacio del viewport se divide entre el valor de column-width pero el sobrante (en caso de que no sea un número entero) no es ocupado por la siguiente columna (mostrando sólo una franja vertical de ella). Ese espacio (el resto) se distribuye y añade por igual entre las columnas ya generadas.

Así si se declara como en el código anterior una anchura de la columna de 250px y el espacio disponible en el elemento (antes de forzar su crecimiento) es, por ejemplo, de 550px no se mostrarán 2 columnas completas y 50px de la tercera. Las columnas pasan a tener una anchura final computada de 250px más la mitad del resto (50px/2) = 275px.

Esto supone que si no hay cabida para mostrar dos columnas completas como mínimo, la anchura final de cada columna es el total del viewport.

Apuntes finales

Sin embargo no hay que perder de vista que trabajando con columnas Css te vas a topar con unos cuantos imprevistos, fruto o bien del estancamiento en su desarrollo (CR desde 12 Abril 2011), o bien por bugs e inconsistencias entre los distintos navegadores.

Especialmente notorios en elementos reemplazados (como imágenes) que desbordan la anchura de la columna o los efectos raros si hay animaciones o transiciones.

Si eres un visitante del blog ya veterano recordarás de las dificultades que tuve con un tema basado en columnas allá por 2013. Tantos que al final fue obligado cambiarlo.

avatar del Editor del blog

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 Don Kseso Kseso