Trạng thái của Dịch vụ so sánh giá (CSS) năm 2022

Các tính năng tạo kiểu cho web của hiện tại và tương lai, như đã thấy tại Google I/O 2022, cùng một số tính năng bổ sung.

Năm 2022 được xem là một trong những năm thành công nhất của CSS, cả về tính năng và việc phát hành tính năng trình duyệt hợp tác, với mục tiêu hợp tác là triển khai 14 tính năng!

Tổng quan

Bài đăng này là phiên bản bài viết của bài nói tại Google I/O 2022. Đây không phải là hướng dẫn chuyên sâu về từng tính năng, mà là phần giới thiệu và tổng quan ngắn gọn để thu hút sự chú ý của bạn, cung cấp thông tin rộng rãi thay vì chuyên sâu. Nếu bạn quan tâm, hãy xem phần cuối của một mục để biết các đường liên kết đến tài nguyên cung cấp thêm thông tin.

Mục lục

Hãy sử dụng danh sách dưới đây để chuyển đến các chủ đề bạn quan tâm:

Khả năng tương thích với trình duyệt

Lý do chính khiến nhiều tính năng CSS được thiết lập để phát hành cùng nhau là do nỗ lực của Interop 2022. Trước khi nghiên cứu các nỗ lực về Khả năng tương tác, bạn cần xem xét các nỗ lực của Compat 2021.

Compat 2021

Các mục tiêu cho năm 2021, dựa trên ý kiến phản hồi của nhà phát triển thông qua các cuộc khảo sát, là ổn định các tính năng hiện tại, cải thiện bộ kiểm thử và tăng điểm số đạt của trình duyệt cho 5 tính năng:

  1. sticky vị trí
  2. aspect-ratio định cỡ
  3. Bố cục flex
  4. Bố cục grid
  5. Ảnh động và vị trí transform

Điểm kiểm tra tăng lên trên mọi phương diện, cho thấy độ ổn định và độ tin cậy được cải thiện. Xin chúc mừng các đội tại đây!

Interop 2022

Năm nay, các trình duyệt đã gặp nhau để thảo luận về những tính năng và việc cần ưu tiên mà họ dự định thực hiện, từ đó hợp nhất các nỗ lực của mình. Họ dự định cung cấp các tính năng web sau đây cho nhà phát triển:

  1. @layer
  2. Hệ màu và hàm
  3. Vùng chứa
  4. <dialog>
  5. Khả năng tương thích của biểu mẫu
  6. Thao tác cuộn
  7. Lưới phụ
  8. Kiểu chữ
  9. Đơn vị khung nhìn
  10. Khả năng tương thích với web

Đây là một danh sách thú vị và đầy tham vọng mà tôi rất nóng lòng muốn xem.

Mới mẻ cho năm 2022

Không có gì đáng ngạc nhiên khi trạng thái CSS 2022 chịu ảnh hưởng đáng kể từ hoạt động Interop 2022.

Lớp xếp tầng

Browser Support

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari: 15.4.

Source

Trước @layer, thứ tự phát hiện của các biểu định kiểu đã tải là rất quan trọng, vì các kiểu được tải sau cùng có thể ghi đè các kiểu đã tải trước đó. Điều này dẫn đến các biểu định kiểu mục nhập được quản lý tỉ mỉ, trong đó nhà phát triển cần tải các kiểu ít quan trọng trước và các kiểu quan trọng hơn sau. Có toàn bộ các phương pháp để hỗ trợ nhà phát triển quản lý tầm quan trọng này, chẳng hạn như ITCSS.

Với @layer, tệp nhập có thể xác định trước các lớp và thứ tự của chúng. Sau đó, khi các kiểu tải, được tải hoặc xác định, chúng có thể được đặt trong một lớp, cho phép duy trì tầm quan trọng của việc ghi đè kiểu nhưng không cần phải quản lý tỉ mỉ việc điều phối tải.

Video này cho thấy cách các lớp xếp tầng được xác định cho phép quá trình tạo và tải tự do hơn, đồng thời vẫn duy trì tầng xếp lớp khi cần.

Chrome DevTools rất hữu ích trong việc trực quan hoá những kiểu nào đến từ những lớp nào:

Ảnh chụp màn hình thanh bên Styles (Kiểu) của Công cụ cho nhà phát triển của Chrome, làm nổi bật cách các kiểu xuất hiện trong các nhóm Layer (Lớp) mới.

Tài nguyên

Lưới phụ

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

Trước subgrid, một lưới bên trong một lưới khác không thể tự căn chỉnh với các ô hoặc đường lưới mẹ. Mỗi bố cục dạng lưới đều là duy nhất. Nhiều nhà thiết kế đặt một lưới duy nhất lên toàn bộ thiết kế của họ và liên tục căn chỉnh các mục trong đó, điều này không thể thực hiện được trong CSS.

Sau subgrid, một thành phần con của lưới có thể sử dụng các cột hoặc hàng của thành phần mẹ làm cột hoặc hàng của riêng mình và căn chỉnh chính nó hoặc các thành phần con với các cột hoặc hàng đó!

Trong bản minh hoạ sau đây, phần tử nội dung tạo ra một lưới cổ điển gồm 3 cột: cột ở giữa có tên là main, còn cột bên trái và bên phải đặt tên cho các đường kẻ fullbleed. Sau đó, mỗi phần tử trong nội dung, <nav><main>, sẽ áp dụng các dòng có tên từ nội dung bằng cách đặt grid-template-columns: subgrid.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

Cuối cùng, các thành phần con của <nav> hoặc <main> có thể tự căn chỉnh hoặc định kích thước bằng cách sử dụng các cột và dòng fullbleedmain.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

Công cụ cho nhà phát triển có thể giúp bạn xem các đường kẻ và lưới phụ (hiện chỉ có trên Firefox). Trong hình ảnh sau, lưới mẹ và các lưới con đã được phủ lên nhau. Giờ đây, bố cục này giống với cách các nhà thiết kế nghĩ về bố cục.

Ảnh chụp màn hình của một bản minh hoạ lưới phụ, sử dụng công cụ lớp phủ lưới Chrome DevTools để hiện các đường kẻ do CSS xác định.

Trong bảng điều khiển phần tử của công cụ cho nhà phát triển, bạn có thể thấy những phần tử nào là lưới và lưới con. Điều này rất hữu ích cho việc gỡ lỗi hoặc xác thực bố cục.

Ảnh chụp màn hình bảng điều khiển Elements (Phần tử) của Chrome DevTools, trong đó gắn nhãn những phần tử có bố cục lưới hoặc lưới con.
Ảnh chụp màn hình từ Công cụ cho nhà phát triển của Firefox

Tài nguyên

Truy vấn vùng chứa

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

Trước @container, các phần tử của một trang web chỉ có thể phản hồi kích thước của toàn bộ khung nhìn. Điều này rất phù hợp với bố cục vĩ mô, nhưng đối với bố cục vi mô, khi vùng chứa bên ngoài không phải là toàn bộ khung hiển thị, thì bố cục không thể điều chỉnh cho phù hợp.

