Đang tải...

Ếch Trendy

Cùng chú ếch nhỏ khám phá thế giới Web đầy biến động. Cập nhật trending nhanh như cách ếch đớp mồi! ⌨️🌿


0

Bento Grid trong UI web: vì sao dev đang áp dụng nhiều cho landing page và dashboard

Ếch Trendy
Ếch Trendy

3 tháng trước · 9 phút đọc

Bento grid là gì và tại sao nó xuất hiện khắp nơi

Mở Twitter hay Dribbble bất kỳ ngày nào trong năm nay, bạn sẽ thấy cùng một pattern: những ô vuông và chữ nhật xếp cạnh nhau không đều, mỗi ô giữ một mảnh thông tin, tổng thể nhìn như hộp cơm bento Nhật. Đó chính là bento grid.

Apple popularize pattern này ở trang sản phẩm Mac và iPhone - nơi họ dùng những card kích thước khác nhau để highlight từng tính năng riêng biệt. Sau đó landing page của Linear, Vercel, Resend bắt đầu copy. Rồi đến dashboard. Rồi đến portfolio.

344894 Apple dùng bento grid để highlight từng tính năng mà không làm trang trở nên lộn xộn

Vấn đề bento grid giải quyết thực ra rất cụ thể: làm sao hiển thị nhiều loại thông tin không đồng nhất trên cùng một màn hình mà người dùng vẫn quét được ngay. Layout lưới truyền thống (equal columns, equal rows) bắt mọi nội dung phải có cùng trọng số. Bento grid thì không - ô lớn = thông tin quan trọng hơn, ô nhỏ = thông tin bổ trợ. Hierarchy được mã hóa ngay vào kích thước.

Nói thẳng: bento grid không phải xu hướng thẩm mỹ thuần túy. Nó là giải pháp cho bài toán information architecture cụ thể.


Khi nào bento grid thực sự giúp ích, khi nào chỉ làm màu

Bento grid không phải silver bullet. Có use case nó phù hợp, có use case dùng vào là hại.

Phù hợp:

  • Landing page feature section: Khi bạn có 4-6 tính năng với trọng số khác nhau (1-2 tính năng chủ lực + vài tính năng phụ), bento grid cho phép hierarchy trực quan mà không cần heading size khổng lồ.
  • Dashboard overview: Analytics dashboard cần hiển thị metric, chart, và table cùng lúc. Bento grid tổ chức được heterogeneous content (nội dung không đồng nhất) tốt hơn equal-column layout.
  • Portfolio gallery: Ảnh hay case study có tỉ lệ khác nhau, bento grid tránh được white space lãng phí.
  • About page hoặc team page: Card người + số liệu + quote xen kẽ nhau tạo cảm giác editorial thay vì catalog.

Không phù hợp:

  • Danh sách đồng nhất (product list, blog list): Khi mọi item có cùng tầm quan trọng, bento grid tạo hierarchy giả tạo, gây confusion.
  • Content dài dạng article: Người đọc cần linear flow, không cần scan nhiều ô cùng lúc.
  • Mobile-first content: Bento grid phức tạp trên màn nhỏ nếu không được thiết kế responsive từ đầu.

344895 Use case đúng quyết định 80% thành công của bento grid

Dấu hiệu bạn đang dùng bento grid chỉ để làm đẹp: chia ô xong nhồi chữ vào đầy, hoặc mọi ô đều cùng màu cùng loại content. Lúc đó layout chỉ là decoration, không có giá trị cognitive nào.


Cách chia khối và cân bằng khoảng trắng trong bento grid

Phần này là nơi nhiều người implement sai nhất.

Quy tắc span:

Bento grid về cơ bản là CSS Grid với grid-column: span Ngrid-row: span N. Điểm khác biệt là bạn chủ động kiểm soát kích thước từng cell thay vì để auto-fill đều nhau.

Một template phổ biến cho feature section:

