Khi tìm hiểu các nguyên tắc của CSS cơ bản, người ta được dạy cách viết các kiểu mô-đun, có thể tái sử dụng và mô tả để đảm bảo khả năng bảo trì. Nhưng khi các nhà phát triển tham gia vào các ứng dụng trong thế giới thực, họ thường cảm thấy không thể thêm các tính năng giao diện người dùng mà không có kiểu dáng lọt vào các khu vực ngoài ý muốn. Vấn đề này thường biến thành một vòng lặp tự hoàn thiện; các kiểu về mặt lý thuyết nằm trong phạm vi một thành phần hoặc lớp bắt đầu hiển thị ở nơi chúng không thuộc về. Điều này buộc nhà phát triển phải tạo ra các bộ chọn cụ thể hơn nữa để ghi đè các kiểu bị rò rỉ, sau đó vô tình ghi đè các kiểu chung, v.v. Các quy ước tên lớp cứng nhắc, chẳng hạn như BEM, là một giải pháp lý thuyết cho vấn đề này. Phương pháp BEM (Khối, Phần tử, Công cụ sửa đổi) là một cách đặt tên có hệ thống cho các lớp CSS để đảm bảo khả năng sử dụng lại và cấu trúc trong các tệp CSS. Các quy ước đặt tên như thế này có thể giảm tải nhận thức bằng cách tận dụng ngôn ngữ miền để mô tả các thành phần và trạng thái của chúng, đồng thời nếu được triển khai đúng cách, có thể tạo kiểu cho các ứng dụng lớn dễ bảo trì hơn. Tuy nhiên, trong thế giới thực, không phải lúc nào mọi chuyện cũng diễn ra như vậy. Các ưu tiên có thể thay đổi và cùng với sự thay đổi, việc thực hiện sẽ trở nên không nhất quán. Những thay đổi nhỏ đối với cấu trúc HTML có thể yêu cầu sửa đổi nhiều tên lớp CSS. Với các ứng dụng giao diện người dùng có tính tương tác cao, tên lớp theo mẫu BEM có thể trở nên dài và khó sử dụng (ví dụ: tổng quan người dùng ứng dụng__status--đang xác thực) và việc không tuân thủ đầy đủ các quy tắc đặt tên sẽ phá vỡ cấu trúc của hệ thống, do đó phủ nhận các lợi ích của nó. Trước những thách thức này, không có gì ngạc nhiên khi các nhà phát triển đã chuyển sang sử dụng các framework, trong đó Tailwind là framework CSS phổ biến nhất. Thay vì cố gắng chống lại những gì có vẻ giống như một cuộc chiến về tính đặc hiệu không thể phân thắng bại giữa các phong cách, việc từ bỏ CSS Cascade và sử dụng các công cụ đảm bảo sự cô lập hoàn toàn sẽ dễ dàng hơn. Các nhà phát triển dựa nhiều hơn vào các tiện ích Làm sao chúng tôi biết rằng một số nhà phát triển muốn tránh các kiểu xếp tầng? Đó là sự nổi lên của công cụ giao diện người dùng “hiện đại” - như các khung CSS-in-JS - được thiết kế đặc biệt cho mục đích đó. Làm việc với các phong cách riêng biệt có phạm vi chặt chẽ đối với các thành phần cụ thể có thể giống như một luồng gió mới. Nó loại bỏ nhu cầu đặt tên cho mọi thứ - vẫn là một trong những nhiệm vụ giao diện người dùng bị ghét và tốn thời gian nhất - và cho phép các nhà phát triển làm việc hiệu quả mà không cần hiểu đầy đủ hoặc tận dụng lợi ích của việc kế thừa CSS. Nhưng việc loại bỏ CSS Cascade cũng có những vấn đề riêng. Ví dụ: việc soạn các kiểu trong JavaScript yêu cầu cấu hình xây dựng nặng và thường dẫn đến các kiểu xen kẽ một cách lúng túng với đánh dấu thành phần hoặc HTML. Thay vì xem xét cẩn thận các quy ước đặt tên, chúng tôi cho phép các công cụ xây dựng tự động tạo bộ chọn và mã nhận dạng cho chúng tôi (ví dụ: .jsx-3130221066), yêu cầu các nhà phát triển phải cập nhật một ngôn ngữ giả khác ngay trong chính nó. (Như thể tải trọng nhận thức của việc hiểu tất cả các useEffects của thành phần của bạn làm gì vẫn chưa đủ!) Việc trừu tượng hóa hơn nữa công việc đặt tên các lớp cho công cụ có nghĩa là việc gỡ lỗi cơ bản thường bị hạn chế ở các phiên bản ứng dụng cụ thể được biên dịch để phát triển, thay vì tận dụng các tính năng trình duyệt gốc hỗ trợ gỡ lỗi trực tiếp, chẳng hạn như Công cụ dành cho nhà phát triển. Nó gần giống như việc chúng ta cần phát triển các công cụ để gỡ lỗi các công cụ mà chúng ta đang sử dụng nhằm trừu tượng hóa những gì web đã cung cấp - tất cả chỉ nhằm mục đích thoát khỏi “nỗi đau” khi viết CSS tiêu chuẩn. May mắn thay, các tính năng CSS hiện đại không chỉ giúp việc viết CSS tiêu chuẩn linh hoạt hơn mà còn cung cấp cho các nhà phát triển như chúng tôi nhiều quyền lực hơn để quản lý phân tầng và làm cho nó hoạt động hiệu quả. Lớp CSS Cascade là một ví dụ tuyệt vời, nhưng có một tính năng khác đang thiếu sự chú ý một cách đáng ngạc nhiên - mặc dù điều đó hiện đang thay đổi khi gần đây nó đã trở nên tương thích với Baseline. Quy tắc CSS @scope Tôi coi quy tắc CSS @scope là một phương pháp chữa trị tiềm năng cho loại lo lắng do rò rỉ phong cách mà chúng tôi đã đề cập, một điều không buộc chúng tôi phải thỏa hiệp các lợi thế của web gốc để có được tính trừu tượng và công cụ xây dựng bổ sung. “Quy tắc CSS @scope cho phép bạn chọn các phần tử trong cây con DOM cụ thể, nhắm mục tiêu chính xác các phần tử mà không cần viết các bộ chọn quá cụ thể khó ghi đè và không kết hợp các bộ chọn của bạn quá chặt với cấu trúc DOM.”- MDN
Nói cách khác, chúng ta có thể làm việc với các kiểu riêng biệt trong các trường hợp cụ thể mà không phải hy sinh tính kế thừa, xếp tầng hoặc thậm chí là sự phân tách cơ bản các mối quan tâmđó đã là nguyên tắc định hướng lâu dài của sự phát triển front-end. Thêm vào đó, nó có phạm vi phủ sóng trình duyệt tuyệt vời. Trên thực tế, Firefox 146 đã thêm hỗ trợ cho @scope vào tháng 12, khiến nó tương thích với Baseline lần đầu tiên. Dưới đây là so sánh đơn giản giữa một nút sử dụng mẫu BEM và quy tắc @scope:
Quy tắc @scope cho phép độ chính xác với độ phức tạp ít hơn. Nhà phát triển không còn cần phải tạo ranh giới bằng cách sử dụng tên lớp, do đó, cho phép họ viết các bộ chọn dựa trên các phần tử HTML gốc, do đó loại bỏ nhu cầu về các mẫu tên lớp CSS quy định. Chỉ cần loại bỏ nhu cầu quản lý tên lớp, @scope có thể giảm bớt nỗi sợ hãi liên quan đến CSS trong các dự án lớn.
Cách sử dụng cơ bản
Để bắt đầu, hãy thêm quy tắc @scope vào CSS của bạn và chèn bộ chọn gốc cho các kiểu sẽ nằm trong phạm vi:
@scope () {
/* Kiểu dáng nằm trong phạm vi
Vì vậy, ví dụ: nếu chúng ta định phạm vi kiểu cho phần tử
@scope (điều hướng) { a { /* Kiểu liên kết trong phạm vi điều hướng */ }
a:active { /* Kiểu liên kết hoạt động */ }
a:active::trước { /* Liên kết hoạt động với phần tử giả để tạo kiểu bổ sung */ }
@media (độ rộng tối đa: 768px) { a { /* Điều chỉnh đáp ứng */ } } }
Bản thân điều này không phải là một tính năng đột phá. Tuy nhiên, đối số thứ hai có thể được thêm vào phạm vi để tạo ranh giới thấp hơn, xác định điểm bắt đầu và điểm kết thúc của phạm vi một cách hiệu quả.
/* Bất kỳ phần tử a nào bên trong ul sẽ không được áp dụng kiểu */ @scope (điều hướng) đến (ul) { một { cỡ chữ: 14px; } }
Cách thực hành này được gọi là phạm vi bánh rán và có một số cách tiếp cận mà người ta có thể sử dụng, bao gồm một loạt các bộ chọn tương tự, có tính đặc hiệu cao được kết hợp chặt chẽ với cấu trúc DOM, bộ chọn giả :not hoặc gán tên lớp cụ thể cho các phần tử trong