Responsive Web Design
Responsive design là kỹ thuật thiết kế web hiển thị tốt trên mọi kích thước màn hình — từ điện thoại nhỏ đến màn hình rộng — bằng cách điều chỉnh layout và nội dung tự động.
Viewport meta tag
Bắt buộc có trong <head> của mọi trang responsive:
<meta name="viewport" content="width=device-width, initial-scale=1">
Không có tag này, trình duyệt di động sẽ thu nhỏ toàn bộ trang.
Mobile-first
Triết lý mobile-first: viết CSS mặc định cho màn hình nhỏ, rồi mở rộng lên màn hình lớn bằng min-width.
/* Mặc định: layout 1 cột (mobile) */
.container { flex-direction: column; }
/* Màn hình >= 768px: 2 cột */
@media (min-width: 768px) {
.container { flex-direction: row; }
}
Ngược lại là desktop-first — dùng
max-width. Ít phổ biến hơn.
Media queries
@media (min-width: 768px) { /* >= 768px */ }
@media (max-width: 767px) { /* <= 767px */ }
@media (min-width: 600px) and (max-width: 900px) { /* khoảng giữa */ }
@media (orientation: landscape) { /* nằm ngang */ }
@media (prefers-color-scheme: dark) { /* dark mode OS */ }
Breakpoints phổ biến
| Tên | Giá trị | Thiết bị |
|---|---|---|
| xs | < 576px | Điện thoại nhỏ |
| sm | ≥ 576px | Điện thoại lớn |
| md | ≥ 768px | Tablet |
| lg | ≥ 992px | Desktop |
| xl | ≥ 1200px | Màn hình rộng |
Đơn vị tương đối
| Đơn vị | Tương đối theo |
|---|---|
% |
Kích thước cha |
em |
font-size phần tử cha |
rem |
font-size của <html> |
vw |
1% chiều rộng viewport |
vh |
1% chiều cao viewport |
Các kỹ thuật responsive cơ bản
/* Container có max-width */
.container { max-width: 1200px; margin: 0 auto; padding: 0 16px; }
/* Ảnh responsive */
img { max-width: 100%; height: auto; }
/* Grid responsive (không cần media query) */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
clamp() cho fluid typography
/* font-size tối thiểu 1rem, lý tưởng 2.5vw, tối đa 1.5rem */
h1 { font-size: clamp(1rem, 2.5vw, 1.5rem); }
$\text{clamp}(min, val, max)$ — kẹp giá trị trong khoảng $[min, max]$.
Demo: 1 cột → 2 cột khi >= 600px
<div class="page-container">
<header class="r-header">Header</header>
<div class="r-body">
<main class="r-main">
<h2>Main Content</h2>
<p>Đây là vùng nội dung chính. Trên mobile hiển thị toàn chiều rộng, trên màn hình lớn hơn sẽ ở bên phải sidebar.</p>
</main>
<aside class="r-sidebar">
<h3>Sidebar</h3>
<p>Nội dung phụ</p>
</aside>
</div>
<footer class="r-footer">Footer</footer>
</div>
* { box-sizing: border-box; }
body { font-family: sans-serif; margin: 0; padding: 8px; }
h2, h3 { margin: 0 0 .5rem; }
.page-container { max-width: 800px; margin: 0 auto; }
.r-header { background: #4472c4; color: white; padding: 12px 16px; border-radius: 4px; margin-bottom: 8px; font-weight: bold; }
.r-footer { background: #595959; color: white; padding: 10px 16px; border-radius: 4px; margin-top: 8px; text-align: center; }
/* Mobile mặc định: 1 cột dọc */
.r-body { display: flex; flex-direction: column; gap: 8px; }
.r-main { background: #f0f4ff; padding: 16px; border-radius: 4px; }
.r-sidebar { background: #d4edda; padding: 16px; border-radius: 4px; }
/* >= 600px: 2 cột ngang */
@media (min-width: 600px) {
.r-body { flex-direction: row; }
.r-main { flex: 2; }
.r-sidebar { flex: 1; }
}
Gợi ý: dùng nút
2 cộthoặc1 cột, kéo thanh chia ở giữa, rồi kéo mép phải vùng preview để xem layout thay đổi theo nhiều kích thước khác nhau.
Demo: Fluid typography với clamp()
<div class="demo-wrap">
<h1 class="fluid-h1">Tiêu đề fluid (clamp)</h1>
<h2 class="fluid-h2">Tiêu đề phụ fluid</h2>
<p class="fluid-body">Đoạn văn bản body dùng clamp để font tự điều chỉnh theo chiều rộng viewport.</p>
<code style="display:block;margin-top:1rem;font-size:.8rem">
h1: clamp(1.5rem, 5vw, 3rem)<br>
h2: clamp(1.2rem, 3.5vw, 2rem)<br>
p: clamp(0.875rem, 1.5vw, 1.125rem)
</code>
<div class="fixed-comparison">
<div>
<p class="compare-label">Fixed px</p>
<h2 class="fixed-h2">Tiêu đề cố định 24px</h2>
<p class="fixed-body">Body cố định 16px — không thay đổi theo viewport</p>
</div>
<div>
<p class="compare-label">Fluid clamp()</p>
<h2 class="fluid-h2-sm">Tiêu đề fluid</h2>
<p class="fluid-body-sm">Body fluid — tự điều chỉnh</p>
</div>
</div>
</div>
body { font-family: sans-serif; padding: 1rem; margin: 0; }
.demo-wrap { max-width: 100%; }
.fluid-h1 { font-size: clamp(1.5rem, 5vw, 3rem); margin: 0 0 .25rem; color: #4472c4; }
.fluid-h2 { font-size: clamp(1.2rem, 3.5vw, 2rem); margin: 0 0 .25rem; color: #333; }
.fluid-body { font-size: clamp(0.875rem, 1.5vw, 1.125rem); color: #555; margin: 0; }
.fixed-comparison {
display: flex; gap: 16px; margin-top: 1.5rem;
background: #f8f8f8; padding: 1rem; border-radius: 6px;
}
.fixed-comparison > div { flex: 1; }
.compare-label { font-size: .7rem; color: #888; text-transform: uppercase; letter-spacing: .05em; margin: 0 0 .25rem; }
.fixed-h2 { font-size: 24px; margin: 0 0 .25rem; }
.fixed-body { font-size: 16px; margin: 0; color: #555; }
.fluid-h2-sm { font-size: clamp(1rem, 2.5vw, 1.5rem); margin: 0 0 .25rem; color: #4472c4; }
.fluid-body-sm { font-size: clamp(0.8rem, 1.2vw, 1rem); margin: 0; color: #555; }
Bình luận