.bento-grid {
  display: grid;
  /* 4 cột bằng nhau, gap 16px */
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

/* Card chủ lực - chiếm 2 cột, 2 hàng */
.card-hero {
  grid-column: span 2;
  grid-row: span 2;
}

/* Card ngang - chiếm 2 cột, 1 hàng */
.card-wide {
  grid-column: span 2;
}

/* Card nhỏ mặc định - 1 cột, 1 hàng */
.card-small {
  grid-column: span 1;
}

Gap là thứ tạo ra "bento feel":

Gap đồng đều (không phải margin không đều) là thứ tạo ra visual identity của bento. Thông thường dùng gap: 12px đến gap: 20px. Nhỏ quá thì trông chật, to quá thì mất liên kết.

344896 Gap đồng đều tạo ra cảm giác có tổ chức - không phải màu sắc hay icon

Khoảng trắng bên trong (padding):

Mỗi card cần padding đủ để content không sát mép. Công thức đơn giản: padding bên trong = 1.5x gap bên ngoài. Nếu gap là 16px, padding card là 24px. Cảm giác "thoáng" đến từ tỉ lệ này.

Đừng nhồi nội dung:

Mỗi ô chỉ cần một ý - icon + heading + 1-2 dòng text, hoặc một số liệu lớn + label, hoặc một chart nhỏ. Khi ô có 3-4 loại content khác nhau, nó trở thành một landing page mini bên trong landing page.


Ví dụ HTML/CSS thực tế - feature section kiểu Apple

Mình build một feature section bento grid hoàn chỉnh, responsive, không dùng framework nào ngoài CSS thuần.

Demo tương tác đầy đủ bạn có thể tải về hoặc fork tại đây: Tải file demo bento grid

Còn đây là phần core CSS và structure để bạn hiểu logic:

<section class="bento-section">
  <div class="bento-grid">
    <!-- Card chủ lực: chiếm 2 cột 2 hàng -->
    <div class="card card-hero">
      <span class="card-icon"></span>
      <h3>Tốc độ vượt trội</h3>
      <p>Load dưới 1 giây với Edge network toàn cầu</p>
      <div class="card-stat">99.9%</div>
      <div class="card-stat-label">uptime SLA</div>
    </div>

    <!-- Card ngang: 2 cột 1 hàng -->
    <div class="card card-wide">
      <span class="card-icon">🔒</span>
      <h3>Bảo mật mặc định</h3>
      <p>End-to-end encryption, SOC 2 certified</p>
    </div>

    <!-- 2 card nhỏ -->
    <div class="card card-small">
      <span class="card-icon">📊</span>
      <h3>Analytics</h3>
      <p>Realtime dashboard</p>
    </div>

    <div class="card card-small">
      <span class="card-icon">🔗</span>
      <h3>API đơn giản</h3>
      <p>RESTful, có SDK</p>
    </div>
  </div>
</section>
.bento-section {
  max-width: 1100px;
  margin: 0 auto;
  padding: 4rem 1.5rem;
}

.bento-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

.card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 16px;
  padding: 1.5rem;
}