Sau @container, các phần tử có thể phản hồi kích thước hoặc kiểu của vùng chứa mẹ! Điểm hạn chế duy nhất là các vùng chứa phải tự khai báo là mục tiêu truy vấn có thể, đây là một yêu cầu nhỏ nhưng mang lại lợi ích lớn.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

Những kiểu này giúp các cột Thứ Hai, Thứ Ba, Thứ Tư, Thứ Năm và Thứ Sáu trong video sau đây có thể được truy vấn theo các phần tử sự kiện.

Bản minh hoạ của Una Kravets

Sau đây là CSS để truy vấn vùng chứa calendar-day theo kích thước, sau đó điều chỉnh bố cục và cỡ chữ:

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

Sau đây là một ví dụ khác: một thành phần sách tự điều chỉnh cho phù hợp với không gian có sẵn trong cột mà thành phần đó được kéo vào:

Bản minh hoạ của Max Böck

Una đánh giá đúng tình hình là thiết kế mới có khả năng thích ứng. Có rất nhiều quyết định thú vị và có ý nghĩa về thiết kế cần đưa ra khi sử dụng @container.

Tài nguyên

accent-color

Browser Support

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari: 15.4.

Source

Trước accent-color, khi muốn có một biểu mẫu có màu sắc phù hợp với thương hiệu, bạn có thể phải sử dụng các thư viện phức tạp hoặc giải pháp CSS khó quản lý theo thời gian. Mặc dù họ cung cấp cho bạn tất cả các lựa chọn và hy vọng bao gồm cả khả năng hỗ trợ tiếp cận, nhưng việc chọn sử dụng các thành phần tích hợp hoặc áp dụng thành phần của riêng bạn sẽ trở nên tẻ nhạt nếu bạn tiếp tục chọn.

Sau accent-color, một dòng CSS sẽ mang màu thương hiệu đến các thành phần tích hợp. Ngoài sắc thái, trình duyệt sẽ chọn màu tương phản phù hợp cho các phần phụ trợ của thành phần một cách thông minh và thích ứng với bảng phối màu hệ thống (sáng hoặc tối).

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

Các phần tử HTML được làm nổi bật ở chế độ sáng và tối đặt cạnh nhau để so sánh.

Để tìm hiểu thêm về accent-color, hãy xem bài đăng của tôi trên web.dev. Trong bài đăng này, tôi sẽ khám phá nhiều khía cạnh khác của thuộc tính CSS hữu ích này.

Tài nguyên

Cấp độ màu 4 và 5

Web đã bị sRGB chi phối trong nhiều thập kỷ qua, nhưng trong một thế giới kỹ thuật số ngày càng mở rộng với màn hình độ phân giải cao và thiết bị di động được trang bị sẵn màn hình OLED hoặc QLED, sRGB là không đủ. Hơn nữa, người dùng mong đợi các trang linh động có thể thích ứng với lựa chọn ưu tiên của họ, đồng thời việc quản lý màu sắc ngày càng trở thành mối lo ngại của các nhà thiết kế, hệ thống thiết kế và người duy trì mã.

Tuy nhiên, không phải trong năm 2022. CSS có một số hàm và không gian màu mới: - Màu sắc đạt đến khả năng màu HD của màn hình. – Các không gian màu phù hợp với một mục đích, chẳng hạn như tính đồng nhất về cảm quan. – Không gian màu cho các chuyển màu làm thay đổi đáng kể kết quả nội suy. – Các hàm màu giúp bạn phối và tương phản, đồng thời chọn không gian mà bạn thực hiện công việc.

Trước khi có tất cả các tính năng về màu sắc này, các hệ thống thiết kế cần phải tính toán trước các màu tương phản phù hợp và đảm bảo bảng màu sống động một cách thích hợp, trong khi các trình tiền xử lý hoặc JavaScript đã thực hiện phần lớn công việc.

Sau tất cả các tính năng về màu sắc này, trình duyệt và CSS có thể thực hiện mọi thao tác, một cách linh hoạt và đúng lúc. Thay vì gửi nhiều KB CSS và JavaScript cho người dùng để cho phép họ tạo giao diện và màu trực quan hoá dữ liệu, CSS có thể thực hiện việc điều phối và tính toán. CSS cũng được trang bị tốt hơn để kiểm tra khả năng hỗ trợ trước khi sử dụng hoặc xử lý các trường hợp dự phòng một cách hiệu quả.

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

Browser Support

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15.

Source

HWB là viết tắt của hue (sắc độ), whiteness (độ trắng) và blackness (độ đen). HSL là một cách thể hiện màu sắc thân thiện với con người, vì đây chỉ là một sắc độ và lượng màu trắng hoặc đen để làm sáng hoặc tối. Những nghệ sĩ pha màu với màu trắng hoặc đen có thể sẽ đánh giá cao việc bổ sung cú pháp màu này.

Việc sử dụng hàm màu này sẽ tạo ra màu sắc từ không gian màu sRGB, giống như HSL và RGB. Về tính mới của năm 2022, điều này không mang đến cho bạn các màu mới, nhưng có thể giúp người hâm mộ cú pháp và mô hình tư duy thực hiện một số tác vụ dễ dàng hơn.

Tài nguyên

Hệ màu

Cách biểu thị màu sắc được thực hiện bằng không gian màu. Mỗi không gian màu đều có nhiều tính năng và điểm đánh đổi để xử lý màu. Một số người có thể xếp tất cả các màu sáng lại với nhau; một số người có thể xếp chúng theo độ sáng trước.

CSS 2022 dự kiến sẽ cung cấp 10 không gian màu mới, mỗi không gian có các tính năng riêng biệt để hỗ trợ nhà thiết kế và nhà phát triển trong việc hiển thị, chọn và trộn màu. Trước đây, sRGB là lựa chọn duy nhất để xử lý màu sắc, nhưng giờ đây CSS mở ra tiềm năng mới và một không gian màu mặc định mới, LCH.

color-mix()

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

Trước color-mix(), nhà phát triển và nhà thiết kế cần các trình tiền xử lý như Sass để trộn các màu trước khi trình duyệt nhìn thấy chúng. Hầu hết các hàm trộn màu cũng không cung cấp lựa chọn chỉ định không gian màu để trộn, đôi khi dẫn đến kết quả khó hiểu.

Sau color-mix(), các nhà phát triển và nhà thiết kế có thể kết hợp màu sắc trong trình duyệt, cùng với tất cả các kiểu khác của họ, mà không cần chạy quy trình xây dựng hoặc bao gồm JavaScript. Ngoài ra, họ có thể chỉ định hệ màu để thực hiện việc trộn hoặc sử dụng hệ màu trộn mặc định là LCH.

Thường thì màu thương hiệu được dùng làm màu cơ bản và các biến thể được tạo ra từ màu đó, chẳng hạn như màu sáng hơn hoặc tối hơn cho kiểu di chuột. Đây là hình ảnh minh hoạ khi sử dụng color-mix():

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

và nếu bạn muốn trộn những màu đó trong một không gian màu khác, chẳng hạn như srgb, hãy thay đổi:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

