Bài 9.5: Bài tập thực hành CSS Grid

Bài 9.5: Bài tập thực hành CSS Grid
Chào mừng trở lại với chuỗi bài blog về Lập trình Web Front-end!
Sau khi đã làm quen với những khái niệm cơ bản và sức mạnh khủng khiếp của CSS Grid trong việc tạo bố cục hai chiều, đã đến lúc chúng ta không chỉ nói lý thuyết nữa. Hãy xắn tay áo lên và cùng nhau đi sâu vào thực hành qua các bài tập cụ thể để thật sự làm chủ công cụ layout đỉnh cao này!
Mục tiêu của bài viết này là giúp bạn:
- Củng cố kiến thức về các thuộc tính CSS Grid quan trọng.
- Hiểu rõ hơn cách áp dụng Grid vào các kịch bản layout thực tế.
- Tăng sự tự tin khi đối mặt với các yêu cầu bố cục phức tạp.
Chúng ta sẽ bắt đầu với những bài tập đơn giản và dần nâng độ khó lên. Hãy chuẩn bị môi trường code của bạn (một file HTML và một file CSS là đủ!) và cùng bắt đầu nào!
Bài Tập 1: Bố Cục Cơ Bản - 3 Cột Đều Nhau
Yêu cầu: Tạo một hàng ngang chứa 3 phần tử con có chiều rộng bằng nhau, có khoảng cách giữa chúng.
Đây là bài tập khởi động nhẹ nhàng để bạn làm quen lại với việc thiết lập Grid Container và Grid Items.
HTML:
<div class="grid-container-1">
<div class="grid-item">Item 1</div>
<div class="grid-item">Item 2</div>
<div class="grid-item">Item 3</div>
</div>
CSS:
.grid-container-1 {
display: grid; /* Biến phần tử cha thành Grid Container */
/* Định nghĩa 3 cột với chiều rộng bằng nhau.
1fr có nghĩa là 1 phần của không gian trống có sẵn. */
grid-template-columns: 1fr 1fr 1fr;
/* Hoặc cách viết ngắn gọn hơn: */
/* grid-template-columns: repeat(3, 1fr); */
/* Tạo khoảng cách giữa các items */
gap: 10px;
padding: 10px; /* Thêm padding để dễ nhìn */
border: 1px solid #ccc;
}
.grid-item {
background-color: #f0f0f0;
border: 1px solid #d0d0d0;
padding: 20px;
text-align: center;
}
Giải thích:
display: grid;
: Thuộc tính quan trọng nhất để biếndiv.grid-container-1
thành một lưới (grid).grid-template-columns: 1fr 1fr 1fr;
: Thuộc tính này định nghĩa số lượng và chiều rộng của các cột.1fr
(fraction unit) đại diện cho một phần tự do của không gian còn lại trong container. Khi cả 3 cột đều là1fr
, chúng sẽ chia đều không gian đó.repeat(3, 1fr);
: Là cách viết ngắn gọn và thanh lịch hơn của1fr 1fr 1fr
. Nó lặp lại mẫu1fr
3 lần.gap: 10px;
: Thuộc tính này tạo khoảng cách (gutter) giữa các hàng và các cột trong lưới.
Thấy không? Chỉ với vài dòng CSS, chúng ta đã có ngay một bố cục cột đều nhau cực kỳ gọn gàng!
Bài Tập 2: Layout Với Cột Cố Định và Cột Linh Hoạt
Yêu cầu: Tạo một bố cục hai cột, trong đó cột bên trái có chiều rộng cố định (ví dụ: 200px) và cột bên phải chiếm toàn bộ không gian còn lại.
Đây là một layout rất phổ biến cho các trang web có sidebar.
HTML:
<div class="grid-container-2">
<div class="grid-item sidebar">Sidebar (200px)</div>
<div class="grid-item main-content">Nội dung chính (chiếm phần còn lại)</div>
</div>
CSS:
.grid-container-2 {
display: grid;
/* Cột đầu tiên cố định 200px, cột thứ hai chiếm 1 phần tự do (toàn bộ phần còn lại) */
grid-template-columns: 200px 1fr;
gap: 15px; /* Tăng khoảng cách một chút */
padding: 10px;
border: 1px solid #ccc;
}
.grid-item {
background-color: #e9e9ff; /* Màu khác để phân biệt */
border: 1px solid #c0c0ee;
padding: 20px;
text-align: center;
/* Đảm bảo nội dung đủ dài để thấy rõ layout */
min-height: 100px;
}
.sidebar {
background-color: #ffe9e9;
}
Giải thích:
grid-template-columns: 200px 1fr;
: Ở đây, chúng ta kết hợp đơn vị cố định (px
) với đơn vị linh hoạt (fr
). Cột đầu tiên sẽ luôn rộng 200px, bất kể kích thước container, trong khi cột thứ hai sẽ tự động co giãn để lấp đầy toàn bộ không gian còn lại sau khi cột đầu tiên đã chiếm 200px. Đây là sức mạnh củafr
!
Layout sidebar-content chỉ trong một dòng CSS? Quá đỉnh!
Bài Tập 3: Bố Cục Nhiều Hàng và Cột Với grid-area
Yêu cầu: Xây dựng một bố cục trang web cổ điển gồm Header, Navigation (menu), Main Content và Footer, sử dụng thuộc tính grid-area
để định vị các khu vực.
grid-area
là một cách cực kỳ trực quan để "vẽ" bố cục của bạn ngay trong CSS.
HTML:
<div class="grid-container-3">
<header class="grid-item" style="background-color: #ffd700;">Header</header>
<nav class="grid-item" style="background-color: #add8e6;">Navigation</nav>
<main class="grid-item" style="background-color: #90ee90;">Main Content</main>
<footer class="grid-item" style="background-color: #ffb6c1;">Footer</footer>
</div>
CSS:
.grid-container-3 {
display: grid;
/* Định nghĩa các "khu vực" (areas) của layout bằng tên */
grid-template-areas:
"header header header" /* Hàng 1: 3 cột đều là 'header' */
"nav main main" /* Hàng 2: cột 1 là 'nav', cột 2&3 là 'main' */
"footer footer footer"; /* Hàng 3: 3 cột đều là 'footer' */
/* Định nghĩa số lượng và chiều rộng/cao của các cột/hàng */
grid-template-columns: 150px 1fr 1fr; /* Cột nav cố định, 2 cột còn lại linh hoạt */
grid-template-rows: auto 1fr auto; /* Hàng header/footer tự co giãn theo nội dung, hàng main chiếm phần còn lại */
gap: 10px; /* Khoảng cách giữa các khu vực */
min-height: 400px; /* Đặt chiều cao tối thiểu để thấy rõ layout */
padding: 10px;
border: 1px solid #ccc;
}
/* Gán tên "khu vực" đã định nghĩa ở trên cho từng phần tử */
header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: footer; }
.grid-container-3 .grid-item {
border: 1px solid #d0d0d0;
padding: 20px;
text-align: center;
/* Xóa màu nền ở .grid-item chung nếu đã đặt màu riêng cho từng khu vực */
background-color: initial;
}
Giải thích:
grid-template-areas
: Đây là "bản đồ" trực quan của layout. Mỗi chuỗi trong ngoặc kép là một hàng. Tên lặp lại trong cùng một hàng cho biết phần tử đó sẽ trải dài qua các cột tương ứng. Dấu chấm (.
) có thể dùng để bỏ trống một ô trong lưới.grid-template-columns
: Định nghĩa 3 cột: 150px, 1fr, 1fr. Điều này khớp với 3 "vị trí" trong mỗi hàng củagrid-template-areas
.grid-template-rows
: Định nghĩa 3 hàng:auto
(chiều cao tự động theo nội dung của header/footer), và1fr
(hàng main chiếm phần còn lại).grid-area: <tên>;
: Thuộc tính này gán một phần tử con vào "khu vực" có tên tương ứng đã định nghĩa tronggrid-template-areas
.
Cách này giúp bạn nhìn thấy cấu trúc layout của mình bằng "mắt thường" ngay trong CSS. Cực kỳ tiện lợi khi làm việc với bố cục phức tạp!
Bài Tập 4: Căn Chỉnh Các Items Trong Grid Cell
Yêu cầu: Tạo một lưới và thực hành căn chỉnh các phần tử con cả theo chiều ngang và chiều dọc bên trong ô lưới của chúng.
CSS Grid cung cấp các thuộc tính căn chỉnh mạnh mẽ không chỉ cho các items riêng lẻ mà còn cho cả lưới.
HTML:
<div class="grid-container-4">
<div class="grid-item" style="width: 50px; height: 50px;">Center</div>
<div class="grid-item" style="width: 70px;">End</div>
<div class="grid-item" style="height: 60px;">Start</div>
<div class="grid-item">Stretch</div>
</div>
CSS:
.grid-container-4 {
display: grid;
grid-template-columns: repeat(2, 1fr); /* Lưới 2 cột */
grid-template-rows: repeat(2, 100px); /* Lưới 2 hàng cố định 100px */
gap: 10px;
/* Căn chỉnh tất cả items trong container theo chiều ngang (trong ô của chúng) */
justify-items: center; /* center, start, end, stretch */
/* Căn chỉnh tất cả items trong container theo chiều dọc (trong ô của chúng) */
align-items: center; /* center, start, end, stretch */
padding: 10px;
border: 1px solid #ccc;
}
/* Có thể ghi đè căn chỉnh cho từng item riêng lẻ bằng justify-self, align-self */
.grid-container-4 .grid-item:nth-child(2) {
justify-self: end; /* Item thứ 2 căn sang phải trong ô của nó */
}
.grid-container-4 .grid-item:nth-child(3) {
align-self: start; /* Item thứ 3 căn lên trên trong ô của nó */
}
.grid-container-4 .grid-item:nth-child(4) {
/* Mặc định là stretch nếu item không có kích thước cố định */
justify-self: stretch;
align-self: stretch;
}
.grid-container-4 .grid-item {
background-color: #d4edda;
border: 1px solid #c3e6cb;
padding: 10px;
/* text-align: center; Không cần text-align nếu dùng justify-items/align-items center */
}
Giải thích:
justify-items
: Điều khiển cách các item được căn chỉnh dọc theo trục ngang (inline axis) bên trong ô lưới của chúng. Các giá trị phổ biến làstart
,end
,center
,stretch
(mặc định).align-items
: Điều khiển cách các item được căn chỉnh dọc theo trục dọc (block axis) bên trong ô lưới của chúng. Các giá trị tương tự:start
,end
,center
,stretch
(mặc định).justify-self
,align-self
: Các thuộc tính này áp dụng cho từng item riêng lẻ, cho phép bạn ghi đè cài đặtjustify-items
vàalign-items
của container cho item đó.
Với các thuộc tính căn chỉnh này, việc đặt nội dung vào đúng vị trí mong muốn bên trong từng "ô" của lưới trở nên cực kỳ dễ dàng!
Bài Tập 5: Tự Động Tạo Cột Responsive Với auto-fit
và minmax()
Yêu cầu: Tạo một lưới các phần tử có chiều rộng tối thiểu, và lưới sẽ tự động điều chỉnh số lượng cột (thêm hoặc bớt) tùy thuộc vào chiều rộng của màn hình, mà không cần dùng Media Queries phức tạp.
Đây là một trong những kỹ thuật thần thánh nhất của CSS Grid để tạo layout responsive một cách nhẹ nhàng.
HTML:
<div class="grid-container-5">
<div class="grid-item">Item 1</div>
<div class="grid-item">Item 2</div>
<div class="grid-item">Item 3</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Item 5</div>
<div class="grid-item">Item 6</div>
<div class="grid-item">Item 7</div>
<div class="grid-item">Item 8</div>
</div>
CSS:
.grid-container-5 {
display: grid;
/* repeat(auto-fit, ...) là ma thuật chính!
Nó sẽ tự động tạo CỘT dựa trên không gian có sẵn.
minmax(250px, 1fr) định nghĩa kích thước của mỗi cột:
- Chiều rộng tối thiểu (min) là 250px.
- Chiều rộng tối đa (max) là 1fr (chiếm 1 phần không gian trống).
Kết hợp lại, các cột sẽ co giãn nhưng không nhỏ hơn 250px.
Khi không còn đủ chỗ cho cột 250px nữa, nó sẽ tự động xuống hàng mới. */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
padding: 10px;
border: 1px solid #ccc;
}
.grid-container-5 .grid-item {
background-color: #fffacd;
border: 1px solid #eee8aa;
padding: 20px;
text-align: center;
min-height: 80px; /* Đặt chiều cao để dễ hình dung */
}
Giải thích:
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
: Đây là cú pháp vô cùng mạnh mẽ.repeat()
: Lặp lại một mẫu.auto-fit
: Từ khóa này bảo Grid hãy tự động tính toán số lần lặp lại dựa trên kích thước container và kích thước của các items. Nó sẽ mở rộng các items để lấp đầy không gian trống nếu còn (sau khi tất cả items đạt min width). (Lưu ý:auto-fill
là một lựa chọn khác, nó sẽ tạo ra các cột "trống" nếu không đủ item, thường dùngauto-fit
hơn cho responsive layouts).minmax(250px, 1fr)
: Đây là kích thước của mỗi cột được tạo ra bởirepeat
. Nó nói rằng cột đó phải ít nhất là 250px, nhưng tối đa có thể rộng bằng 1 phần không gian trống (1fr
).
- Kết quả: Khi container đủ rộng, Grid sẽ xếp nhiều cột 250px nhất có thể vào một hàng. Nếu còn không gian trống, các cột đó sẽ tự co giãn để lấp đầy (nhờ
1fr
). Khi thu nhỏ container, nếu không còn đủ 250px cho một cột nữa, cột đó sẽ tự động "nhảy" xuống hàng tiếp theo. Responsive mà không cần nhiều Media Queries!
Comments