/* Card chiếm 2 cột 2 hàng */
.card-hero {
  grid-column: span 2;
  grid-row: span 2;
  background: #0f172a;
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/* Card chiếm 2 cột */
.card-wide {
  grid-column: span 2;
}

.card-stat {
  font-size: 3rem;
  font-weight: 700;
  line-height: 1;
  margin-top: auto;
}

/* Responsive: 2 cột trên tablet */
@media (max-width: 768px) {
  .bento-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Card hero vẫn chiếm 2 cột */
  .card-hero {
    grid-column: span 2;
    grid-row: span 1; /* Reset span hàng trên mobile */
  }

  .card-wide {
    grid-column: span 2;
  }
}

/* Mobile: 1 cột */
@media (max-width: 480px) {
  .bento-grid {
    grid-template-columns: 1fr;
  }

  .card-hero,
  .card-wide {
    grid-column: span 1;
  }
}

344897 Responsive quan trọng hơn visual - mobile cần reset grid-row span

Điểm quan trọng nhất trong code trên: mobile phải reset grid-row: span. Nếu không, card hero vẫn chiếm 2 hàng trên màn hình 1 cột, tạo ra khoảng trắng khổng lồ bên cạnh. Đây là bug phổ biến nhất khi implement bento grid responsive.

Nếu bạn đang học CSS Grid bài bản, khóa Responsive Với Grid System cover chi tiết phần grid layout và responsive - miễn phí và thực hành ngay trên browser.


Bento grid vs layout lưới truyền thống: chọn cái nào?

Không phải bento grid tốt hơn lưới truyền thống. Chúng giải quyết vấn đề khác nhau.

Lưới truyền thống Bento Grid
Content Đồng nhất (cùng loại) Hỗn hợp (nhiều loại)
Hierarchy Bằng phẳng Có trọng số rõ ràng
Responsive Đơn giản hơn Cần kế hoạch kỹ
Scan pattern Top-to-bottom F-pattern hoặc Z-pattern
Ví dụ dùng Blog list, product list Feature section, dashboard
Maintenance Dễ thêm item mới Cần điều chỉnh khi thêm

Một quy tắc đơn giản: nếu bạn có thể dùng grid-template-columns: repeat(3, 1fr) và mọi thứ trông ổn - dùng lưới truyền thống. Nếu bạn cần nhấn mạnh một số item hơn số khác, và content có nhiều dạng khác nhau - bento grid đáng thử.

344898 Chọn layout theo nhu cầu thông tin, không phải theo trend

Về mặt kỹ thuật, bento grid trên Tailwind CSS cũng khá gọn:

<div class="grid grid-cols-4 gap-4">
  <!-- Card hero 2x2 -->
  <div class="col-span-2 row-span-2 bg-slate-900 text-white rounded-2xl p-6">
    <h3 class="text-2xl font-bold">Tính năng chính</h3>
    <div class="text-5xl font-black mt-auto">99.9%</div>
  </div>

  <!-- Card ngang -->
  <div class="col-span-2 bg-white border rounded-2xl p-6">
    <h3 class="font-semibold">Bảo mật</h3>
  </div>

  <!-- 2 card nhỏ -->
  <div class="bg-white border rounded-2xl p-6">Analytics</div>
  <div class="bg-white border rounded-2xl p-6">API</div>
</div>

Nếu chưa quen Tailwind, khóa Tailwind CSS miễn phí trên F8 - sau khoảng 4-5 bài là bạn viết được bento grid bằng utility class thoải mái.


Bắt đầu áp dụng bento grid đúng cách

Ba bước để implement bento grid không bị sai:

1. Phân loại content trước khi code

Liệt kê tất cả nội dung cần hiển thị. Đánh dấu cái nào là primary (1-2 items), cái nào là secondary, cái nào là supporting. Kích thước card map trực tiếp vào phân loại này - primary = card lớn, không phải theo ý thích.

2. Thiết kế mobile trước

Bento grid ở desktop trông đẹp, nhưng nếu không plan responsive từ đầu, mobile sẽ vỡ. Bắt đầu từ single column, rồi mở rộng ra 2, 4 cột. Nhớ reset grid-row: span khi về 1 cột.

3. Test bằng cách che màu sắc

Xem layout bằng grayscale. Nếu hierarchy vẫn rõ ràng khi không có màu - layout tốt. Nếu phải dựa vào màu để phân biệt quan trọng/không quan trọng - cần điều chỉnh kích thước card.

344899 Ba bước này cắt 90% bug bento grid gặp phải trong thực tế

Một checklist nhanh trước khi ship:

  • [ ] Mỗi card chỉ chứa một ý duy nhất
  • [ ] Gap đồng đều (không dùng margin hỗn độn)
  • [ ] Padding bên trong = 1.5x gap bên ngoài
  • [ ] Đã test responsive trên 3 breakpoint
  • [ ] Card hero không chiếm quá 50% diện tích tổng
  • [ ] Có thể đọc hierarchy khi xem grayscale

Tải checklist đầy đủ tại đây: Tải checklist bento grid

Bento grid phổ biến vì nó trả lời câu hỏi cụ thể: làm sao người dùng quét được thông tin quan trọng nhất trong 3 giây đầu? Nếu bạn build landing page hay dashboard mà đang dùng equal columns cho mọi thứ - đây là lúc thử một cách khác.