Sau đây là bản minh hoạ về việc tạo giao diện bằng color-mix(). Hãy thử thay đổi màu thương hiệu và xem giao diện cập nhật:

Hãy thoả sức phối màu trong nhiều không gian màu trong biểu định kiểu vào năm 2022!

Tài nguyên

color-contrast()

Trước color-contrast(), tác giả của biểu định kiểu cần biết trước các màu có thể truy cập. Thường thì bảng màu sẽ hiển thị văn bản màu đen hoặc trắng trên một mẫu màu để cho người dùng hệ thống màu biết màu văn bản nào cần thiết để tương phản đúng cách với mẫu đó.

Ảnh chụp màn hình 3 bảng màu Material, cho thấy 14 màu và màu tương phản thích hợp (trắng hoặc đen) cho văn bản.
Ví dụ về bảng màu Material Design năm 2014

Sau color-contrast(), tác giả biểu định kiểu có thể hoàn toàn chuyển nhiệm vụ này cho trình duyệt. Bạn không chỉ có thể sử dụng trình duyệt để tự động chọn màu đen hoặc trắng, mà còn có thể cung cấp cho trình duyệt một danh sách các màu phù hợp với hệ thống thiết kế và để trình duyệt chọn màu đầu tiên đạt được tỷ lệ tương phản mà bạn mong muốn.

Dưới đây là ảnh chụp màn hình của một bản minh hoạ bộ bảng màu HWB, trong đó màu văn bản được trình duyệt tự động chọn dựa trên màu mẫu:

Ảnh chụp màn hình bản minh hoạ HWB, trong đó mỗi bảng màu có một cặp văn bản sáng hoặc tối khác nhau, do trình duyệt xác định.
Thử bản minh hoạ

Cú pháp cơ bản có dạng như sau, trong đó màu xám được truyền đến hàm và trình duyệt xác định xem màu đen hay màu trắng có độ tương phản cao nhất:

color: color-contrast(gray);

Bạn cũng có thể tuỳ chỉnh hàm này bằng một danh sách màu, trong đó hàm sẽ chọn màu có độ tương phản cao nhất trong số các màu được chọn:

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

Cuối cùng, trong trường hợp bạn không muốn chọn màu có độ tương phản cao nhất trong danh sách, bạn có thể cung cấp tỷ lệ tương phản mục tiêu và màu đầu tiên đạt được tỷ lệ đó sẽ được chọn:

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

Bạn có thể dùng hàm này cho nhiều mục đích khác ngoài màu văn bản, mặc dù tôi ước tính rằng đây sẽ là trường hợp sử dụng chính của hàm. Hãy nghĩ xem việc cung cấp các giao diện dễ đọc và hỗ trợ tiếp cận sẽ dễ dàng hơn bao nhiêu khi việc chọn màu tương phản phù hợp được tích hợp vào chính ngôn ngữ CSS.

Tài nguyên

Cú pháp màu tương đối

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 15.

Source

Trước cú pháp màu tương đối, để tính toán và điều chỉnh màu, các kênh màu cần được đặt riêng lẻ vào các thuộc tính tuỳ chỉnh. Hạn chế này cũng khiến HSL trở thành hàm màu chính để thao tác với màu vì bạn có thể điều chỉnh sắc độ, độ bão hoà hoặc độ sáng theo cách đơn giản bằng calc().

Sau cú pháp màu tương đối, mọi màu trong mọi không gian đều có thể được phân tách, sửa đổi và trả về dưới dạng một màu, tất cả trong một dòng CSS. Không còn hạn chế đối với HSL – bạn có thể thao tác trong bất kỳ không gian màu nào mình muốn và không cần tạo nhiều thuộc tính tuỳ chỉnh để hỗ trợ việc này.

Trong ví dụ về cú pháp sau đây, một giá trị hex cơ sở được cung cấp và hai màu mới được tạo tương ứng với giá trị đó. Màu đầu tiên --absolute-change tạo một màu mới trong LCH từ màu cơ bản, sau đó tiến hành thay thế độ sáng của màu cơ bản bằng 75%, duy trì độ bão hoà (c) và tông màu (h). Màu thứ hai --relative-change tạo một màu mới trong LCH từ màu cơ bản, nhưng lần này giảm độ bão hoà (c) xuống 20%.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

Việc này tương tự như trộn màu, nhưng giống với việc sửa đổi hơn là trộn. Bạn có thể truyền một màu từ một màu khác, có quyền truy cập vào 3 giá trị kênh theo tên của hàm màu được dùng, đồng thời có cơ hội điều chỉnh các kênh đó. Nhìn chung, đây là một cú pháp rất hay và mạnh mẽ cho màu sắc.

Trong bản minh hoạ sau, tôi đã sử dụng cú pháp màu tương đối để tạo các biến thể sáng hơn và tối hơn của màu cơ bản, đồng thời sử dụng color-contrast() để đảm bảo các nhãn có độ tương phản phù hợp:

Ảnh chụp màn hình có 3 cột, mỗi cột có màu tối hơn hoặc sáng hơn cột ở giữa.
Thử bản minh hoạ

Bạn cũng có thể dùng hàm này để tạo bảng màu. Đây là bản minh hoạ về cách tạo toàn bộ bảng màu từ một màu cơ bản được cung cấp. Một nhóm CSS này cung cấp năng lượng cho tất cả các bảng màu, mỗi bảng màu chỉ đơn giản là cung cấp một cơ sở khác. Ngoài ra, vì tôi đã sử dụng LCH, hãy xem các bảng màu này đồng đều như thế nào về mặt cảm quan – không có điểm nóng hoặc điểm chết nào, nhờ vào hệ màu này.

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
Ảnh chụp màn hình 15 bảng màu đều được CSS tạo động.
Thử bản minh hoạ

Hy vọng đến đây bạn có thể thấy cách không gian màu và các hàm màu khác nhau có thể được dùng cho nhiều mục đích, dựa trên điểm mạnh và điểm yếu của chúng.

Tài nguyên

Không gian màu chuyển màu

Trước hệ màu chuyển sắc, sRGB là hệ màu mặc định được sử dụng. sRGB thường đáng tin cậy, nhưng có một số điểm yếu như vùng chết màu xám.

4 hiệu ứng chuyển màu trong một lưới, tất cả đều từ màu lục lam sang màu hồng đậm. LCH và LAB có độ sống động nhất quán hơn, trong khi sRGB có độ bão hoà thấp hơn một chút ở giữa.

Sau không gian màu chuyển màu, hãy cho trình duyệt biết không gian màu cần dùng để nội suy màu. Nhờ đó, nhà phát triển và nhà thiết kế có thể chọn hiệu ứng chuyển màu mà họ muốn. Không gian màu mặc định cũng thay đổi thành LCH thay vì sRGB.

Phần bổ sung cú pháp này nằm sau hướng chuyển màu, sử dụng cú pháp in mới và không bắt buộc:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

