Cập nhật tháng 10/2026. Mức hỗ trợ trình duyệt được đối chiếu với dữ liệu Baseline (dự án web-features, hiển thị trên MDN và web.dev) trong tháng 10/2026; các ví dụ doanh nghiệp là tình huống minh hoạ.
Bài này dành cho ai: người làm web và đội marketing tự quản trị website WordPress muốn trang nhẹ hơn mà vẫn đẹp trên mọi màn hình.
Bạn sẽ nắm được gì: 5 tính năng CSS đã dùng được rộng rãi (container queries, :has(), clamp(), nesting, biến CSS): vấn đề cũ, mã mẫu, mức hỗ trợ và lúc chưa nên dùng.
Thời gian đọc: khoảng 9 phút.
Nhiều website doanh nghiệp vẫn kéo theo thư viện JavaScript chỉ để đổi bố cục thẻ, tô viền ô nhập sai hay chỉnh cỡ chữ. Quan điểm của bài: năm 2026, phần lớn việc đó CSS tự làm được. Ít JavaScript hơn là ít mã phải tải, ít thứ hỏng khi cập nhật plugin và trang phản hồi nhanh hơn, điều mà bài Core Web Vitals cho chủ doanh nghiệp đã cho thấy ảnh hưởng trực tiếp đến trải nghiệm khách.

