Giúp chọn cú pháp để lồng CSS

Bạn cần có hai cú pháp cạnh tranh để xác định xem một cú pháp nào sẽ được ưu tiên sử dụng cho đối tượng cụ thể.

Adam Argyle
Adam Argyle
Miriam Suzanne
Miriam Suzanne

Lồng CSS là một cú pháp bổ sung tiện lợi cho phép thêm CSS vào bên trong bộ quy tắc. Nếu bạn đã từng sử dụng SCSS, Ít hoặc Bút cảm ứng, thì chắc chắn bạn sẽ thấy một số phiên bản như sau:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Sau khi được bộ tiền xử lý biên dịch thành CSS thông thường, các CSS này sẽ chuyển thành CSS thông thường như sau:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

Phiên bản CSS chính thức của cú pháp này đang được xem xét một cách cẩn thận và chúng tôi có một lựa chọn ưu tiên là chúng tôi muốn tận dụng sự trợ giúp của cộng đồng để phá vỡ sự ràng buộc. Phần còn lại của bài đăng này sẽ giới thiệu các tuỳ chọn cú pháp để bạn có thể tham gia khảo sát khi kết thúc.

Tại sao ví dụ về cách lồng ghép chính xác được hiển thị ở trên không thể là cú pháp cho cách lồng ghép CSS?

Có một vài lý do khiến không thể sử dụng cú pháp lồng phổ biến nhất:

  1. Phân tích cú pháp không rõ ràng
    Một số bộ chọn lồng nhau có thể giống hệt như các thuộc tính và bộ tiền xử lý có thể phân giải và quản lý chúng tại thời điểm xây dựng. Các công cụ trình duyệt sẽ không có cùng các thành phần tương tác, nên các bộ chọn không được diễn giải lỏng lẻo.

  2. Xung đột phân tích cú pháp bộ tiền xử lý
    Cách lồng ghép của CSS không làm hỏng các bộ tiền xử lý hoặc quy trình lồng ghép hiện có của nhà phát triển. Điều này sẽ gây phiền toái và không cân nhắc cho các hệ sinh thái cũng như cộng đồng đó.

  3. Đang chờ :is()
    Lồng ghép cơ bản không cần :is() nhưng cách lồng ghép phức tạp hơn thì có. Xem Ví dụ 3 để biết giới thiệu ngắn về danh sách bộ chọn và cách lồng ghép. Hãy tưởng tượng rằng danh sách bộ chọn nằm ở giữa một bộ chọn thay vì ở đầu, trong những trường hợp đó, bạn bắt buộc phải có :is() để nhóm các bộ chọn ở giữa một bộ chọn khác.

Tổng quan về những gì chúng tôi đang so sánh

Chúng tôi muốn CSS lồng ghép đúng cách và trên tinh thần đó, chúng tôi đưa cộng đồng vào. Các phần sau đây sẽ mô tả 3 phiên bản mà chúng tôi đang đánh giá. Sau đó, chúng ta sẽ đi qua một số ví dụ về cách sử dụng để so sánh và cuối cùng sẽ có một cuộc khảo sát ngắn hỏi bạn xem bạn thích cách nào.

Cách 1: @nest

Đây là cú pháp được chỉ định hiện tại trong CSS Nesting 1. Lớp này mang đến một cách thuận tiện để lồng các kiểu nối bằng cách bắt đầu các bộ chọn lồng nhau mới với &. Phương thức này cũng cung cấp @nest như một cách để đặt ngữ cảnh & ở bất kỳ đâu bên trong một bộ chọn mới, chẳng hạn như khi bạn không chỉ thêm các chủ thể. Tính năng này linh hoạt và tối thiểu, nhưng với chi phí cần phải nhớ @nest hoặc &, tuỳ thuộc vào trường hợp sử dụng của bạn.

Cách 2: Hạn chế @nest

Đây là một giải pháp thay thế nghiêm ngặt hơn nhằm giảm chi phí đề cập khi phải nhớ hai phương thức lồng. Cú pháp bị hạn chế này chỉ cho phép lồng nhau sau @nest, do đó, không có mẫu tiện lợi nào chỉ nối thêm. Loại bỏ sự không rõ ràng về lựa chọn, tạo ra một cách lồng ghép dễ nhớ nhưng hy sinh sự ngắn gọn theo quy ước.

Cách 3: Dấu ngoặc vuông

Để tránh cú pháp kép hoặc sự lộn xộn khác liên quan đến các đề xuất @nest, Miriam SuzanneElika Etemad đã đề xuất một cú pháp thay thế dựa trên dấu ngoặc nhọn bổ sung. Điều này mang lại sự rõ ràng về cú pháp, chỉ có thêm hai ký tự và không có quy tắc at mới. Điều này cũng cho phép các quy tắc lồng nhau được nhóm theo loại lồng nhau cần thiết, như một cách đơn giản hoá nhiều bộ chọn lồng nhau tương tự nhau.

Ví dụ 1 – Lồng ghép trực tiếp

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest luôn

.foo {
  color: #111;

  @nest & .bar {
    color: #eee;
  }
}

dấu ngoặc

.foo {
  color: #111;

  {
    & .bar {
      color: #eee;
    }
  }
}

CSS tương đương

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

Ví dụ 2 – Làm lồng ghép

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest luôn

.foo {
  color: blue;

  @nest &.bar {
    color: red;
  }
}