Đây là một hiệu ứng chuyển màu cơ bản và thiết yếu từ đen sang trắng. Xem xét phạm vi kết quả trong từng không gian màu. Một số người đạt đến màu đen đậm sớm hơn những người khác, một số người chuyển sang màu trắng quá muộn.

11 không gian màu được hiển thị khi so sánh màu đen với màu trắng.

Trong ví dụ tiếp theo này, màu đen được chuyển sang màu xanh dương vì đây là một khoảng màu có vấn đề đã biết đối với các chuyển màu. Hầu hết các không gian màu đều chuyển sang màu tím trong quá trình nội suy màu hoặc, như tôi thường nghĩ, khi màu sắc di chuyển trong không gian màu của chúng từ điểm A đến điểm B. Vì dải chuyển màu sẽ lấy một đường thẳng từ điểm A đến điểm B, nên hình dạng của không gian màu sẽ thay đổi đáng kể các điểm dừng mà đường dẫn đi qua.

11 không gian màu được hiển thị khi so sánh màu xanh dương với màu đen.

Để tìm hiểu sâu hơn, xem các ví dụ và bình luận, hãy đọc chuỗi bài đăng này trên Twitter.

Tài nguyên

inert

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112.
  • Safari: 15.5.

Source

Trước inert, bạn nên hướng sự tập trung của người dùng vào những khu vực cần được chú ý ngay trên trang hoặc ứng dụng. Chiến lược tiêu điểm có hướng dẫn này được gọi là bẫy tiêu điểm vì các nhà phát triển sẽ đặt tiêu điểm vào một không gian tương tác, theo dõi các sự kiện thay đổi tiêu điểm và nếu tiêu điểm rời khỏi không gian tương tác, thì tiêu điểm sẽ bị buộc quay lại. Người dùng sử dụng bàn phím hoặc trình đọc màn hình sẽ được hướng dẫn quay lại không gian tương tác để đảm bảo hoàn tất tác vụ trước khi chuyển sang tác vụ khác.

Sau inert, bạn không cần phải bẫy vì bạn có thể đóng băng hoặc bảo vệ toàn bộ các phần của trang hoặc ứng dụng. Các lượt nhấp và nỗ lực thay đổi tiêu điểm sẽ không có sẵn khi những phần đó của tài liệu không hoạt động. Bạn cũng có thể coi đây là những người bảo vệ thay vì một cái bẫy, trong đó inert không muốn bạn ở lại một nơi nào đó, mà là khiến những nơi khác không truy cập được.

Một ví dụ điển hình về điều này là hàm alert() JavaScript:

Trang web hiển thị ở dạng tương tác, sau đó một alert() được gọi và trang không còn hoạt động nữa.

Hãy lưu ý trong video trước đó cách người dùng có thể truy cập vào trang bằng chuột và bàn phím cho đến khi alert() được gọi. Sau khi hộp thoại cảnh báo bật lên, phần còn lại của trang bị đóng băng hoặc inert. Tiêu điểm của người dùng được đặt bên trong hộp thoại cảnh báo và không có nơi nào khác để chuyển hướng. Sau khi người dùng tương tác và hoàn tất yêu cầu chức năng cảnh báo, trang sẽ tương tác trở lại. inert cho phép nhà phát triển dễ dàng đạt được trải nghiệm tập trung có hướng dẫn tương tự.

Dưới đây là một đoạn mã nhỏ minh hoạ cách hoạt động của tính năng này:

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

Hộp thoại là một ví dụ điển hình, nhưng inert cũng hữu ích cho những việc như trải nghiệm người dùng của trình đơn bên dạng trượt ra. Khi người dùng trượt trình đơn bên ra, bạn không nên cho phép chuột hoặc bàn phím tương tác với trang ở phía sau. Điều này sẽ gây khó khăn cho người dùng. Thay vào đó, khi trình đơn bên đang hiển thị, hãy làm cho trang trở nên trơ, và giờ đây, người dùng phải đóng hoặc di chuyển trong trình đơn bên đó, và sẽ không bao giờ thấy mình bị lạc ở đâu đó khác trong trang có trình đơn đang mở.

Tài nguyên

Phông chữ COLRv1

Trước phông chữ COLRv1, web có phông chữ OT-SVG, cũng là một định dạng mở cho phông chữ có hiệu ứng chuyển màu và màu sắc cũng như hiệu ứng tích hợp. Tuy nhiên, những thẻ này có thể phát triển rất lớn và mặc dù cho phép chỉnh sửa văn bản, nhưng không có nhiều phạm vi để tuỳ chỉnh.

Sau phông chữ COLRv1, web có kích thước nhỏ hơn, có thể mở rộng theo vectơ, có thể định vị lại, có tính năng chuyển màu và có phông chữ dựa trên chế độ hoà trộn chấp nhận các tham số để tuỳ chỉnh phông chữ theo từng trường hợp sử dụng hoặc để phù hợp với một thương hiệu.

Hình ảnh minh hoạ so sánh và biểu đồ dạng cột cho thấy phông chữ COLRv1 sắc nét và nhỏ hơn.
Hình ảnh lấy từ https://developer.chrome.com/blog/colrv1-fonts/

Dưới đây là một ví dụ trong bài đăng trên blog của Nhà phát triển Chrome về biểu tượng cảm xúc. Có thể bạn đã nhận thấy rằng nếu bạn tăng kích thước phông chữ trên một biểu tượng cảm xúc, thì biểu tượng đó sẽ không giữ được độ sắc nét. Đây là hình ảnh chứ không phải ảnh vectơ. Trong các ứng dụng, khi một biểu tượng cảm xúc được dùng, biểu tượng đó thường được thay thế bằng một thành phần có chất lượng cao hơn. Với phông chữ COLRv1, các biểu tượng cảm xúc đều là vectơ và rất đẹp:

Phông chữ biểu tượng có thể làm được một số việc đáng kinh ngạc với định dạng này, chẳng hạn như cung cấp bảng màu tuỳ chỉnh gồm 2 tông màu, v.v. Việc tải một phông chữ COLRv1 cũng giống như bất kỳ tệp phông chữ nào khác:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

Bạn có thể tuỳ chỉnh phông chữ COLRv1 bằng @font-palette-values, một quy tắc đặc biệt của CSS để nhóm và đặt tên cho một bộ tuỳ chọn tuỳ chỉnh thành một gói để tham chiếu sau này. Lưu ý cách bạn chỉ định tên tuỳ chỉnh giống như một thuộc tính tuỳ chỉnh, bắt đầu bằng --:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

Với --colorized làm bí danh cho các chế độ tuỳ chỉnh, bước cuối cùng là áp dụng bảng màu cho một phần tử đang sử dụng họ phông chữ màu:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
Ảnh chụp màn hình phông chữ Bungee Spice với từ DUNE.
Phông chữ Bungee Spice xuất hiện với màu tuỳ chỉnh, nguồn từ https://developer.chrome.com/blog/colrv1-fonts/

Khi ngày càng có nhiều phông chữ biến đổi và phông chữ màu xuất hiện, kiểu chữ trên web đang đi trên một con đường rất tuyệt vời hướng tới khả năng tuỳ chỉnh phong phú và thể hiện sự sáng tạo.