1. Đọc nhãn Baseline trước khi dùng tính năng mới
Baseline là nhãn cho biết một tính năng đã chạy trên Chrome, Edge, Firefox và Safari (máy tính lẫn điện thoại) hay chưa:
Newly available
Vừa có trên đủ trình duyệt chính; máy chưa cập nhật có thể chưa chạy.
Widely available
Đã đủ 30 tháng kể từ mốc trên: mức an toàn cho website doanh nghiệp.
Cả 5 tính năng trong bài đều đã Widely available tính đến tháng 10/2026. Nhãn này hiện ở đầu mỗi trang tài liệu MDN.
2. Container queries: thẻ tự đổi bố cục theo khung chứa
Vấn đề cũ: media query chỉ biết độ rộng màn hình. Khối thẻ dịch vụ ở cột chính nên 4 cột, ở cột phụ nên 1 cột, dù màn hình vẫn 1440px. Trước đây phải thêm class cho từng chỗ đặt hoặc dùng JavaScript đo khung.
Cách mới: khai báo khung là container rồi viết điều kiện theo độ rộng khung. Ví dụ lưới 4/2/1:
.luoi-dich-vu > ul { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@container (min-width: 36rem) {
.luoi-dich-vu > ul { grid-template-columns: repeat(2, 1fr); }
}
@container (min-width: 60rem) {
.luoi-dich-vu > ul { grid-template-columns: repeat(4, 1fr); }
}
Muốn 3/3/1 thì bỏ mốc giữa, đặt repeat(3, 1fr) từ khoảng 40rem. Ví dụ minh hoạ: công ty nội thất dùng chung khối “Gói thiết kế” ở trang chủ và cột bên bài viết; khối tự xếp 4 hay 1 cột, không thêm JavaScript.
Hỗ trợ: container size queries Widely available từ tháng 8/2025. Chưa nên dùng khi: bạn định đặt điều kiện lên chính phần tử container (container chỉ tạo điều kiện cho phần tử con), hoặc khi cần style queries (truy vấn theo giá trị biến): tính năng này mới ở mức Newly available từ tháng 5/2026, nên chỉ dùng làm phần tăng cường.
3. :has(): chọn phần tử cha theo thứ nó chứa
Vấn đề cũ: CSS chỉ chọn xuôi từ cha xuống con. Muốn tô đỏ nhóm trường khi ô bên trong sai phải dùng JavaScript thêm class.
Cách mới:
.truong-nhap:has(input:invalid:not(:placeholder-shown)) {
border-color: var(–mau-loi);
}
/* Thẻ có ảnh thì chia 2 cột, thẻ không ảnh giữ 1 cột */
.the-dich-vu:has(img) { display: grid; grid-template-columns: 8rem 1fr; }
/* Khoá cuộn trang khi hộp thoại đang mở */
body:has(dialog[open]) { overflow: hidden; }
Ví dụ đầu rất hợp với form liên hệ; bài thiết kế form liên hệ chuyển đổi tốt bàn kỹ hơn về thông báo lỗi dễ hiểu.
Hỗ trợ: Widely available từ tháng 6/2026. Chưa nên dùng khi: khách của bạn có tỉ lệ đáng kể dùng máy cũ không cập nhật trình duyệt (xem số liệu trình duyệt trong công cụ thống kê trước); khi đó đặt mã trong @supports selector(:has(a)). Tránh lạm dụng body:has(…) vì trình duyệt phải kiểm tra lại nhiều phần tử.

4. clamp(): cỡ chữ co giãn mà không cần hàng loạt media query
Vấn đề cũ: phải viết 3–4 media query chỉ để đổi cỡ chữ tiêu đề.
Cách mới: clamp(nhỏ nhất, giá trị ưu tiên, lớn nhất).
.section { padding-block: clamp(2rem, 5vw, 5rem); }
Hỗ trợ: Widely available từ đầu năm 2023. Chưa nên dùng khi: giá trị giữa chỉ có vw thuần. Chữ khi đó không to lên lúc người dùng phóng to trang, trái tiêu chí 1.4.4 của WCAG. Luôn cộng thêm phần rem và thử phóng to 200%.
5. CSS nesting: viết lồng như Sass, không cần công cụ dựng
Vấn đề cũ: muốn viết lồng phải cài Sass, thêm bước dựng mà website nhỏ thường không có.
Cách mới:
padding: 1.5rem;
& h3 { margin-top: 0; }
&:hover { box-shadow: 0 4px 16px rgb(0 0 0 / .08); }
@media (width < 40rem) { padding: 1rem; }
}
Hỗ trợ: Widely available từ tháng 6/2026. Chưa nên dùng khi: bạn lồng quá 3 tầng, vì selector dài và độ ưu tiên tăng khó lường; phần lồng được tính độ ưu tiên giống :is(). Nếu từng vật lộn với chuyện “sao CSS của mình không ăn”, hãy đọc lại Làm chủ CSS Specificity trước khi lồng.
6. Biến CSS (custom properties): đổi màu thương hiệu ở một chỗ
Vấn đề cũ: mã màu gõ thẳng ở hàng trăm chỗ, đổi màu nút là dễ sót.
Cách mới: khai báo một lần, ghi đè theo khu vực hoặc chế độ tối:
–mau-chu: #1f2937;
–mau-nen: #fffdf8;
–mau-nut: #c65300;
}
.nut-chinh { background: var(–mau-nut); color: #fff; }
@media (prefers-color-scheme: dark) {
:root { –mau-chu: #f3f4f6; –mau-nen: #111827; }
}
Khác biến Sass, biến CSS sống trong trình duyệt nên đổi được theo khu vực hay chế độ tối.
Hỗ trợ: Widely available từ 2019. Chưa nên dùng khi: bạn định đặt biến trong điều kiện @media (không hoạt động). Đặt tên theo vai trò (--mau-nut) thay vì theo màu (--cam) để đổi thương hiệu không sai nghĩa.

7. Khi nào vẫn cần JavaScript và framework
Giỏ hàng, bộ lọc có trạng thái, xác thực phía máy chủ vẫn là việc của JavaScript và backend. Cách chia việc thực tế:
Giao cho CSS
Bố cục theo khung, cỡ chữ co giãn, trạng thái hiển thị theo nội dung, màu theo chủ đề.
Giao cho HTML
Hộp thoại dialog, khối mở rộng details, kiểu ô nhập đúng bàn phím.
Giữ cho JavaScript
Dữ liệu động, tương tác có trạng thái phức tạp, gọi API, theo dõi chuyển đổi.
8. Bài học áp dụng được ngay
Tuần này, tìm trên website một đoạn JavaScript chỉ dùng để đổi giao diện (số cột, class báo lỗi, cỡ chữ), thay bằng một trong 5 tính năng trên, thử trên điện thoại thật và đo lại tốc độ. Mỗi đoạn mã bớt đi là một thứ ít hỏng hơn.
9. Thuật ngữ cần biết
- Baseline: nhãn cho biết tính năng web đã chạy trên đủ trình duyệt chính; mức Widely available nghĩa là đã ổn định 30 tháng. Nguồn: web.dev/baseline.
- Container query: điều kiện CSS dựa trên kích thước của phần tử chứa thay vì màn hình. Nguồn: MDN.
- Custom property (biến CSS): thuộc tính bắt đầu bằng
--, đọc bằngvar(), kế thừa theo cây phần tử. Nguồn: MDN. - Nesting selector (
&): ký hiệu đại diện cho selector cha khi viết CSS lồng nhau. Nguồn: CSS Nesting Module, CSS WG.
10. Tìm hiểu thêm
- MDN: :has() và MDN: clamp(): cú pháp và ví dụ chi tiết.
- MDN: CSS nesting: các quy tắc lồng và độ ưu tiên.
- WCAG 2.2: Resize Text: vì sao cỡ chữ phải phóng to được.
11. Câu hỏi thường gặp
Website WordPress dùng trình dựng trang có áp dụng được không?
Được. Đặt container-type lên khối bọc rồi viết @container trong phần CSS tuỳ chỉnh của trình dựng trang. Nên thử trên bản nháp trước.
Container queries có thay hẳn media queries không?
Không. Media queries vẫn hợp cho bố cục cấp trang như đầu trang, menu, chân trang và các điều kiện như chế độ tối hay giảm chuyển động. Container queries hợp cho thành phần dùng lại ở nhiều chỗ.
Đọc tiếp
- Bài trước (Lập trình & Thiết kế): Một tuần làm việc của người làm web tự do: chia khối thời gian, bàn giao gọn, dùng AI đúng chỗ
- Bài sau trong chuyên mục Lập trình & Thiết kế: Vì sao dự án website đi chệch hướng: 7 bài học từ nghề làm web
- Nên đọc cùng: Làm chủ CSS Specificity
PDL Digital đào tạo đội ngũ làm web và marketing nội bộ cách viết giao diện gọn, nhanh, dễ bảo trì, kết hợp AI để rà soát mã và kiểm tra trên nhiều thiết bị; xem các khoá tại trang đào tạo.



