Khai phá sức mạnh của quy tắc CSS @when để tạo ra các thiết kế web động và đáp ứng. Tìm hiểu cách áp dụng style theo điều kiện dựa trên container queries, trạng thái tùy chỉnh và các tiêu chí khác.
Làm chủ quy tắc CSS @when: Áp dụng Style có điều kiện cho Thiết kế Web Động
Quy tắc @when trong CSS, một phần của đặc tả CSS Conditional Rules Module Level 5, cung cấp một cách mạnh mẽ để áp dụng các style một cách có điều kiện dựa trên các điều kiện nhất định. Nó vượt xa các media query truyền thống, cho phép kiểm soát chi tiết hơn việc tạo kiểu dựa trên kích thước vùng chứa, thuộc tính tùy chỉnh và thậm chí cả trạng thái của các phần tử. Điều này có thể nâng cao đáng kể khả năng đáp ứng và thích ứng của thiết kế web của bạn, dẫn đến trải nghiệm người dùng tốt hơn trên các thiết bị và ngữ cảnh khác nhau.
Hiểu rõ các nguyên tắc cơ bản của quy tắc @when
Về cơ bản, quy tắc @when cung cấp một cơ chế để thực thi một khối các style CSS chỉ khi một điều kiện cụ thể được đáp ứng. Điều này tương tự như các câu lệnh if trong các ngôn ngữ lập trình. Hãy cùng phân tích cú pháp:
@when condition {
/* CSS rules to apply when the condition is true */
}
condition (điều kiện) có thể dựa trên nhiều yếu tố khác nhau, bao gồm:
- Container Queries: Tạo kiểu cho các phần tử dựa trên kích thước của phần tử chứa chúng thay vì viewport.
- Trạng thái tùy chỉnh (Custom States): Phản ứng với các tương tác của người dùng hoặc trạng thái ứng dụng.
- Biến CSS (CSS Variables): Áp dụng các style dựa trên giá trị của các thuộc tính tùy chỉnh CSS.
- Truy vấn phạm vi (Range Queries): Kiểm tra xem một giá trị có nằm trong một phạm vi cụ thể hay không.
Sức mạnh của @when nằm ở khả năng tạo ra việc tạo kiểu thực sự dựa trên component. Bạn có thể đóng gói logic tạo kiểu trong một component và đảm bảo nó chỉ được áp dụng khi component đó đáp ứng các tiêu chí nhất định, bất kể bố cục trang xung quanh.
Container Queries với @when
Container queries là một yếu tố thay đổi cuộc chơi cho thiết kế đáp ứng. Chúng cho phép các phần tử điều chỉnh kiểu dáng của mình dựa trên kích thước của vùng chứa cha, chứ không chỉ dựa vào chiều rộng của viewport. Điều này cho phép tạo ra các component linh hoạt và có thể tái sử dụng hơn. Hãy tưởng tượng một component thẻ hiển thị khác nhau tùy thuộc vào việc nó được đặt trong một thanh bên hẹp hay một khu vực nội dung chính rộng lớn. Quy tắc @when làm cho điều này trở nên cực kỳ đơn giản.
Ví dụ cơ bản về Container Query
Đầu tiên, bạn cần khai báo một container. Bạn có thể làm điều này bằng cách sử dụng thuộc tính container-type:
.container {
container-type: inline-size;
}
inline-size cho phép truy vấn container dựa trên kích thước nội tuyến của nó (chiều rộng trong chế độ viết ngang, chiều cao trong chế độ viết dọc). Bạn cũng có thể sử dụng size để truy vấn cả hai chiều, hoặc normal để không tạo ra một query container.
Bây giờ, bạn có thể sử dụng @container (thường được sử dụng kết hợp với @when) để áp dụng các style dựa trên kích thước của container:
@container (min-width: 300px) {
.card {
flex-direction: row;
align-items: center;
}
.card__image {
width: 100px;
height: 100px;
}
}
@container (max-width: 299px) {
.card {
flex-direction: column;
align-items: flex-start;
}
.card__image {
width: 100%;
height: auto;
}
}
Trong ví dụ này, bố cục của .card thay đổi dựa trên chiều rộng của container. Khi container rộng ít nhất 300px, thẻ sẽ hiển thị hình ảnh và văn bản cạnh nhau. Khi nó hẹp hơn, chúng sẽ xếp chồng lên nhau theo chiều dọc.
Đây là cách chúng ta có thể sử dụng @when để đạt được kết quả tương tự, có thể kết hợp với @container tùy thuộc vào sự hỗ trợ của trình duyệt và sở thích lập trình (vì @when cung cấp sự linh hoạt hơn trong một số kịch bản ngoài việc chỉ dựa vào kích thước container):
@container card-container (min-width: 300px) {
@when container(card-container) {
.card {
flex-direction: row;
align-items: center;
}
.card__image {
width: 100px;
height: 100px;
}
}
}
@container card-container (max-width: 299px) {
@when container(card-container) {
.card {
flex-direction: column;
align-items: flex-start;
}
.card__image {
width: 100%;
height: auto;
}
}
}
Trong trường hợp này, `card-container` là một tên container được gán với `@container`, và `container(card-container)` trong `@when` kiểm tra xem ngữ cảnh container được chỉ định có hoạt động hay không. Lưu ý: Hỗ trợ cho hàm `container()` và cú pháp chính xác có thể khác nhau giữa các trình duyệt và phiên bản. Hãy tham khảo bảng tương thích của trình duyệt trước khi triển khai.
Các ví dụ quốc tế thực tiễn
- Danh sách sản phẩm thương mại điện tử: Hiển thị danh sách sản phẩm khác nhau dựa trên không gian có sẵn trong lưới trang danh mục. Một container nhỏ hơn có thể chỉ hiển thị hình ảnh và giá sản phẩm, trong khi một container lớn hơn có thể bao gồm mô tả ngắn và xếp hạng. Điều này hữu ích ở các khu vực khác nhau với tốc độ internet và loại thiết bị khác nhau, cho phép tối ưu hóa trải nghiệm trên cả máy tính để bàn cao cấp và các kết nối di động băng thông thấp ở các nước đang phát triển.
- Tóm tắt bài viết tin tức: Điều chỉnh độ dài của các bản tóm tắt bài viết được hiển thị trên trang chủ của một trang web tin tức dựa trên chiều rộng của container. Trong một thanh bên hẹp, chỉ hiển thị tiêu đề và một vài từ; trong khu vực nội dung chính, cung cấp một bản tóm tắt chi tiết hơn. Cần xem xét sự khác biệt về ngôn ngữ, nơi một số ngôn ngữ (ví dụ: tiếng Đức) có xu hướng có các từ và cụm từ dài hơn, ảnh hưởng đến không gian cần thiết cho các bản tóm tắt.
- Widget trên Bảng điều khiển (Dashboard): Sửa đổi bố cục của các widget trên bảng điều khiển dựa trên kích thước container của chúng. Một widget nhỏ có thể hiển thị một biểu đồ đơn giản, trong khi một widget lớn hơn có thể bao gồm các thống kê và điều khiển chi tiết. Tùy chỉnh trải nghiệm bảng điều khiển cho thiết bị và kích thước màn hình cụ thể của người dùng, xem xét các sở thích văn hóa về trực quan hóa dữ liệu. Ví dụ, một số nền văn hóa có thể thích biểu đồ cột hơn biểu đồ tròn.
Sử dụng @when với Trạng thái tùy chỉnh (Custom States)
Trạng thái tùy chỉnh cho phép bạn định nghĩa các trạng thái riêng cho các phần tử và kích hoạt các thay đổi về style dựa trên các trạng thái đó. Điều này đặc biệt hữu ích trong các ứng dụng web phức tạp nơi các pseudo-class CSS truyền thống như :hover và :active không đủ. Mặc dù trạng thái tùy chỉnh vẫn đang trong giai đoạn phát triển trong các trình duyệt, quy tắc @when cung cấp một hướng đi hứa hẹn để kiểm soát các style dựa trên các trạng thái này khi sự hỗ trợ trở nên hoàn thiện hơn.
Ví dụ về mặt khái niệm (Sử dụng biến CSS để mô phỏng trạng thái)
Vì hỗ trợ trạng thái tùy chỉnh gốc chưa phổ biến rộng rãi, chúng ta có thể mô phỏng nó bằng cách sử dụng các biến CSS và JavaScript.
/* CSS */
.my-element {
--is-active: 0;
background-color: #eee;
}
@when var(--is-active) = 1 {
.my-element {
background-color: #aaf;
}
}
/* JavaScript */
const element = document.querySelector('.my-element');
element.addEventListener('click', () => {
element.style.setProperty('--is-active', element.style.getPropertyValue('--is-active') === '0' ? '1' : '0');
});
Trong ví dụ này, chúng ta sử dụng một biến CSS --is-active để theo dõi trạng thái của phần tử. Đoạn mã JavaScript sẽ chuyển đổi giá trị của biến này khi phần tử được nhấp. Quy tắc @when sau đó sẽ áp dụng một màu nền khác khi --is-active bằng 1. Mặc dù đây là một giải pháp tạm thời, nó minh họa khái niệm về việc tạo kiểu có điều kiện dựa trên trạng thái.
Các trường hợp sử dụng tiềm năng trong tương lai với Trạng thái tùy chỉnh thực sự
Khi trạng thái tùy chỉnh thực sự được triển khai, cú pháp có thể trông giống như thế này (lưu ý: đây là giả định và dựa trên các đề xuất):
.my-element {
/* Initial styles */
}
@when :state(my-custom-state) {
.my-element {
/* Styles when the custom state is active */
}
}
Sau đó, bạn sẽ sử dụng JavaScript để thiết lập và gỡ bỏ trạng thái tùy chỉnh:
element.states.add('my-custom-state'); // Activate the state
element.states.remove('my-custom-state'); // Deactivate the state
Điều này sẽ cho phép kiểm soát vô cùng chi tiết việc tạo kiểu dựa trên logic ứng dụng.
Các lưu ý về Quốc tế hóa và Địa phương hóa
- Ngôn ngữ từ phải sang trái (RTL): Trạng thái tùy chỉnh có thể được sử dụng để điều chỉnh bố cục và kiểu dáng của các thành phần cho các ngôn ngữ RTL như tiếng Ả Rập và tiếng Do Thái. Ví dụ, phản chiếu bố cục của một menu điều hướng khi một trạng thái RTL cụ thể được kích hoạt.
- Khả năng tiếp cận (Accessibility): Sử dụng trạng thái tùy chỉnh để cung cấp các tính năng trợ năng nâng cao, chẳng hạn như làm nổi bật các phần tử được focus hoặc cung cấp mô tả văn bản thay thế khi một trạng thái tương tác của người dùng được kích hoạt. Đảm bảo rằng những thay đổi trạng thái này được truyền đạt hiệu quả đến các công nghệ hỗ trợ.
- Sở thích thiết kế văn hóa: Điều chỉnh giao diện trực quan của các thành phần dựa trên sở thích thiết kế văn hóa. Ví dụ, sử dụng các bảng màu hoặc bộ biểu tượng khác nhau dựa trên ngôn ngữ hoặc địa phương của người dùng.
Làm việc với Biến CSS và Truy vấn phạm vi
Quy tắc @when cũng có thể được sử dụng với các biến CSS để tạo ra các style động và có thể tùy chỉnh. Bạn có thể áp dụng các style dựa trên giá trị của một biến CSS, cho phép người dùng tùy chỉnh giao diện trang web của bạn mà không cần viết bất kỳ mã nào.
Ví dụ: Chuyển đổi Giao diện (Theme)
:root {
--theme-color: #fff;
--text-color: #000;
}
body {
background-color: var(--theme-color);
color: var(--text-color);
}
@when var(--theme-color) = #000 {
body {
--text-color: #fff;
}
}
Trong ví dụ này, biến --theme-color kiểm soát màu nền của body. Khi nó được đặt thành #000, quy tắc @when sẽ thay đổi --text-color thành #fff, tạo ra một giao diện tối. Người dùng sau đó có thể thay đổi giá trị của --theme-color bằng JavaScript hoặc bằng cách đặt một biến CSS khác trong một stylesheet người dùng.
Truy vấn phạm vi
Truy vấn phạm vi cho phép bạn kiểm tra xem một giá trị có nằm trong một phạm vi cụ thể hay không. Điều này có thể hữu ích để tạo ra các style có điều kiện phức tạp hơn.
@when (400px <= width <= 800px) {
.element {
/* Styles applied when the width is between 400px and 800px */
}
}
Tuy nhiên, cú pháp chính xác và sự hỗ trợ cho các truy vấn phạm vi trong @when có thể khác nhau. Bạn nên tham khảo các đặc tả mới nhất và bảng tương thích của trình duyệt. Container queries thường cung cấp một giải pháp thay thế mạnh mẽ và được hỗ trợ tốt hơn cho các điều kiện dựa trên kích thước.
Khả năng tiếp cận Toàn cầu và Tùy chọn người dùng
- Giao diện Tương phản cao: Sử dụng các biến CSS và quy tắc
@whenđể triển khai các giao diện có độ tương phản cao nhằm phục vụ người dùng bị khiếm thị. Cho phép người dùng tùy chỉnh bảng màu và kích thước phông chữ để đáp ứng nhu cầu cụ thể của họ. - Giảm chuyển động (Reduced Motion): Tôn trọng sở thích của người dùng về việc giảm chuyển động bằng cách sử dụng các biến CSS để tắt các hoạt ảnh và hiệu ứng chuyển tiếp khi người dùng đã bật cài đặt "giảm chuyển động" trong hệ điều hành của họ. Media query
prefers-reduced-motioncó thể được kết hợp với@whenđể kiểm soát chính xác hơn. - Điều chỉnh kích thước phông chữ: Cho phép người dùng điều chỉnh kích thước phông chữ của trang web bằng cách sử dụng các biến CSS. Sử dụng quy tắc
@whenđể điều chỉnh bố cục và khoảng cách của các phần tử để phù hợp với các kích thước phông chữ khác nhau, đảm bảo khả năng đọc và sử dụng cho tất cả người dùng.
Các phương pháp hay nhất và Lưu ý
- Tương thích Trình duyệt: Quy tắc
@whenvẫn còn tương đối mới và hỗ trợ trình duyệt chưa phổ biến. Luôn kiểm tra bảng tương thích của trình duyệt trước khi sử dụng nó trong môi trường production. Cân nhắc sử dụng các polyfill hoặc giải pháp dự phòng cho các trình duyệt cũ hơn. Tính đến cuối năm 2024, hỗ trợ trình duyệt vẫn còn hạn chế, và việc phụ thuộc nhiều vào@containervà sử dụng biến CSS một cách khôn ngoan với các giải pháp dự phòng JavaScript thường là một cách tiếp cận thực tế hơn. - Độ ưu tiên (Specificity): Hãy lưu ý đến độ ưu tiên của CSS khi sử dụng quy tắc
@when. Đảm bảo rằng các style có điều kiện của bạn đủ cụ thể để ghi đè bất kỳ style xung đột nào. - Khả năng bảo trì: Sử dụng các biến CSS và bình luận để làm cho mã của bạn dễ đọc và dễ bảo trì hơn. Tránh tạo ra các quy tắc có điều kiện quá phức tạp, khó hiểu và khó gỡ lỗi.
- Hiệu suất: Mặc dù quy tắc
@whencó thể cải thiện hiệu suất bằng cách giảm lượng CSS cần được phân tích, điều quan trọng là phải sử dụng nó một cách hợp lý. Việc lạm dụng các quy tắc có điều kiện có thể ảnh hưởng tiêu cực đến hiệu suất, đặc biệt là trên các thiết bị cũ. - Nâng cấp tăng dần (Progressive Enhancement): Sử dụng phương pháp nâng cấp tăng dần để đảm bảo rằng trang web của bạn hoạt động tốt ngay cả khi trình duyệt không hỗ trợ quy tắc
@when. Cung cấp một trải nghiệm cơ bản, chức năng cho tất cả người dùng và sau đó nâng cấp dần cho các trình duyệt hỗ trợ tính năng này.
Tương lai của việc Tạo kiểu có điều kiện
Quy tắc @when đại diện cho một bước tiến đáng kể trong CSS. Nó cho phép tạo kiểu linh hoạt và biểu cảm hơn, mở đường cho các ứng dụng web phức tạp và đáp ứng hơn. Khi hỗ trợ trình duyệt được cải thiện và đặc tả phát triển, quy tắc @when có khả năng trở thành một công cụ thiết yếu cho các nhà phát triển web.
Những tiến bộ hơn nữa trong CSS Houdini và việc chuẩn hóa các trạng thái tùy chỉnh sẽ nâng cao hơn nữa khả năng của @when, cho phép kiểm soát chi tiết hơn nữa việc tạo kiểu và tích hợp liền mạch hơn với JavaScript.
Kết luận
Quy tắc @when của CSS cung cấp một cách mạnh mẽ và linh hoạt để áp dụng các style một cách có điều kiện dựa trên container queries, trạng thái tùy chỉnh, biến CSS và các tiêu chí khác. Mặc dù hỗ trợ trình duyệt vẫn đang phát triển, đây là một công cụ có giá trị trong kho vũ khí của bạn để tạo ra các thiết kế web động và đáp ứng, thích ứng với các ngữ cảnh và sở thích người dùng khác nhau. Bằng cách hiểu các nguyên tắc cơ bản của quy tắc @when và tuân theo các phương pháp hay nhất, bạn có thể khai thác hết tiềm năng của nó và tạo ra những trải nghiệm người dùng thực sự đặc biệt. Hãy nhớ luôn kiểm tra kỹ lưỡng trên các trình duyệt và thiết bị khác nhau để đảm bảo tính tương thích và hiệu suất tối ưu.
Khi web tiếp tục phát triển, việc nắm bắt các tính năng CSS mới như @when là rất quan trọng để đi trước đón đầu và mang lại những trải nghiệm web tiên tiến cho khán giả toàn cầu.