Tài nguyên

Đơn vị khung nhìn

Hình ảnh minh hoạ cách màn hình thiết bị, cửa sổ trình duyệt và iframe đều có các khung hiển thị khác nhau.

Trước các biến thể khung hiển thị mới, web cung cấp các đơn vị vật lý để hỗ trợ việc điều chỉnh khung hiển thị. Có một giá trị cho chiều cao, chiều rộng, kích thước nhỏ nhất (vmin) và cạnh lớn nhất (vmax). Những điều này hoạt động hiệu quả cho nhiều việc, nhưng trình duyệt di động lại gây ra một sự phức tạp.

Trên thiết bị di động, khi tải một trang, thanh trạng thái có URL sẽ xuất hiện và thanh này chiếm một phần không gian khung hiển thị. Sau vài giây và một số hoạt động tương tác, thanh trạng thái có thể trượt đi để người dùng có trải nghiệm khung hiển thị lớn hơn. Nhưng khi thanh đó trượt ra, chiều cao khung hiển thị đã thay đổi và mọi đơn vị vh sẽ dịch chuyển và thay đổi kích thước khi kích thước mục tiêu của chúng thay đổi. Trong những năm sau đó, đơn vị vh này cần phải quyết định cụ thể sẽ sử dụng kích thước khung hiển thị nào trong hai kích thước, vì điều này gây ra các vấn đề về bố cục trực quan khó chịu trên thiết bị di động. Người ta xác định rằng vh sẽ luôn đại diện cho khung nhìn lớn nhất.

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

Sau các biến thể khung nhìn mới, các đơn vị khung nhìn nhỏ, lớn và động sẽ được cung cấp, cùng với việc bổ sung các đơn vị tương đương logic cho các đơn vị vật lý. Ý tưởng là cho phép nhà phát triển và nhà thiết kế chọn đơn vị mà họ muốn sử dụng cho một tình huống cụ thể. Có thể bạn không cần lo lắng về việc bố cục bị thay đổi đột ngột một chút khi thanh trạng thái biến mất, vì khi đó bạn có thể dùng dvh (chiều cao khung hiển thị động).

Hình ảnh minh hoạ có 3 chiếc điện thoại để minh hoạ DVH, LVH và SVH. Điện thoại ví dụ DVH có hai đường thẳng dọc, một đường thẳng giữa cuối thanh tìm kiếm và cuối khung hiển thị, còn một đường thẳng giữa phía trên thanh tìm kiếm (bên dưới thanh trạng thái hệ thống) đến cuối khung hiển thị; cho thấy DVH có thể có một trong hai độ dài này. LVH xuất hiện ở giữa, có một đường kẻ giữa cuối thanh trạng thái của thiết bị và nút của khung hiển thị điện thoại. Ví dụ cuối cùng là đơn vị SVH, cho thấy một đường kẻ từ cuối thanh tìm kiếm của trình duyệt đến cuối khung nhìn

Dưới đây là danh sách đầy đủ tất cả các lựa chọn mới về đơn vị khung hiển thị được cung cấp cùng với các biến thể khung hiển thị mới:

Đơn vị chiều cao của khung nhìn
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
Đơn vị chiều rộng khung nhìn
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
Đơn vị bên nhỏ nhất của khung nhìn
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Đơn vị bên lớn nhất của khung nhìn
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

Hy vọng những thông tin này sẽ mang đến cho nhà phát triển và nhà thiết kế sự linh hoạt cần thiết để đạt được các thiết kế đáp ứng khung hiển thị.

Tài nguyên

:has()

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

Trước :has(), đối tượng của bộ chọn luôn ở cuối. Ví dụ: chủ đề của bộ chọn này là một mục trong danh sách: ul > li. Bộ chọn giả có thể thay đổi bộ chọn nhưng không thay đổi đối tượng: ul > li:hover hoặc ul > li:not(.selected).

Sau :has(), một đối tượng ở cấp cao hơn trong cây phần tử vẫn có thể là đối tượng trong khi cung cấp một truy vấn về các đối tượng con: ul:has(> li). Bạn có thể dễ dàng hiểu được cách :has() có tên gọi chung là "bộ chọn mẹ", vì đối tượng của bộ chọn hiện là phần tử mẹ trong trường hợp này.

Sau đây là ví dụ về cú pháp cơ bản, trong đó lớp .parent vẫn là chủ đề nhưng chỉ được chọn nếu phần tử con có lớp .child:

.parent:has(.child) {...}

Sau đây là ví dụ trong đó phần tử <section> là đối tượng, nhưng bộ chọn chỉ khớp nếu một trong các phần tử con có :focus-visible:

section:has(*:focus-visible) {...}

Trình chọn :has() bắt đầu trở thành một tiện ích tuyệt vời khi có nhiều trường hợp sử dụng thực tế hơn. Ví dụ: hiện tại, bạn không thể chọn thẻ <a> khi thẻ này bao bọc hình ảnh, khiến bạn khó hướng dẫn thẻ liên kết cách thay đổi kiểu khi ở trường hợp sử dụng đó. Tuy nhiên, bạn có thể làm được việc này bằng :has():

a:has(> img) {...}

Đây đều là những ví dụ mà :has() chỉ trông giống như một bộ chọn gốc. Cân nhắc trường hợp sử dụng hình ảnh bên trong các phần tử <figure> và điều chỉnh kiểu cho hình ảnh nếu hình ảnh có <figcaption>. Trong ví dụ sau, các số liệu có chú thích hình được chọn, sau đó là hình ảnh trong ngữ cảnh đó. :has() được dùng và không thay đổi chủ đề, vì chủ đề mà chúng ta đang nhắm đến là hình ảnh chứ không phải số liệu:

figure:has(figcaption) img {...}

Có vô số cách kết hợp. Kết hợp :has() với các truy vấn về số lượng và điều chỉnh bố cục lưới CSS dựa trên số lượng phần tử con. Kết hợp :has() với các trạng thái giả lớp tương tác và tạo các ứng dụng phản hồi theo những cách sáng tạo mới.

Việc kiểm tra khả năng hỗ trợ trở nên đơn giản nhờ @supports và hàm selector() của nó. Hàm này kiểm thử xem trình duyệt có hiểu cú pháp hay không trước khi sử dụng:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

Tài nguyên

Năm 2022 trở đi

Vẫn còn một số việc khó thực hiện sau khi tất cả những tính năng tuyệt vời này ra mắt vào năm 2022. Phần tiếp theo sẽ xem xét một số vấn đề còn lại và các giải pháp đang được tích cực phát triển để giải quyết những vấn đề đó. Những giải pháp này đang trong giai đoạn thử nghiệm, mặc dù có thể được chỉ định hoặc có sẵn sau các cờ trong trình duyệt.

Kết quả của các phần tiếp theo sẽ là sự thoải mái khi biết rằng những vấn đề được liệt kê có nhiều người từ nhiều công ty đang tìm cách giải quyết, chứ không phải là những giải pháp này sẽ được phát hành vào năm 2023.

Thuộc tính tuỳ chỉnh được nhập lỏng lẻo

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

