• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Codemotion Magazine

We code the future. Together

  • Discover
    • Events
    • Community
    • Partners
    • Become a partner
    • Hackathons
  • Magazine
    • DevOps
    • Carreras tech
    • Frontend
    • Inteligencia Artificial
    • Dev life
    • Desarrollo web
  • Talent
    • Discover Talent
    • Jobs
    • Manifiesto
  • Companies
  • For Business
    • EN
    • IT
    • ES
  • Sign in

Massimo Avvisatienero 22, 2025 5 min read

Creamos un diseño de caja bento usando CSS moderno

Frontend
facebooktwitterlinkedinreddit

Una caja bento (🍱) es el famoso recipiente japonés para almuerzos que mantiene separadas de manera ordenada las diferentes comidas preparadas. Llevar a la escuela un bento listo es un gesto de afecto hacia quien lo recibe, y la atención con la que se organizan y presentan los distintos platos, además de la calidad de la comida, representa cuánto te importa esa persona.

De esta costumbre y del diseño minimalista, equilibrado y funcional de este peculiar objeto, ha surgido una tendencia en UX/UI llamada Bento Layout (o Bento Box Layout), que será el tema de este tutorial: no utilizaremos arroz, zanahorias o salchichas con forma de pulpo, sino HTML y CSS modernos como nuestros ingredientes, ¡pero la dedicación y el cariño con los que se combinan son los mismos!

Recommended article
junio 12, 2025

Componentes: Integraciones simples, funcionalidades poderosas

Codemotion

Codemotion

Frontend

La base

Para nuestro experimento, queremos partir de una base bastante sencilla pero extremadamente común: tenemos un elemento <main> que contiene varios elementos <section>, cada uno con su propio <article>, que a su vez incluye un <header> y una imagen dentro de un elemento semántico <figure>.

<!DOCTYPE html>
<html lang="es">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
<title>🍱 Diseño de Caja Bento con CSS Moderno</title>
</head>
<body>
<main>
<section class="bento">
<article>
<header>
<h2>Caja 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</header>
<figure>
<img src="./images/0.png" alt="imagen generada por IA de anime">
</figure>
</article>
<!-- 7 artículos más aquí -->
</section>
</main>
</body>
</html>

Utilizaremos CSS moderno (Baseline) para hacer que nuestra base sea responsive, adoptando un enfoque mobile-first:

root {
font-family: system-ui, sans-serif;
font-size: clamp(14px, 5vw, 20px);
--dark-color: #5c6378ff;
--light-color: #edf2f4ff;
--background-color: #2b2d42ff;
--secondary-color: #757e93ff;
--antiflash-white: #edf2f4ff;
--important-color: #ef233cff;
--fire-engine-red: #d90429ff;
}

body {
background-color: var(--background-color);
color: var(--light-color);
margin: 0;
}

article {
background-color: var(--light-color);
color: var(--dark-color);
padding: 1rem;
margin-bottom: 1rem;
}

article figure {
margin: 0;
}

img {
display: block;
width: 100%;
}

main {
width: 90%;
max-width: 1200px;
margin-inline: auto;
padding-block-start: 2rem;
}

Para experimentar con un diseño bento, añadimos algunos artículos y observamos que, por defecto, si nos limitamos a pocos cambios en la hoja de estilo, nuestros elementos HTML aparecerán accesibles y perfectamente utilizables: menos es más en CSS.

Bento con diseño de cuadrícula

La técnica ideal para un diseño modular compuesto por contenedores es establecer la propiedad CSS display de nuestras secciones a grid. Sin embargo, para poder jugar con la posición y la forma de los artículos, necesitaremos algunos ajustes adicionales que nos serán útiles más adelante.

.bento {
--bento-cols: 5;
--bento-rows: 3;
--bento-border-radius: 1rem;
--bento-gap: 1rem;
display: grid;
grid-template-columns: repeat(var(--bento-cols), 1fr);
grid-template-rows: repeat(var(--bento-rows), 1fr);
width: 100%;
aspect-ratio: var(--bento-cols) / var(--bento-rows);
}

.bento>* {
overflow: hidden;
position: relative;
margin: calc(var(--bento-gap) / 2);
border-radius: var(--bento-border-radius);
}

@media screen and (aspect-ratio < 1) {

.bento {
--bento-cols: 3;
--bento-rows: 5;
}
}

Hemos introducido algunas variables para controlar el número de columnas y filas. Utilizaremos estos dos valores para determinar en cuántas fracciones dividir nuestra «cuadrícula bento» y calcular la propiedad aspect-ratio, es decir, la proporción entre el ancho y la altura. Este pequeño truco nos permite tener celdas exactamente cuadradas, y será la clave de nuestra estrategia.

