Bài 8. CSS mới: :has, container, nesting

CSS ngày nay làm được nhiều việc trước kia cần JavaScript: chọn theo con, truy vấn theo khung chứa, lồng quy tắc.

40 phútTrung cấp
Bạn sẽ học được
  • Dùng :has() chọn phần tử cha theo con
  • Dùng container queries
  • Viết CSS lồng nhau (nesting)
  • Dùng dialog và popover không cần thư viện
Thuật ngữ cần biết
Container query
Điều kiện CSS theo kích thước của khung chứa, không phải toàn cửa sổ.
Nesting
Viết quy tắc con bên trong quy tắc cha.
Popover
Thuộc tính HTML tạo hộp nổi, tự quản lý đóng/mở.

:has() - bộ chọn "cha"

/* thẻ có chứa ảnh thì chia hai cột */
.the:has(img) { display: grid; grid-template-columns: 120px 1fr; }
/* nhãn đổi màu khi ô nhập không hợp lệ */
label:has(+ input:invalid) { color: crimson; }

Container queries

.khung { container-type: inline-size; }
.the { display: block; }
@container (min-width: 480px) {
  .the { display: flex; gap: 16px; }
}

Thẻ tự đổi bố cục theo chỗ đặt: trong thanh bên hẹp thì xếp dọc, trong vùng chính rộng thì xếp ngang.

CSS lồng nhau

.menu {
  display: flex;
  a {
    padding: 8px 14px;
    &:hover { background: #e8f5e9; }
    &.active { font-weight: 700; }
  }
}

dialog và popover

<dialog id="hop">
  <p>Bạn chắc chắn muốn xóa?</p>
  <form method="dialog"><button>Hủy</button><button value="ok">Xóa</button></form>
</dialog>
<button onclick="hop.showModal()">Xóa</button>

<button popovertarget="goi-y">Gợi ý</button>
<div id="goi-y" popover>Nội dung hiện khi bấm, bấm ngoài là đóng.</div>

Một vài tính năng hay khác

  • aspect-ratio: 16/9 giữ tỉ lệ khung.
  • gap cho cả flex và grid.
  • color-mix() trộn màu, text-wrap: balance cân tiêu đề.
  • scroll-snap, position: sticky làm cuộn đẹp.
  • @layer kiểm soát thứ tự ưu tiên.
Tình huống: Thẻ sản phẩm dùng được mọi nơi

Cùng một component thẻ nhưng đặt vào trang chủ, thanh bên và giỏ hàng. Container query giúp thẻ tự co giãn mà không cần viết lại CSS cho từng chỗ.

Mẹo hay

Kiểm tra mức hỗ trợ trình duyệt tại caniuse.com; các tính năng trong bài đều có trong trình duyệt hiện đại.

Lưu ý

Nếu cần hỗ trợ trình duyệt rất cũ, hãy dùng @supports để dự phòng.

Thực hành
  1. Dùng :has() đổi viền khung biểu mẫu khi có ô sai.
  2. Tạo hộp thoại xác nhận bằng thẻ dialog.
  3. Viết lại một đoạn CSS dài bằng nesting.
Tóm tắt bài học
  • :has(), container queries, nesting đều dùng được ngay.
  • dialog và popover thay thế nhiều thư viện modal.
  • Luôn kiểm tra hỗ trợ trình duyệt.