Thuộc tính tuỳ chỉnh của CSS rất tuyệt vời. Chúng cho phép lưu trữ mọi loại dữ liệu bên trong một biến được đặt tên, sau đó có thể mở rộng, tính toán, chia sẻ và nhiều thao tác khác. Trên thực tế, chúng quá linh hoạt, nên sẽ tốt hơn nếu có một số ít linh hoạt hơn.

Hãy xem xét một trường hợp mà box-shadow sử dụng các thuộc tính tuỳ chỉnh cho các giá trị của nó:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

Mọi thứ đều hoạt động tốt cho đến khi một trong các thuộc tính được thay đổi thành một giá trị mà CSS không chấp nhận, chẳng hạn như --x: red. Toàn bộ dữ liệu bóng sẽ bị hỏng nếu có bất kỳ biến lồng nào bị thiếu hoặc được đặt thành một loại giá trị không hợp lệ.

Đây là lúc @property phát huy tác dụng: --x có thể trở thành một thuộc tính tuỳ chỉnh được nhập, không còn lỏng lẻo và linh hoạt nữa, mà an toàn với một số ranh giới được xác định:

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

Giờ đây, khi box-shadow sử dụng var(--x) và sau đó --x: red được thử, red sẽ bị bỏ qua vì đây không phải là <length>. Điều này có nghĩa là bóng đổ vẫn tiếp tục hoạt động, ngay cả khi một giá trị không hợp lệ được gán cho một trong các thuộc tính tuỳ chỉnh của bóng đổ. Thay vì thất bại, nó sẽ quay trở lại initial-value của 0px.

Hoạt ảnh

Ngoài tính an toàn của kiểu, nó còn mở ra nhiều cơ hội cho ảnh động. Tính linh hoạt của cú pháp CSS khiến việc tạo ảnh động cho một số đối tượng trở nên bất khả thi, chẳng hạn như các chuyển màu. @property sẽ giúp ích ở đây vì thuộc tính CSS được nhập có thể cho trình duyệt biết ý định của nhà phát triển trong quá trình nội suy phức tạp. Về cơ bản, điều này giới hạn phạm vi khả năng đến mức trình duyệt có thể tạo ảnh động cho các khía cạnh của một kiểu mà trước đây trình duyệt không thể làm được.

Hãy xem xét ví dụ minh hoạ này, trong đó một vùng chuyển màu dạng hình tròn được dùng để tạo một phần của lớp phủ, tạo hiệu ứng tiêu điểm nổi bật. JavaScript đặt x và y của chuột khi phím alt/opt được nhấn, sau đó thay đổi kích thước tiêu điểm thành một giá trị nhỏ hơn, chẳng hạn như 25%, tạo vòng tròn tiêu điểm nổi bật tại vị trí chuột:

Dùng thử bản minh hoạ
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

Tuy nhiên, bạn không thể tạo hiệu ứng chuyển màu. Chúng quá linh hoạt và quá phức tạp để trình duyệt có thể "chỉ cần suy ra" cách bạn muốn chúng chuyển động. Tuy nhiên, với @property, một thuộc tính có thể được nhập và tạo hiệu ứng động riêng biệt, nhờ đó trình duyệt có thể dễ dàng hiểu được ý định.

Trò chơi điện tử sử dụng hiệu ứng tiêu điểm này luôn tạo ảnh động cho vòng tròn, từ một vòng tròn lớn đến một vòng tròn nhỏ như lỗ kim. Sau đây là cách sử dụng @property với bản minh hoạ của chúng tôi để trình duyệt tạo hiệu ứng cho mặt nạ chuyển màu:

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
Dùng thử bản minh hoạ

Giờ đây, trình duyệt có thể tạo ảnh động cho kích thước của hiệu ứng chuyển màu vì chúng ta đã giảm diện tích sửa đổi xuống chỉ còn một thuộc tính và nhập giá trị để trình duyệt có thể nội suy độ dài một cách thông minh.

@property có thể làm được nhiều việc hơn nữa, nhưng những tính năng nhỏ này có thể mang lại hiệu quả lớn.

Tài nguyên

Đã ở min-width hoặc max-width

Trước các dải truy vấn nội dung nghe nhìn, truy vấn nội dung nghe nhìn CSS sử dụng min-widthmax-width để diễn đạt các điều kiện trên và dưới. Thông báo có thể như sau:

@media (min-width: 320px) {
  
}

Sau các dải truy vấn nội dung nghe nhìn, cùng một truy vấn nội dung nghe nhìn có thể trông như sau:

@media (width >= 320px) {
  
}

Một truy vấn phương tiện CSS sử dụng cả min-widthmax-width có thể có dạng như sau:

@media (min-width: 320px) and (max-width: 1280px) {
  
}

Sau các dải truy vấn nội dung nghe nhìn, cùng một truy vấn nội dung nghe nhìn có thể trông như sau:

@media (320px <= width <= 1280px) {
  
}

Tuỳ thuộc vào kinh nghiệm lập trình của bạn, một trong hai cách đó sẽ dễ đọc hơn nhiều so với cách còn lại. Nhờ những điểm bổ sung này, nhà phát triển có thể chọn điểm mà họ muốn hoặc thậm chí sử dụng các điểm này thay thế cho nhau.

Tài nguyên

Không có biến truy vấn về nội dung nghe nhìn

Trước @custom-media, các truy vấn nội dung nghe nhìn phải lặp lại nhiều lần hoặc dựa vào các trình tiền xử lý để tạo đầu ra thích hợp dựa trên các biến tĩnh trong thời gian xây dựng.

Sau @custom-media, CSS cho phép đặt tên thay thế cho truy vấn phương tiện và tham chiếu đến các truy vấn đó, giống như một thuộc tính tuỳ chỉnh.

Việc đặt tên cho mọi thứ là rất quan trọng: nó có thể điều chỉnh mục đích cho phù hợp với cú pháp, giúp mọi người dễ dàng chia sẻ và sử dụng hơn trong nhóm. Sau đây là một số truy vấn nội dung nghe nhìn tuỳ chỉnh theo tôi giữa các dự án:

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

Giờ đây, sau khi xác định xong, tôi có thể sử dụng một trong các đối tượng đó như sau:

@media (--OSdark) {
  :root {
    
  }
}

Tìm danh sách đầy đủ các truy vấn nội dung nghe nhìn tuỳ chỉnh mà tôi sử dụng trong thư viện thuộc tính tuỳ chỉnh CSS Open Props.

Tài nguyên

Việc lồng bộ chọn rất hữu ích

Trước @nest, có rất nhiều nội dung lặp lại trong biểu định kiểu. Việc này trở nên đặc biệt khó khăn khi bộ chọn dài và mỗi bộ chọn nhắm đến những điểm khác biệt nhỏ. Sự tiện lợi của việc lồng ghép là một trong những lý do phổ biến nhất để áp dụng một trình tiền xử lý.

Sau @nest, chế độ lặp lại sẽ biến mất. Gần như mọi tính năng của tính năng lồng ghép được hỗ trợ bởi trình tiền xử lý sẽ được tích hợp vào CSS.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