Una griglia css con celle tutte quadrate

Para asegurarnos de que los elementos <article> estén contenidos dentro de las celdas, hemos añadido la regla overflow: hidden.

Para mantener la flexibilidad de nuestro diseño, es importante no usar la propiedad gap de la cuadrícula, ya que esto rompe la proporción entre el ancho y la altura totales, y los módulos (los elementos en nuestro bento dejan de ser exactamente cuadrados). Utilizaremos el margen de los contenidos para espaciar los «alimentos» o elementos de nuestro bento.

Personaliza tu diseño bento

¡Finalmente llega la parte más divertida y específica de este tutorial! Personalicemos nuestra caja bento decidiendo cuántas celdas ocupará cada elemento: usando el valor span 2 en las propiedades grid-column o grid-row, podemos obtener módulos horizontales (2×1 celdas) y verticales (1×2 celdas). Combinándolos, conseguimos una celda grande cuadrada (2×2 celdas).

Estamos listos para especificar así la forma (e importancia) que tendrán nuestros <article> según el orden en el que estén en la <section>. Agregamos una clase layout-1, que será nuestra plantilla reutilizable, ¡y listo!

.bento.layout-1> :nth-child(1) {
grid-column: span 2;
grid-row: span 2;
background-color: var(--important-color);
color: var(--light-color);
}

.bento.layout-1> :nth-child(2) {
grid-row: span 2;
background-color: var(--secondary-color);
color: var(--light-color);
}

.bento.layout-1> :nth-child(3),
.bento.layout-1> :nth-child(4),
.bento.layout-1> :nth-child(8) {
grid-column: span 2;
background-color: var(--dark-color);
color: var(--light-color);
}

.bento.layout-1> :nth-child(n + 9) {
display: none;
}

Bento Layout verticale

Para pantallas verticales, es posible que debamos reorganizar nuestro diseño bento. Aprovechemos esta oportunidad para crear un diseño específico invirtiendo el número de columnas y filas, y reajustando nuestros módulos para que mantengan un equilibrio en pantallas verticales.


@media screen and (aspect-ratio < 1) {

.bento.layout-1 {
--bento-cols: 3;
--bento-rows: 5;
}

.bento.layout-1> :nth-child(n) {
/* Reset spans */
grid-column: auto;
grid-row: auto;
}

.bento.layout-1> :nth-child(1),
.bento.layout-1> :nth-child(8) {
grid-column: span 2;
grid-row: span 2;
}

.bento.layout-1> :nth-child(5) {
grid-column: span 2;
}

.bento.layout-1> :nth-child(7) {
grid-column: 1;
grid-row: 5;
}

}

Diseño de caja bento y consultas de contenedor

Y ahora, el plato fuerte de nuestro diseño bento: ¡utilicemos las container queries para dar un diseño específico a cada <article>!

Antes de personalizar los formatos individuales de nuestros elementos, preparemos una base común que facilite nuestro trabajo:

.bento>* {
display: flex;
flex-direction: column-reverse;
}

.bento.layout-1 h1, .bento.layout-1 h2, .bento.layout-1 h3, .bento.layout-1 p {
margin: 0;
}

.bento.layout-1>* figure {
position: absolute;
inset: 0;
}
.bento.layout-1>* header {
position: relative;
z-index: 1;
background-color: inherit;
}

.bento.layout-1>* figure img {
object-fit: cover;
height: 100%;
}

.bento.layout-1>* header {
position: absolute;
bottom: 0;
inset-inline: 0;
border-radius: 0;
font-size: 70%;
padding: 0.5rem;
}

¡Por fin añadimos las propiedades CSS container-type y container-name para darle a los contenidos de nuestros bento layouts el superpoder de hacer consultas sobre propiedades como width, height y, súper importante, aspect-ratio! 🚀

.bento > * {
container-type: size;
container-name: bento-item;
}

Completemos nuestro diseño bento definiendo los diferentes formatos en los que debe aparecer cada artículo. Para ello, podemos evaluar tanto las dimensiones (y, por lo tanto, ocultar algunos elementos) como las proporciones: ¿será nuestro contenedor cuadrado, vertical u horizontal? ¿Tendrá suficiente espacio para todo?

Descubramos cómo lograrlo utilizando las container queries (consultas de contenedor):


@container bento-item (width < 200px) and (height < 200px) {
.bento.layout-1>* header {
font-size: 0.7rem;
}

.bento.layout-1>* header p {
display: none;
}
}