dấu ngoặc

.foo {
  color: blue;

  {
    &.bar {
      color: red;
    }
  }
}

CSS tương đương

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

Ví dụ 3 – Danh sách bộ chọn và cách lồng ghép

@nest

.foo, .bar {
  color: blue;

  & + .baz,
  &.qux {
    color: red;
  }
}

@nest luôn

.foo, .bar {
  color: blue;

  @nest & + .baz,
  &.qux {
    color: red;
  }
}

dấu ngoặc

.foo, .bar {
  color: blue;

  {
    & + .baz,
    &.qux {
      color: red;
    }
  }
}

CSS tương đương

.foo, .bar {
  color: blue;
}

:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
  color: red;
}

Ví dụ 4: Nhiều cấp độ

@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

    & > p {
      font-size: .9rem;
    }
  }
}

@nest luôn

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

    @nest & > p {
      font-size: .9rem;
    }
  }
}

dấu ngoặc

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

      {
        & > p {
          font-size: .9rem;
        }
      }
    }
  }
}

CSS tương đương

figure {
  margin: 0;
}

figure > figcaption {
  background: hsl(0 0% 0% / 50%);
}

figure > figcaption > p {
  font-size: .9rem;
}

Ví dụ 5 – Lồng ghép cha mẹ hoặc thay đổi chủ thể

@nest

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

@nest luôn

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

dấu ngoặc

.foo {
  color: red;

  {
    .parent & {
      color: blue;
    }
  }
}

CSS tương đương

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

Ví dụ 6 – Kết hợp trực tiếp và lồng nhau

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest luôn

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    @nest &.baz {
      color: green;
    }
  }
}

dấu ngoặc

.foo {
  color: blue;

  {
    .bar & {
      color: red;

      {
        &.baz {
          color: green;
        }
      }
    }
  }
}

CSS tương đương

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

.bar .foo.baz {
  color: green;
}

Ví dụ 7 – Lồng ghép truy vấn phương tiện

@nest

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

hoặc rõ ràng / mở rộng

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

@nest luôn (luôn phản cảm)

.foo {
  display: grid;

  @media (width => 30em) {
    @nest & {
      grid-auto-flow: column;
    }
  }
}

dấu ngoặc

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

hoặc rõ ràng / mở rộng

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

CSS tương đương

.foo {
  display: grid;
}

@media (width => 30em) {
  .foo {
    grid-auto-flow: column;
  }
}

Ví dụ 8 – Nhóm lồng ghép

@nest

fieldset {
  border-radius: 10px;

  &:focus-within {
    border-color: hotpink;
  }

  & > legend {
    font-size: .9em;
  }

  & > div {
    & + div {
      margin-block-start: 2ch;
    }

    & > label {
      line-height: 1.5;
    }
  }
}

@nest luôn

fieldset {
  border-radius: 10px;

  @nest &:focus-within {
    border-color: hotpink;
  }

  @nest & > legend {
    font-size: .9em;
  }

  @nest & > div {
    @nest & + div {
      margin-block-start: 2ch;
    }

    @nest & > label {
      line-height: 1.5;
    }
  }
}

dấu ngoặc

fieldset {
  border-radius: 10px;

  {
    &:focus-within {
      border-color: hotpink;
    }
  }

  > {
    legend {
      font-size: .9em;
    }

    div {
      + div {
        margin-block-start: 2ch;
      }

      > label {
        line-height: 1.5;
      }
    }}
  }
}

CSS tương đương

fieldset {
  border-radius: 10px;
}

fieldset:focus-within {
  border-color: hotpink;
}

fieldset > legend {
  font-size: .9em;
}

fieldset > div + div {
  margin-block-start: 2ch;
}

fieldset > div > label {
  line-height: 1.5;
}

Ví dụ 9 – Nhóm làm tổ phức hợp "Chậu rửa trong nhà bếp"

@nest

dialog {
  border: none;

  &::backdrop {
    backdrop-filter: blur(25px);
  }

  & > form {
    display: grid;

    & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

@nest luôn

dialog {
  border: none;

  @nest &::backdrop {
    backdrop-filter: blur(25px);
  }

  @nest & > form {
    display: grid;

    @nest & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

dấu ngoặc

dialog {
  border: none;

  {
    &::backdrop {
      backdrop-filter: blur(25px);
    }

    & > form {
      display: grid;

      {
        & > :is(header, footer) {
          align-items: flex-start;
        }
      }
    }
  }

  {
    html:has(&[open]) {
      overflow: hidden;
    }
  }
}

CSS tương đương

dialog {
  border: none;
}

dialog::backdrop {
  backdrop-filter: blur(25px);
}

dialog > form {
  display: grid;
}

dialog > form > :is(header, footer) {
  align-items: flex-start;
}

html:has(dialog[open]) {
  overflow: hidden;
}

Thời gian bỏ phiếu

Hy vọng bạn cảm thấy đó là một so sánh công bằng và đĩa mẫu của các tuỳ chọn cú pháp mà chúng tôi đang đánh giá. Vui lòng xem xét kỹ các tùy chọn này và cho chúng tôi biết bạn muốn tùy chọn cài đặt nào ở bên dưới. Chúng tôi rất trân trọng việc bạn đã giúp chúng tôi thúc đẩy việc lồng ghép CSS theo cú pháp mà tất cả chúng ta sẽ biết và yêu thích!

Tham gia khảo sát!