Điều quan trọng nhất đối với tôi về việc lồng, ngoài việc không lặp lại article trong bộ chọn lồng nhau, là bối cảnh tạo kiểu vẫn nằm trong một khối kiểu. Thay vì chuyển từ một bộ chọn và kiểu của bộ chọn đó sang một bộ chọn khác có kiểu (ví dụ 1), người đọc có thể vẫn ở trong ngữ cảnh của một bài viết và xem bài viết có các đường liên kết bên trong. Mối quan hệ và ý định về kiểu được kết hợp với nhau, vì vậy article sẽ xuất hiện để sở hữu các kiểu riêng.

Quyền sở hữu cũng có thể được coi là sự tập trung. Thay vì tìm kiếm các kiểu có liên quan trong một biểu định kiểu, bạn có thể tìm thấy tất cả các kiểu được lồng với nhau trong một ngữ cảnh. Điều này áp dụng cho cả mối quan hệ từ mẹ sang con và từ con sang mẹ.

Hãy xem xét một thành phần con muốn điều chỉnh chính nó khi ở trong một ngữ cảnh mẹ khác, thay vì thành phần mẹ sở hữu kiểu và thay đổi thành phần con:

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

@nest giúp tổ chức, tập trung và sở hữu kiểu dáng lành mạnh hơn. Các thành phần có thể nhóm và sở hữu các kiểu riêng, thay vì để các kiểu đó trải rộng trong số các khối kiểu khác. Có thể bạn thấy kích thước này nhỏ trong những ví dụ này, nhưng nó có thể có tác động rất lớn, cả về sự thuận tiện và khả năng đọc.

Tài nguyên

Việc tạo kiểu theo phạm vi thực sự khó khăn

Browser Support

  • Chrome: 118.
  • Edge: 118.
  • Firefox: behind a flag.
  • Safari: 17.4.

Source

Trước @scope, có nhiều chiến lược tồn tại vì các kiểu trong CSS xếp tầng, kế thừa và được phạm vi toàn cầu theo mặc định. Những tính năng này của CSS rất tiện lợi cho nhiều việc, nhưng đối với các trang web và ứng dụng phức tạp, có thể có nhiều kiểu thành phần khác nhau, không gian chung và bản chất của tầng có thể khiến các kiểu trông như thể chúng đang bị rò rỉ.

Sau @scope, không chỉ có thể giới hạn phạm vi kiểu trong một ngữ cảnh (chẳng hạn như một lớp), mà bạn còn có thể xác định nơi kiểu kết thúc và không tiếp tục xếp tầng hoặc kế thừa.

Trong ví dụ sau, phạm vi quy ước đặt tên BEM có thể được đảo ngược thành ý định thực tế. Bộ chọn BEM đang cố gắng đặt phạm vi màu của phần tử header thành vùng chứa .card theo quy ước đặt tên. Điều này yêu cầu tiêu đề phải có tên lớp này, hoàn thành mục tiêu. Với @scope, bạn không cần quy ước đặt tên để hoàn thành cùng một mục tiêu mà không cần đánh dấu phần tử tiêu đề:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

Sau đây là một ví dụ khác, ít cụ thể về thành phần hơn và tập trung hơn vào bản chất phạm vi toàn cầu của CSS. Giao diện tối và sáng phải cùng tồn tại trong một biểu định kiểu, trong đó thứ tự có vai trò quan trọng trong việc xác định kiểu chiến thắng. Thông thường, điều này có nghĩa là các kiểu giao diện tối sẽ xuất hiện sau giao diện sáng; điều này thiết lập giao diện sáng làm mặc định và giao diện tối làm kiểu không bắt buộc. Tránh việc sắp xếp và tranh giành phạm vi với @scope:

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

Để hoàn tất câu chuyện ở đây, @scope cũng cho phép thiết lập vị trí kết thúc phạm vi kiểu. Bạn không thể thực hiện việc này bằng bất kỳ quy ước đặt tên hoặc trình tiền xử lý nào; đây là một quy tắc đặc biệt và chỉ có CSS tích hợp sẵn trong trình duyệt mới có thể thực hiện. Trong ví dụ sau, các kiểu img.content chỉ được áp dụng khi một phần tử con của .media-block là phần tử cùng cấp hoặc phần tử gốc của .content:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

Tài nguyên

Không có cách nào để tạo bố cục kiểu xếp gạch bằng CSS

Trước khi có bố cục dạng khối CSS với lưới, JavaScript là cách tốt nhất để tạo bố cục dạng khối, vì bất kỳ phương thức CSS nào có cột hoặc flexbox đều sẽ thể hiện không chính xác thứ tự nội dung.

Sau khi CSS masonry có lưới, bạn sẽ không cần đến các thư viện JavaScript và thứ tự nội dung sẽ chính xác.

Ảnh chụp màn hình bố cục kiểu xếp gạch cho thấy các con số di chuyển dọc theo phía trên cùng, sau đó đi xuống.
Hình ảnh và bản minh hoạ của Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

Bạn có thể đạt được bản minh hoạ trên bằng CSS sau:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Thật yên tâm khi biết rằng đây là một chiến lược bố cục còn thiếu và bạn có thể dùng thử ngay hôm nay trong Firefox.

Tài nguyên

CSS không thể giúp người dùng giảm dữ liệu

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Source

Trước truy vấn nội dung nghe nhìn prefers-reduced-data, JavaScript và một máy chủ có thể thay đổi hành vi của chúng dựa trên hệ điều hành hoặc lựa chọn "trình tiết kiệm dữ liệu" của trình duyệt của người dùng, nhưng CSS thì không thể.

Sau truy vấn nội dung nghe nhìn prefers-reduced-data, CSS có thể tham gia vào việc nâng cao trải nghiệm người dùng và đóng vai trò trong việc lưu dữ liệu.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

CSS ở trên được dùng trong thành phần cuộn nội dung nghe nhìn này và mức tiết kiệm có thể rất lớn. Tuỳ thuộc vào kích thước của khung hiển thị mà bạn truy cập, bạn sẽ tiết kiệm được càng nhiều thời gian tải trang. Quá trình lưu sẽ tiếp tục khi người dùng tương tác với các trình cuộn nội dung nghe nhìn. Tất cả hình ảnh đều có thuộc tính loading="lazy" và điều đó, kết hợp với CSS ẩn hoàn toàn phần tử, có nghĩa là yêu cầu mạng cho hình ảnh sẽ không bao giờ được thực hiện.

Ảnh chụp màn hình giao diện băng chuyền chương trình truyền hình, trong đó có nhiều hình thu nhỏ và tiêu đề.

Đối với thử nghiệm của tôi, trên một khung nhìn có kích thước trung bình, ban đầu đã tải 40 yêu cầu và 700 kb tài nguyên. Khi người dùng cuộn danh sách lựa chọn nội dung nghe nhìn, nhiều yêu cầu và tài nguyên khác sẽ được tải. Với CSS và truy vấn nội dung nghe nhìn có dữ liệu giảm, 10 yêu cầu và 172 kb tài nguyên được tải. Đó là mức tiết kiệm nửa megabyte và người dùng thậm chí chưa cuộn bất kỳ nội dung nghe nhìn nào, tại thời điểm đó, không có yêu cầu nào khác được thực hiện.