@container bento-item (aspect-ratio > 1) {
.bento.layout-1>* header {
top: 0;
right: 60%;
}

.bento.layout-1> * figure {
inset: 0 0 0 40%;
}
}


@container bento-item (aspect-ratio = 1) and (width > 200px) {
.bento.layout-1>* header {
font-size: 120%;
background-color: #0006;
color: var(--light-color);
backdrop-filter: blur(4px);
}
}

Microanimaciones

Para dar vida a nuestro diseño bento, añadamos microanimaciones sutiles pero efectivas. Las animaciones hacen que la interfaz sea más dinámica y agradable, manteniendo siempre un enfoque minimalista que refleja la filosofía del diseño bento.

Primero, añadamos una transición fluida a todos los elementos del bento:

.bento > * {
transition: transform 0.3s ease-out, filter 0.3s ease-out;
}

Creamos un efecto de hover que eleva ligeramente el elemento y añade una sutil sombra.

.bento > *:hover {
transform: translateY(-0.5rem);
filter: drop-shadow(0 0.5rem 0.1rem #0009);
}

Para las imágenes, podemos añadir un ligero efecto de zoom combinado con un movimiento hacia abajo, logrando una especie de movimiento de cámara similar a un «dolly».

.bento.layout-1 > * figure img {
transition: transform 1s;
}

.bento.layout-1 > *:hover figure img {
transform: scale(1.50) translateY(15%);
}

Recordemos respetar las preferencias de accesibilidad del usuario desactivando las animaciones si prefers-reduced-motion está activado en el navegador:

@media (prefers-reduced-motion: reduce) {
.bento > *,
.bento.layout-1 > * header,
.bento.layout-1 > * figure img {
transition: none;
}

.bento > *:hover {
transform: none;
}

.bento.layout-1 > *:hover figure img {
transform: none;
}
}

Conclusiones

En este tutorial, hemos explorado cómo crear un diseño de caja bento moderno utilizando CSS contemporáneo. Inspirándonos en la filosofía del bento japonés, hemos construido una interfaz modular empleando:

  • CSS Grid para la estructura base, utilizando span en las propiedades grid-column y grid-row para crear módulos de diferentes tamaños.
  • La propiedad aspect-ratio para obligar a la cuadrícula a mantener las proporciones cuadradas de los módulos.
  • Consultas de contenedor (Container Queries) para adaptar el contenido a diferentes contenedores.
  • Consultas de medios (Media Queries) para controlar los diseños en orientaciones verticales.
  • Microanimaciones para dar vida a la interfaz.

La belleza de este enfoque reside en su flexibilidad: al igual que una auténtica caja bento, podemos organizar nuestros contenidos en infinitas combinaciones, manteniendo siempre el orden y el equilibrio. Hemos visto cómo las funcionalidades modernas de CSS nos permiten crear diseños complejos pero mantenibles, responsivos pero precisos, dinámicos pero accesibles.

El código de este tutorial está pensado como un punto de partida: os invito a experimentar para encontrar las recetas adecuadas para vuestro bento especial.

¡Buen provecho!

Artículos relacionados

Bajo la superficie de React: Explorando las profundidades para crear mejores desarrollos

Codemotion
junio 11, 2025

Migrando 400.000 líneas de código

Codemotion
abril 28, 2025

Zustand: Todo lo que debes saber para dominarlo

Orli Dun
enero 27, 2025

React y Tailwind CSS: La dupla perfecta para tus interfaces de usuario

Orli Dun
enero 13, 2025
Share on:facebooktwitterlinkedinreddit

Tags:CSS

Massimo Avvisati
Soy un desarrollador full stack, artista digital, maker y educador con una pasión por la Inteligencia Artificial. Creo instalaciones inmersivas y desarrollo software educativo, empujando los límites de la tecnología. Creo en el Software Libre y en las licencias Creative Commons como base para el intercambio de conocimientos. Mi objetivo es crear experiencias educativas únicas y atractivas utilizando tecnología de vanguardia, demostrando el potencial de la tecnología en la educación. En la actualidad, mi enfoque está en la Tecnología Educativa, donde me esfuerzo por crear herramientas de software y hardware innovadoras que comprometan e inspiren a los estudiantes. Creo firmemente…
Construyendo componentes agnósticos con CVA y Tailwind
Artículo anterior
¿Robots Jueces? Captcha y la IA
Próximo artículo

Footer

Discover

  • Events
  • Community
  • Partners
  • Become a partner
  • Hackathons

Magazine

  • Tech articles

Talent

  • Discover talent
  • Jobs

Companies

  • Discover companies

For Business

  • Codemotion for companies

About

  • About us
  • Become a contributor
  • Work with us
  • Contact us

Follow Us

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions