Chào mừng các bạn đến với Rcom Dăm Yi blog - Kho tài liệu bổ ích!, Chúng tôi sẽ từng bước hoàn thiện để bạn đọc cảm thấy hài lòng, hữu ích!

Thứ Sáu, 23 tháng 1, 2026

Bài 9: CSS Grid – Bố cục 2 chiều + Responsive cơ bản

🎯 Mục tiêu

  • Hiểu CSS Grid là gì và khác Flexbox ở điểm nào
  • Biết tạo lưới bằng display: grid
  • Biết dùng: grid-template-columns, gap, repeat(), minmax()
  • Biết responsive cơ bản để grid tự co theo màn hình

📘 Lý thuyết ngắn

1) Khi nào dùng Grid?

  • Dùng Grid khi bạn cần bố cục 2 chiều (hàng và cột)
  • Dùng Flexbox khi bạn cần sắp xếp 1 chiều (hàng hoặc cột)

2) Ví dụ grid cơ bản


.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 12px;
}
    

3) Responsive grid “tự co” bằng minmax


grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    

Ý nghĩa: mỗi cột tối thiểu 220px, nếu đủ chỗ thì tự tăng và tự xếp thêm cột. Khi màn hình nhỏ, nó tự giảm số cột xuống 2 → 1.

🧾 Thuộc tính Grid hay dùng

Thuộc tính Ý nghĩa Ví dụ
display Bật Grid display: grid;
grid-template-columns Khai báo số cột 1fr 1fr 1fr
gap Khoảng cách giữa ô gap: 16px;
repeat() Lặp cột nhanh repeat(3, 1fr)
minmax() Min–max của cột minmax(220px, 1fr)

💻 Code mẫu (Gallery card bằng Grid + JS lọc nhanh)


<!doctype html>
<html lang="vi">
<head>
  <meta charset="utf-8">
  <title>Bài 9 - CSS Grid</title>

  <style>
    body{
      font-family: Arial;
      padding: 24px;
      background: #f7f8fa;
      line-height: 1.7;
    }

    .wrap{
      max-width: 1000px;
      margin: 0 auto;
    }

    h1{
      text-align: center;
      margin-top: 0;
    }

    .toolbar{
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      justify-content: center;
      margin: 14px 0 18px;
    }

    .btn{
      padding: 10px 14px;
      border: 0;
      border-radius: 10px;
      cursor: pointer;
      background: #111;
      color: #fff;
      font-weight: 600;
    }

    .btn.blue{ background:#2563eb; }
    .btn.gray{ background:#374151; }

    .grid{
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
      gap: 16px;
    }

    .card{
      background: #fff;
      border: 1px solid #e5e5e5;
      border-radius: 12px;
      padding: 14px;
    }

    .thumb{
      width: 100%;
      height: 140px;
      border-radius: 12px;
      background: #e5e7eb;
      display:flex;
      align-items:center;
      justify-content:center;
      font-weight: 700;
      color:#111;
      margin-bottom: 10px;
    }

    .tag{
      display:inline-block;
      font-size: 12px;
      padding: 2px 10px;
      border-radius: 999px;
      background:#eef2ff;
      border:1px solid #dbeafe;
      margin-right: 6px;
    }

    .hidden{ display:none; }
  </style>
</head>

<body>
  <div class="wrap">
    <h1>Gallery card bằng CSS Grid</h1>

    <div class="toolbar">
      <button class="btn blue" data-filter="all">Tất cả</button>
      <button class="btn" data-filter="html">HTML</button>
      <button class="btn" data-filter="css">CSS</button>
      <button class="btn gray" data-filter="js">JavaScript</button>
    </div>

    <div class="grid" id="grid">
      <div class="card" data-cat="html">
        <div class="thumb">HTML</div>
        <h3>Bài HTML</h3>
        <p>Tạo cấu trúc trang.</p>
        <span class="tag">html</span>
      </div>

      <div class="card" data-cat="css">
        <div class="thumb">CSS</div>
        <h3>Bài CSS</h3>
        <p>Làm đẹp giao diện.</p>
        <span class="tag">css</span>
      </div>

      <div class="card" data-cat="js">
        <div class="thumb">JS</div>
        <h3>Bài JavaScript</h3>
        <p>Tạo tương tác.</p>
        <span class="tag">js</span>
      </div>

      <div class="card" data-cat="css">
        <div class="thumb">CSS</div>
        <h3>Grid nâng cao</h3>
        <p>Lưới tự co theo màn hình.</p>
        <span class="tag">css</span>
      </div>

      <div class="card" data-cat="html">
        <div class="thumb">HTML</div>
        <h3>Semantic</h3>
        <p>Viết HTML chuẩn ý nghĩa.</p>
        <span class="tag">html</span>
      </div>
    </div>
  </div>

  <script>
    const buttons = document.querySelectorAll(".toolbar .btn");
    const cards = document.querySelectorAll(".card");

    buttons.forEach(btn => {
      btn.addEventListener("click", () => {
        const filter = btn.dataset.filter;

        cards.forEach(card => {
          const cat = card.dataset.cat;
          if(filter === "all" || cat === filter){
            card.classList.remove("hidden");
          } else {
            card.classList.add("hidden");
          }
        });
      });
    });
  </script>
</body>
</html>
    

👉 Copy code → lưu thành bai9.html → mở bằng Chrome.
Thử thu nhỏ màn hình để thấy số cột tự đổi. Bấm nút lọc để ẩn/hiện card.

✍️ Bài tập

  1. Thêm ít nhất 3 card mới (tự đặt nội dung).
  2. Đổi minmax(220px, 1fr) thành minmax(280px, 1fr) và quan sát thay đổi.
  3. Thêm nút lọc “CSS + JS” (hiển thị cả 2 loại).
  4. (Nâng cao) Khi đang lọc, làm nút đang chọn đổi màu.

✅ Đáp án gợi ý

1) Nút lọc CSS + JS


<button class="btn" data-filter="cssjs">CSS + JS</button>
    

2) Xử lý trong JS


if(filter === "cssjs"){
  if(cat === "css" || cat === "js"){
    card.classList.remove("hidden");
  } else {
    card.classList.add("hidden");
  }
}
    

3) Đổi màu nút đang chọn (gợi ý)


buttons.forEach(b => b.classList.remove("active"));
btn.classList.add("active");
    

Không có nhận xét nào:

Đăng nhận xét

Bài đăng phổ biến

💬 Bình luận

💬 Bình luận

📌 Danh sách bình luận