Có thể bạn đã sớm sử dụng những khai báo lồng nhau trong CSS, thế nhưng, bạn sẽ cần chú ý tới những chi tiết đó nếu đang chuyển đi từ Sass.
Kể từ khi ra đời, CSS đã kiên quyết từ chối hỗ trợ cú pháp cho bộ chọn lồng nhau. Giải pháp thay thế luôn là sử dụng một bộ tiền xử lý CSS như Sass. Thế nhưng hiện tại, lồng nhau chính thức trở thành một phần của CSS gốc. Bạn có thể thử tính năng này trực tiếp trong các trình duyệt hiện đại.
Nếu chuyển sang từ Sass, bạn cần xét tới mọi sự khác biệt giữa cả hai tính năng lồng nhau gốc và Sass.
Bạn cần dùng “&” với bộ chọn thành phần trong CSS gốc
Đây là ví dụ về kiểu lồng nhau bạn sẽ thấy trong Sass, bằng cú pháp SCSS:
.nav {
ul { display: flex; }
a { color: black; }
}
Khối CSS này chỉ định bất kỳ danh sách chưa được xếp thứ tự bên trong một phần tử với class nav căn chỉnh dưới dạng cột linh hoạt. Thêm vào đó, toàn bộ anchor liên kết văn bản bên trong các thành phần bằng một class sẽ là màu đen.
Bây giờ, trong CSS gốc, kiểu lồng nhau đó sẽ không hợp lệ. Để khiến nó hoạt động, bạn phải bao gồm ký hiệu & ở phía trước của các thành phần lồng nhau như thế này:
.nav {
& ul { display: flex; }
& a { color: black; }
}
Giờ nếu đang dùng bộ chọn bắt đầu bằng một biểu tượng để nhắm mục tiêu một phần cụ thể trên trang, bạn có thể bỏ qua dấu &. Do đó, cú pháp sau sẽ hoạt động ở cả CSS gốc và Sass:
.nav {
.nav-list { display: flex; }
.nav-link { color: black; }
}
Bạn không thể tạo một bộ chọn mới bằng “&” trong CSS gốc
Một trong số những tính năng có thể được yêu thích ở Sass là khả năng làm những việc như thế này:
.nav {
&-list { display: flex; }
&-link { color: black; }
}
Code Sass biên dịch sang CSS thô như sau:
.nav-list {
display: flex;
}
.nav-link {
color: black;
}
Trong CSS gốc, bạn không thể tạo một bộ chọn mới bằng “&”. Trình biên dịch Sass thay thế “&” bằng thành phần cha nhưng CSS gốc sẽ xem “&” và phần này sau nó là hai bộ chọn riêng biệt. Kết quả, nó sẽ cố gắng tạo một bộ chọn kết hợp mà không cho kết quả tương tự.
Tuy nhiên, ví dụ này sẽ hoạt động trong CSS gốc:
.nav {
&.nav-list { display: flex; }
&.nav-link { color: black; }
}
Điều này hoạt động do bộ chọn đầu tiên giống nav.nav-list ở CSS thuần túy và thứ hai giống nav.nav-link. Thêm khoảng cách giữa “&” và bộ chọn sẽ tương đương với việc viết nav .nav-list.
Trong CSS gốc, nếu dùng ký hiệu & như thế này:
.nav {
&__nav-list { display: flex; }
&__nav-link { color: black; }
}
Điều đó giống như bạn đang viết như sau:
__nav-list.nav {
display: flex;
}
__nav-link.nav {
color: black;
}
Thật ngạc nhiên phải không? Xem xét cả hai __nav-list và __nav-link bên trong bộ chọn .nav. Nhưng ký hiệu &
thực sự đặt các thành phần được lồng ở phía trước thành phần cha.
Nét đặc trưng có thể khác nhau
Nhân tố khác cần lưu ý là tác động của điểm đặc trưng không xảy ra trong Sass nhưng có ở việc lồng CSS gốc.
Giả sử bạn có thành phần <main> và <article>. Với CSS sau, <h2> ở những thành phần này sẽ dùng một font serif:
#main, article {
h2 {
font-family: serif;
}
}
Phiên bản được biên dịch của code Sass trên như sau:
#main h2,
article h2 {
font-family: serif;
}
Thế nhưng cú pháp lồng nhau tương tự trong CSS gốc sẽ cho một kết quả khác, thực tế giống như:
:is(#main, article) h2 {
font-family: serif;
}
Bộ chọn is() xử lý các quy tắc cụ thể khác một chút so với lồng nhau trong Sass. Về cơ bản, tính đặc trưng của :is() được tự động nâng cấp lên mục cụ thể nhất trong danh sách các đối số được cung cấp.
Thư tự các thành phần có thể thay đổi phần tử được chọn
Lồng nhau trong CSS gốc có thể hoàn toàn thay đổi ý nghĩa thật sự của bộ chọn (ví dụ, chọn một thành phần hoàn toàn khác).
Ví dụ, hãy xem xét HTML sau:
<div class="dark-theme">
<div class="call-to-action">
<div class="heading"> Hello </div>
</div>
</div>
Và CSS sau:
body { font-size: 5rem; }
.call-to-action .heading {
.dark-theme & {
padding: 0.25rem;
background: hsl(42, 72%, 61%);
color: #111;
}
}
Đây là kết quả nếu bạn dùng Sass dưới dạng trình biên dịch CSS:
Giờ trong khối HTML, nếu chuyển <div> bằng class của dark-theme bên trong call-to-action, nó sẽ chia tách bộ chọn (ở chế độ Sass). Thế nhưng, khi bạn chuyển sang CSS thông thường, các kiểu sẽ tiếp tục hoạt động.
Nguyên nhân do cách hoạt động của is(). Vì vậy, CSS lồng nhau ở trên sẽ biên dịch thành CSS đơn giản sau:
.dark-theme :is(.call-to-action .heading) {
/* CSS code */
}
Code này chỉ định một .heading là thành phần con của .dark-theme và .call-to-action. Nhưng thứ tự của chúng không thực sự là vấn đề. Miễn là .heading là con của .call-to-action và .dark-theme, nó hoạt động theo cả hai thứ tự.
Đây là trường hợp đặc biệt và không phải lúc nào bạn cũng gặp phải. Thế nhưng hiểu chức năng cơ bản của bộ chọn :is() có thể giúp bạn nắm vững việc lồng nhau trong CSS. Điều này cũng khiến việc gỡ lỗi CSS của bạn dễ dàng hơn nhiều.
Trên đây là mọi điều bạn cần biết về sự khác biệt của lồng nhau trong CSS gốc và Sass. HI vọng bài viết hữu ích với các bạn.