Ảnh chụp màn hình giao diện băng chuyền chương trình truyền hình không có hình thu nhỏ và có nhiều tiêu đề.

Trải nghiệm sử dụng ít dữ liệu hơn mang lại nhiều lợi ích hơn là chỉ tiết kiệm dữ liệu. Bạn có thể xem nhiều tiêu đề hơn và không có hình ảnh bìa gây xao lãng để thu hút sự chú ý. Nhiều người dùng duyệt web ở chế độ tiết kiệm dữ liệu vì họ trả tiền theo mỗi megabyte dữ liệu. Thật tuyệt khi thấy CSS có thể giúp ích trong trường hợp này.

Tài nguyên

Các tính năng cuộn nhanh quá hạn chế

Trước những đề xuất về tính năng chụp nhanh khi cuộn này, việc viết JavaScript của riêng bạn để quản lý băng chuyền, thanh trượt hoặc thư viện có thể nhanh chóng trở nên phức tạp, với tất cả các trình quan sát và hoạt động quản lý trạng thái. Ngoài ra, nếu không cẩn thận, tốc độ cuộn tự nhiên có thể được chuẩn hoá bằng tập lệnh, khiến hoạt động tương tác của người dùng có cảm giác hơi không tự nhiên và có thể vụng về.

API mới

snapChanging()

Sự kiện này sẽ kích hoạt ngay khi trình duyệt phát hành một tiến trình con snap. Điều này cho phép giao diện người dùng phản ánh việc thiếu một thành phần con có thể di chuyển nhanh và trạng thái di chuyển nhanh không xác định của trình cuộn, vì thành phần này hiện đang được dùng và sẽ xuất hiện ở một vị trí mới.

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

Sự kiện này sẽ kích hoạt ngay khi trình duyệt chuyển nhanh đến một thành phần con mới và trình cuộn ở trạng thái nghỉ. Điều này cho phép mọi giao diện người dùng phụ thuộc vào thành phần con được căn chỉnh nhanh cập nhật và phản ánh mối kết nối.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

Không phải lúc nào hoạt động cuộn cũng bắt đầu từ đầu. Hãy cân nhắc sử dụng các thành phần có thể vuốt, trong đó thao tác vuốt sang trái hoặc phải sẽ kích hoạt các sự kiện khác nhau, hoặc một thanh tìm kiếm ban đầu bị ẩn khi tải trang cho đến khi bạn cuộn lên đầu trang. Thuộc tính CSS này cho phép nhà phát triển chỉ định rằng một thành phần cuộn sẽ bắt đầu tại một điểm cụ thể.

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

Bộ chọn CSS này sẽ khớp với các phần tử trong một vùng chứa cuộn nhanh hiện đang được trình duyệt cuộn nhanh.

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

Sau những đề xuất về tính năng căn chỉnh khi cuộn này, việc tạo một thanh trượt, băng chuyền hoặc thư viện trở nên dễ dàng hơn nhiều vì trình duyệt hiện cung cấp các tiện ích cho tác vụ này, loại bỏ các đối tượng theo dõi và mã điều phối hoạt động cuộn để sử dụng các API tích hợp.

Đây vẫn là giai đoạn ban đầu của các tính năng CSS và JS này, nhưng hãy chú ý đến các polyfill có thể giúp việc áp dụng và thử nghiệm các tính năng này diễn ra nhanh chóng.

Tài nguyên

Chuyển đổi giữa các trạng thái đã biết

Trước toggle(), bạn chỉ có thể tận dụng các trạng thái đã được tích hợp sẵn vào trình duyệt để tạo kiểu và tương tác. Ví dụ: hộp đánh dấu có :checked, một trạng thái trình duyệt được quản lý nội bộ cho dữ liệu đầu vào mà CSS có thể dùng để thay đổi phần tử một cách trực quan.

Sau toggle(), bạn có thể tạo trạng thái tuỳ chỉnh trên mọi phần tử để CSS thay đổi và sử dụng cho việc tạo kiểu. Chế độ này cho phép nhóm, đạp xe, chuyển đổi có hướng dẫn và nhiều thao tác khác.

Trong ví dụ sau, hiệu ứng gạch ngang của một mục trong danh sách khi hoàn tất sẽ được thực hiện nhưng không có bất kỳ phần tử hộp đánh dấu nào:

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

Và các kiểu CSS toggle() có liên quan:

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

Nếu đã quen thuộc với các máy trạng thái, bạn có thể nhận thấy mức độ trùng lặp với toggle(). Tính năng này sẽ cho phép nhà phát triển tạo thêm trạng thái của họ vào CSS, hy vọng sẽ mang lại những cách rõ ràng và ngữ nghĩa hơn để điều phối tương tác và trạng thái.

Tài nguyên

Tuỳ chỉnh các phần tử chọn

Trước <selectmenu>, CSS không có khả năng tuỳ chỉnh các phần tử <option> bằng HTML đa dạng hoặc thay đổi nhiều về cách hiển thị danh sách các lựa chọn. Điều này khiến các nhà phát triển phải tải các thư viện bên ngoài để tạo lại phần lớn chức năng của một <select>, dẫn đến việc tốn rất nhiều công sức.

Sau <selectmenu>, nhà phát triển có thể cung cấp HTML đa dạng thức cho các phần tử lựa chọn và tạo kiểu cho các phần tử đó theo nhu cầu, đồng thời vẫn đáp ứng các yêu cầu về khả năng tiếp cận và cung cấp HTML ngữ nghĩa.

Trong ví dụ sau, lấy từ <selectmenu> trang giải thích, một trình đơn chọn mới được tạo với một số lựa chọn cơ bản:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

CSS có thể nhắm đến và tạo kiểu cho các phần của phần tử:

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

Một trình đơn chọn tìm kiếm có màu nhấn là màu đỏ.

Bạn có thể dùng thử phần tử <selectmenu> trên Chromium trong Canary khi bật cờ webexperiments. Hãy chú ý đến các phần tử trình đơn chọn có thể tuỳ chỉnh trong năm 2023 và những năm tiếp theo.

Tài nguyên

Ghim một phần tử vào một phần tử khác

Trước anchor(), vị trí tuyệt đối và tương đối là các chiến lược vị trí được cung cấp cho nhà phát triển để các phần tử con di chuyển trong một phần tử mẹ.

Sau anchor(), nhà phát triển có thể đặt các phần tử vào các phần tử khác, bất kể chúng có phải là phần tử con hay không. Ngoài ra, thuộc tính này còn cho phép nhà phát triển chỉ định cạnh để định vị, cũng như các điểm đặc biệt khác để tạo mối quan hệ vị trí giữa các phần tử.

Phần giải thích này có một số ví dụ và mã mẫu hữu ích được cung cấp, nếu bạn muốn tìm hiểu thêm.

Tài nguyên