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

Các tính năng định kiểu web của hôm nay và ngày mai, như bạn thấy tại Google IO 2022, cùng một số tính năng bổ sung.

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

Tổng quan

Bài đăng này là dạng bài viết của bài nói chuyện được đưa ra tại Google IO 2022. Không có ý nghĩa 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 để khơi gợi sự quan tâm của bạn, cung cấp thông tin bao quát thay vì chuyên sâu. Nếu có người quan tâm, hãy xem cuối phần này để tìm hiểu các đường liên kết đến tài nguyên tham khảo thêm thông tin.

Mục lục

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

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

Mộ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à vì những nỗ lực của Interop 2022. Trước khi nghiên cứu các hoạt động của Interop, bạn cần xem xét những nỗ lực của Compat 2021.

Tương thích 2021

Dựa trên ý kiến phản hồi của nhà phát triển thông qua các bản khảo sát, mục tiêu cho năm 2021 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ố vượt qua của các trình duyệt cho 5 tính năng:

  1. Định vị sticky
  2. Kích thước aspect-ratio
  3. Bố cục flex
  4. Bố cục grid
  5. Vị trí và ảnh động transform

Điểm kiểm thử đã được nâng lên, cho thấy độ ổn định và độ tin cậy đã được nâng cấp. Xin chúc mừng các đội ở đây!

Interop 2022

Năm nay, các trình duyệt đã cùng nhau họp để thảo luận về các tính năng và mức độ ưu tiên mà họ dự định phát triển, đồng thời hợp nhất các nỗ lực của họ. Họ dự định cung cấp các tính năng web sau đây cho các nhà phát triển:

  1. @layer
  2. Không gian và hàm màu
  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 con
  8. Kiểu chữ
  9. Đơn vị khung nhìn
  10. Khả năng tương thích trên web

Đây là một danh sách thú vị và đầy tham vọng mà tôi rất nóng lòng được mở ra.

Nội dung mới cho năm 2022

Không có gì đáng ngạc nhiên khi hoạt động Interop 2022 ảnh hưởng rất lớn đến trạng thái của CSS 2022.

Lớp tầng

Hỗ trợ trình duyệt

  • 99
  • 99
  • 97
  • 15,4

Nguồn

Trước @layer, thứ tự đã phát hiện của các biểu định kiểu được tải là rất quan trọng, vì 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 được quản lý một cách tỉ mỉ, trong đó nhà phát triển phải tải các kiểu ít quan trọng hơn trước và các kiểu quan trọng hơn sau. Toàn bộ phương pháp tồn tại để 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 các lớp đó trước. Sau đó, khi tải kiểu, được tải hoặc xác định, các kiểu này có thể được đặt trong một lớp, cho phép duy trì mức độ quan trọng của ghi đè kiểu mà không cần điều phối việc tải được quản lý tỉ mỉ.

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

Công cụ của Chrome cho nhà phát triển rất hữu ích trong việc trực quan hoá kiểu nào đến từ lớp nào:

Ảnh chụp màn hình thanh bên Kiểu của Chrome Devtools, làm nổi bật cách kiểu xuất hiện trong các nhóm Lớp mới.

Tài nguyên

Lưới con

Hỗ trợ trình duyệt

  • 117
  • 117
  • 71
  • 16

Nguồn

Trước subgrid, lưới bên trong một lưới khác không thể tự căn chỉnh với các ô mẹ hoặc đường lưới đó. Mỗi bố cục lưới 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 mình và liên tục căn chỉnh các mục trong đó. Đây là điều không thể làm được trong CSS.

Sau subgrid, phần tử con của lưới có thể áp dụng các cột hoặc hàng của phần tử mẹ dưới dạng riêng và tự căn chỉnh hoặc căn chỉnh theo các phần tử con tương ứng!

Trong bản minh hoạ sau đây, phần tử nội dung tạo một lưới cổ điển gồm 3 cột: cột ở giữa được gọi là main, còn các cột bên trái và bên phải đặt tên cho các dòng fullbleed. Sau đó, mỗi phần tử trong phần nội dung (<nav><main>) sẽ áp dụng các dòng được đặt tên trong phần 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, 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ột và dòng fullbleedmain.

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

.fullbleed {
  grid-column: fullbleed;
}

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

Ảnh chụp màn hình bản minh hoạ lưới con, sử dụng công cụ lớp phủ lưới của Chrome Devtools để hiển thị các đường 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ể xem các phần tử nào là lưới và lưới con. Các phần tử này rất hữu ích khi 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 Phần tử của Chrome Devtools cho biết những phần tử có bố cục lưới hoặc lưới con.
Ảnh chụp màn hình từ Firefox Devtools

Tài nguyên

Truy vấn vùng chứa

Hỗ trợ trình duyệt

  • 105
  • 105
  • 110
  • 16

Nguồn

Trước @container, các phần tử của trang web chỉ có thể đáp ứng kích thước của toàn bộ khung nhìn. Điều này rất phù hợp đối với bố cục macro, nhưng đối với các bố cục vi mô, trong đó vùng chứa bên ngoài không phải là toàn bộ khung nhìn, 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 về kiểu hoặc kích thước vùng chứa gốc! Lưu ý 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ể có. Đâ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;
}

Các 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 bằng các phần tử sự kiện.

Bản minh hoạ của Una Kravets

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

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

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

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

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

Una là đáp án chính xác khi đánh giá tình huống là phản hồi mới. Có nhiều quyết định thú vị và có ý nghĩa về thiết kế được đưa ra khi sử dụng @container.

Tài nguyên

accent-color

Hỗ trợ trình duyệt

  • 93
  • 93
  • 92
  • 15,4

Nguồn

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ể sẽ phải sử dụng các thư viện hoặc giải pháp CSS phức tạp và trở nên khó quản lý theo thời gian. Mặc dù các tuỳ chọn này đã cung cấp cho bạn mọi tuỳ chọn và hy vọng là có khả năng hỗ trợ tiếp cận, nhưng việc lựa chọn sử dụng các thành phần tích hợp sẵn hoặc dùng các thành phần của riêng bạn sẽ trở nên tẻ nhạt khi tiếp tục chọn.

Sau accent-color, một dòng CSS sẽ mang màu thương hiệu vào các thành phần tích hợp. Ngoài sắc thái màu, 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 của 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ó màu sáng và tối nằm 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. Tại đây, tôi sẽ khám phá nhiều khía cạnh khác về thuộc tính CSS hữu ích này.

Tài nguyên

Màu cấp 4 và 5

Những thập kỷ qua, sRGB thống trị môi trường web, nhưng trong một thế giới kỹ thuật số ngày càng mở rộng với những 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, thì sRGB là chưa đủ. Hơn nữa, các trang động thích ứng với lựa chọn ưu tiên của người dùng và việc quản lý màu sắc ngày càng trở thành mối lo ngại ngày càng lớn đối với nhà thiết kế, hệ thống thiết kế và nhà bảo trì mã.

Mặc dù vậy, 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. – Không gian màu phù hợp với một ý định, chẳng hạn như tính đồng nhất về cảm nhận. – Không gian màu cho các độ dốc thay đổi đáng kể kết quả nội suy. – Các hàm màu giúp các em có thể kết hợp và tương phản cũng như chọn không gian để thực hiện công việc.

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

Sau tất cả các tính năng màu này, trình duyệt và CSS có thể thực hiện tất cả công việc một cách linh động và kịp thời. Thay vì gửi nhiều KB CSS và JavaScript cho người dùng để bật màu cho giao diện và hình ảnh dữ liệu, CSS có thể sắp xếp 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 bản dự phòng một cách linh hoạt.

@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()

Hỗ trợ trình duyệt

  • 101
  • 101
  • 96
  • 15

Nguồn

HWB là từ viết tắt của màu sắc, độ trắng và độ đen. Nó thể hiện như một cách thể hiện màu sắc thân thiện với con người, vì chỉ có một màu sắc và một lượng trắng hoặc đen để làm sáng hoặc làm tối. Các nghệ sĩ kết hợp màu sắc với trắng hoặc đen có thể thấy họ trân trọng 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 các màu từ hệ màu sRGB, giống như HSL và RGB. Xét về tính mới của năm 2022, tính năng này không mang đến cho bạn những màu sắc mới, nhưng có thể giúp những người hâm mộ cú pháp và mô hình tư duy thực hiện một số công việc dễ dàng hơn.

Tài nguyên

Hệ màu

Cách thể hiện màu sắc được thực hiện bằng hệ màu. Mỗi hệ màu cung cấp nhiều tính năng và yếu tố đánh đổi khi kết hợp với màu sắc. Một số có thể kết hợp tất cả các màu sáng lại với nhau; một số có thể xếp các màu đó trước dựa trên độ sáng.

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

color-mix()

Hỗ trợ trình duyệt

  • 111
  • 111
  • 113
  • 16,2

Nguồn

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

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) mà không cần chạy quy trình xây dựng hoặc bao gồm JavaScript. Ngoài ra, các đối tượng đó có thể chỉ định hệ màu cần kết hợp hoặc sử dụng hệ màu trộn mặc định của LCH.

Thông thường, màu thương hiệu được dùng làm màu nền và các biến thể được tạo 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. Dưới đây là giao diện của 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 kết hợp các màu đó trong một không gian màu khác, chẳng hạn như srgb, hãy thay đổi nó:

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

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

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

Hãy tận hưởng sự kết hợp màu sắc trong nhiều hệ màu khác nhau trong biểu định kiểu của bạn vào năm 2022!

Tài nguyên

color-contrast()

Hỗ trợ trình duyệt

  • x
  • x
  • x

Nguồn

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

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

Sau color-contrast(), tác giả biểu định kiểu có thể giảm tải hoàn toàn tác vụ 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à bạn còn có thể cung cấp cho trình duyệt danh sách màu phù hợp với hệ thống thiết kế và yêu cầu trình duyệt chọn màu đầu tiên chuyển tỷ lệ tương phản mong muốn.

Dưới đây là ảnh chụp màn hình bản minh hoạ tập hợp bảng màu HWB, trong đó màu văn bản sẽ được trình duyệt tự động chọn dựa trên màu của bảng 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.
Dùng thử bản minh hoạ

Cú pháp cơ bản có dạng như sau, trong đó màu xám được chuyển đến hàm và trình duyệt sẽ 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, từ đó, hàm sẽ chọn màu có độ tương phản cao nhất từ màu được chọn:

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

Cuối cùng, trong trường hợp không nê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 để truyền 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 */
);

Hàm này có thể được dùng cho nhiều mục đích khác ngoài màu văn bản, mặc dù tôi ước tính đó sẽ là trường hợp sử dụng chính. Hãy nghĩ xem việc cung cấp giao diện dễ truy cập và dễ đọc sẽ dễ dàng đến mức nào sau 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

Hỗ trợ trình duyệt

  • 111
  • 111
  • 113
  • 15

Nguồn

Trước cú pháp màu tương đối, để tính toán dựa trên màu sắc và điều chỉnh, bạn cần đặt riêng các kênh màu 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 để điều chỉnh màu sắc, vì màu sắc, độ rực màu hoặc độ sáng đều có thể được điều chỉnh theo cách đơn giản bằng calc().

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

Trong ví dụ về cú pháp sau, hệ thập lục phân được cung cấp và hai màu mới được tạo tương ứng. Màu đầu tiên --absolute-change tạo màu mới trong LCH từ màu cơ bản, sau đó tiếp tục thay thế độ sáng của màu cơ bản bằng 75%, duy trì sắc độ (c) và sắc độ (h). Màu thứ hai --relative-change tạo màu mới trong LCH dựa trên màu cơ bản, nhưng lần này làm giảm sắc độ (c) đi 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 cũng gần giống như việc kết hợp màu sắc, nhưng nó giống với sự thay đổi hơn là kết hợp. Bạn sẽ truyền màu từ một màu khác, nhận quyền truy cập vào 3 giá trị kênh như được đặt tên theo hàm màu được sử dụng, đồng thời có cơ hội điều chỉnh các kênh đó. Tóm lại, đây là cú pháp rất hay và mạnh mẽ cho màu sắc.

Trong bản minh hoạ sau đây, 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 thích hợp:

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

Hàm này cũng có thể được dùng để tạo bảng màu. Đây là bản minh hoạ, trong đó toàn bộ bảng màu được tạo dựa trên màu cơ bản đã cung cấp. Một tập hợp CSS này hỗ trợ tất cả các bảng màu, mỗi bảng màu chỉ cung cấp một cơ sở khác nhau. Ngoài ra, vì tôi đã sử dụng LCH nên hãy xem xét về mặt khái niệm, ngay cả các bảng màu là không có điểm nóng hay điểm chết, 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 gồm 15 bảng màu do CSS tạo động.
Dùng thử bản minh hoạ

Hy vọng bây giờ bạn có thể biết cách sử dụng hệ màu và các hàm màu khác nhau cho các mục đích khác nhau, dựa trên điểm mạnh và điểm yếu.

Tài nguyên

Hệ màu chuyển màu

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

4 màu dạng lưới, tất cả từ màu lục lam đến màu hồng đậm. LCH và LAB có sự sống động nhất quán hơn, trong đó sRGB có phần khử bão hoà một chút ở giữa.

Sau hệ màu chuyển màu, hãy cho trình duyệt biết cần sử dụng hệ màu nào để nội suy màu. Điều này cho phép các nhà phát triển và nhà thiết kế chọn độ dốc mà họ muốn. Hệ màu mặc định cũng thay đổi thành LCH thay vì sRGB.

Thao tác thêm cú pháp 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à hiệu ứng chuyển màu cơ bản và cần thiết từ đen sang trắng. Xem phạm vi kết quả trong từng hệ màu. Một số chuyển sang màu đen sẫm sớm hơn những người khác, một số chuyển sang màu trắng quá muộn.

11 không gian màu so sánh màu đen với màu trắng.

Trong ví dụ tiếp theo, màu đen được chuyển sang màu xanh dương vì đây là không gian gặp vấn đề đã biết đối với hiệu ứng chuyển màu. Hầu hết các hệ màu đều dần chuyển sang màu tím trong quá trình nội suy màu, hoặc như tôi vẫn thường nghĩ, khi màu sắc di chuyển bên trong không gian màu từ điểm A đến điểm B. Vì độ dốc sẽ đi theo 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 của đường dẫn.

11 không gian màu so sánh màu xanh dương với màu đen.

Để biết thêm thông tin chi tiết, 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

Hỗ trợ trình duyệt

  • 102
  • 102
  • 112
  • 15,5

Nguồn

Trước inert, bạn nên hướng người dùng tập trung vào những phần cần chú ý ngay trên trang hoặc ứng dụng. Chiến lược lấy tâm điểm có hướng dẫn này được gọi là bẫy tâm đ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 tâm điểm và nếu tiêu điểm rời khỏi không gian tương tác, thì nó 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 được hướng dẫn quay lại không gian tương tác để đảm bảo tác vụ đã hoàn tất trước khi chuyển sang không gian tương tác.

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

Ví dụ điển hình là hàm alert() của JavaScript:

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

Trong video trước, hãy lưu ý cách trang có thể truy cập 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 sẽ bị treo, 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 để đi. 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 giúp các nhà phát triển dễ dàng đạt được trải nghiệm lấy tiêu điểm theo hướng dẫn này.

Dưới đây là một mã mẫu nhỏ cho thấy cách hoạt động của mã 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ụ hay, nhưng inert cũng hữu ích cho những vấn đề như trải nghiệm người dùng trên trình đơn bên dạng trượt ra. Khi người dùng trượt trình đơn bên ra, không được để chuột hoặc bàn phím tương tác với trang phía sau nó; điều này gây khó khăn cho người dùng. Thay vào đó, khi trình đơn bên xuất hiện, hãy làm cho trang không tồn tại. Lúc này, người dùng phải đóng hoặc di chuyển trong trình đơn bên đó, đồng thời sẽ không bao giờ bị lạc ở vị trí khác trên trang khi đang mở trình đơn.

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ó độ chuyển màu, màu sắc và hiệu ứng tích hợp. Mặc dù vậy, các kích thước này có thể tăng lên rất lớn, và mặc dù chúng cho phép chỉnh sửa văn bản, nhưng phạm vi tuỳ chỉnh thì không lớn.

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

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

Sau đây là một ví dụ về biểu tượng cảm xúc trong bài đăng trên blog dành cho nhà phát triển Chrome. Có thể bạn đã nhận thấy rằng nếu bạn tăng cỡ chữ của biểu tượng cảm xúc, biểu tượng cảm xúc đó sẽ không sắc nét. Đây là hình ảnh chứ không phải là nghệ thuật vector. Thông thường, trong các ứng dụng khi sử dụng biểu tượng cảm xúc, biểu tượng cảm xúc sẽ được thay thế bằng 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 rất đẹp mắt:

Phông chữ biểu tượng có thể làm được một số điều đáng kinh ngạc với định dạng này, cung cấp bảng màu tuỳ chỉnh với bộ đôi tông màu và nhiều tính năng khác. Việc tải phông chữ COLRv1 cũng giống như mọi tệp phông chữ 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 CSS đặc biệt theo quy tắc để nhóm và đặt tên cho bộ tuỳ chọn tuỳ chỉnh thành một gói để tham khảo sau này. Hãy lưu ý cách bạn chỉ định tên tuỳ chỉnh giống như 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à bí danh cho các phần 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 bộ 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 Gia vị có từ DUNE.
Phông chữ Bungee Gia vị có màu sắc tuỳ chỉnh, lấy từ https://developer.chrome.com/blog/colrv1-fonts/

Với ngày càng có nhiều phông chữ và phông chữ màu biến đổi, kiểu chữ trên web đang trên đà phát triển rất lớn hướng đến khả năng tuỳ chỉnh và thể hiện phong phú các kiểu chữ 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, tất cả đều có khung nhìn khác nhau.

Trước khi có các biến thể khung nhìn mới, web đã cung cấp các đơn vị thực tế để hỗ trợ việc điều chỉnh khung nhìn. Có một thuộc tính 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 cách này hoạt động hiệu quả trong nhiều trường hợp, nhưng các trình duyệt dành cho thiết bị di động cũng có nhiều 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 sử dụng một phần không gian của khung nhìn. 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 để mang lại trải nghiệm khung nhìn lớn hơn cho người dùng. Tuy nhiên, khi thanh đó trượt ra, chiều cao khung nhìn đã thay đổi và mọi đơn vị vh sẽ dịch chuyển và đổi kích thước khi kích thước mục tiêu thay đổi. Trong những năm sau đó, đơn vị vh đặc biệt cần thiết để quyết định sử dụng hai kích thước khung nhìn nào, vì đơn vị này gây ra các vấn đề về bố cục hình ảnh gây khó chịu trên thiết bị di động. Chúng tôi đã 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 khi 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, kèm theo việc bổ sung các đơn vị logic tương đương với các đơn vị khung nhìn thực. Mục đích của ý tưởng này là cung cấp cho các nhà phát triển và nhà thiết kế khả năng chọn đơn vị họ muốn sử dụng cho tình huống cụ thể. Bạn có thể thực hiện một thay đổi nhỏ về bố cục gây khó chịu khi thanh trạng thái biến mất. Nhờ đó, bạn có thể sử dụng dvh (chiều cao khung nhìn động) mà không phải lo lắng.

Hình ảnh có 3 chiếc điện thoại minh hoạ DVH, LVH và SVH. Điện thoại ví dụ về DVH có hai đường dọc, một đường nằm giữa cuối thanh tìm kiếm và cuối khung nhìn và một đường nằm giữa trên thanh tìm kiếm (trong thanh trạng thái hệ thống) đến cuối khung nhìn; cho thấy cách DVH có thể thuộc một trong hai độ dài này. LVH hiển thị ở giữa với một đường nằm giữa phần cuối của thanh trạng thái thiết bị và nút của khung nhìn điện thoại. Cuối cùng là ví dụ về đơn vị SVH, hiển thị một dòng 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 tuỳ chọn đơn vị khung nhìn mới có sẵn cùng với các biến thể khung nhìn mới:

Đơn vị chiều cao 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 khung nhìn nhỏ nhất
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Đơn vị cạnh 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 điều này sẽ mang lại cho các nhà phát triển và nhà thiết kế sự linh hoạt cần thiết để có được thiết kế đáp ứng khung nhìn.

Tài nguyên

:has()

Hỗ trợ trình duyệt

  • 105
  • 105
  • 121
  • 15,4

Nguồn

Trước :has(), chủ đề của bộ chọn luôn nằm ở cuối. Ví dụ: tiêu đề 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 tiêu đề: ul > li:hover hoặc ul > li:not(.selected).

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

Dưới đây là ví dụ cơ bản về cú pháp, 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) {...}

Dưới đây là ví dụ trong đó phần tử <section> là tiêu đề, 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) {...}

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

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

Tất cả đều là ví dụ, trong đó :has() chỉ trông giống như một bộ chọn mẹ. Hãy 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 trên hình ảnh nếu hình có <figcaption>. Trong ví dụ sau, các hình có phụ đề hình vả sẽ được chọn, sau đó là hình ảnh trong ngữ cảnh đó. :has() được dùng và không thay đổi chủ thể, vì đối tượng chúng ta đang nhắm mục tiêu là hình ảnh chứ không phải hình:

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

Sự kết hợp dường như là vô tận. Kết hợp :has() với truy vấn 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 trạng thái lớp giả 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ợ sẽ trở nên đơn giản với @supports và hàm selector(). Các hàm này sẽ kiểm tra xem trình duyệt có hiểu cú pháp trước khi sử dụng hay không:

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

Tài nguyên

2022 trở đi

Vẫn còn nhiều việc sẽ khó thực hiện sau khi tất cả những tính năng tuyệt vời này sẽ 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 các vấn đề đó. Những giải pháp này đang trong giai đoạn thử nghiệm, mặc dù các giải pháp này có thể được chỉ định hoặc có sẵn phía sau các cờ trong trình duyệt.

Kết quả cuối cùng ở các phần tiếp theo sẽ là sự yên tâm khi các vấn đề được liệt kê có nhiều người ở nhiều công ty 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 trong năm 2023.

Thuộc tính tuỳ chỉnh được nhập không ổn định

Hỗ trợ trình duyệt

  • 85
  • 85
  • 16,4

Nguồn

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

Hãy xem xét trường hợp trong đó box-shadow sử dụng 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);

Tất cả đều hoạt động hiệu quả cho đến khi bất kỳ thuộc tính nào được thay đổi thành giá trị mà CSS không chấp nhận ở đó, chẳng hạn như --x: red. Toàn bộ bóng đổ sẽ bị hỏng nếu bất kỳ biến nào lồng nhau bị thiếu hoặc được đặt thành 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 đã nhập, không còn lỏng lẻo và linh hoạt nữa, nhưng 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 đó thử --x: red, red sẽ bị bỏ qua vì không phải là <length>. Điều này có nghĩa là bóng đổ sẽ tiếp tục hoạt động, mặc dù một giá trị không hợp lệ đã được cung cấp cho một trong các thuộc tính tuỳ chỉnh của nó. Thay vì không thành công, mã sẽ chuyển về initial-value0px.

Hoạt ảnh

Ngoài việc đảm bảo an toàn về kiểu, tiện ích này còn mở ra nhiều cửa cho ảnh động. Tính linh hoạt của cú pháp CSS khiến một số yếu tố không thể tạo ảnh động trở nên bất khả thi, chẳng hạn như độ dốc. @property hữu ích trong trường hợp này vì thuộc tính CSS đã nhập có thể thông báo cho trình duyệt về ý định của nhà phát triển bên trong nội dung nội suy quá phức tạp. Về cơ bản, nó giới hạn phạm vi khả năng xảy ra mà một 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ể thực hiện.

Hãy xem xét ví dụ minh hoạ này, trong đó hiệu ứ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 ra hiệu ứng lấy nét tiêu điểm. JavaScript đặt chuột x và y khi nhấn phím alt/chọn và 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 tiêu điểm 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 cho ảnh. Các hình ảnh này quá linh hoạt và quá phức tạp khiến trình duyệt "chỉ cần tìm ra" cách bạn muốn chúng tạo ảnh động. Tuy nhiên, với @property, bạn có thể nhập và tạo ảnh động riêng biệt cho một thuộc tính để trình duyệt có thể dễ dàng hiểu ý định.

Trò chơi điện tử sử dụng hiệu ứng lấy nét 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 lỗ kim. Dưới đây là cách sử dụng @property với bản minh hoạ để trình duyệt tạo ảnh độ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ạ

Trình duyệt nay có thể tạo ảnh động cho kích thước chuyển màu vì chúng tôi đã giảm diện tích bề mặt của nội dung 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 hỗ trợ nhỏ này có thể giúp ích rất nhiều.

Tài nguyên

Từng là min-width hoặc max-width

Trước các phạm vi 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 để so sánh các điều kiện. Thông báo có thể như sau:

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

Sau các phạm vi truy vấn nội dung nghe nhìn, cùng một truy vấn nội dung nghe nhìn sẽ có dạ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 phạm vi truy vấn nội dung nghe nhìn, cùng một truy vấn nội dung nghe nhìn sẽ có dạng như sau:

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

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

Tài nguyên

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

Trước @custom-media, các truy vấn nội dung nghe nhìn phải tự lặp lại nhiều lần hoặc dựa vào bộ tiền xử lý để tạo đầu ra phù 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ạo truy vấn đa phương tiện ở phương thức bí danh 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ứ rất quan trọng: tên này có thể phù hợp với mục đích với cú pháp, giúp nội dung chia sẻ dễ dàng hơn và dễ sử dụng hơn trong các 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);

Bây giờ, chúng đã được định nghĩa, tôi có thể sử dụng một trong các thành phần 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 bên trong thư viện thuộc tính tuỳ chỉnh CSS Open Props.

Tài nguyên

Bộ chọn lồng ghép rất tuyệt

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

Sau @nest, trạng thái lặp lại sẽ biến mất. Gần như mọi tính năng lồng ghép bằng bộ tiền xử lý sẽ được tích hợp sẵn 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 về việc lồng với tôi, ngoài việc không lặp lại article trong bộ chọn lồng, là ngữ cảnh định kiểu vẫn nằm trong một khối kiểu. Thay vì chuyển từ một bộ chọn và các 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 kiểu được nhóm lại với nhau, vì vậy, article dường như sở hữu các kiểu riêng.

Quyền sở hữu cũng có thể được coi là hoạt động tập trung hoá. Thay vì xem xét biểu định kiểu cho các kiểu liên quan, bạn có thể thấy tất cả các kiểu này được lồng với nhau trong một ngữ cảnh. Phương pháp này hoạt động trong mối quan hệ mẹ với mối quan hệ con, cũng như mối quan hệ con với mối quan hệ mẹ.

Hãy xem xét một thành phần con muốn tự điều chỉnh khi ở 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 ích cho việc sắp xếp, tập trung và sở hữu theo cách lành mạnh hơn. Các thành phần có thể nhóm và sở hữu kiểu riêng, thay vì trải rộng giữa các khối kiểu khác. Trong những ví dụ này, điều này có vẻ nhỏ nhưng có thể có tác động rất lớn, vì cả sự tiện lợi và tính dễ đọc.

Tài nguyên

Việc xác định phạm vi thực sự là một việc khó khăn

Hỗ trợ trình duyệt

  • 118
  • 118
  • x
  • 17,4

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 trên toàn cầu theo mặc định. Các tính năng này của CSS rất thuận tiện trong 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à tính chất của tầng có thể khiến các kiểu cảm thấy như bị rò rỉ.

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

Trong ví dụ sau, phạm vi quy ước đặt tên BEM có thể đảo ngược thành ý định thực tế. Bộ chọn BEM đang cố gắng phạm vi màu của phần tử header thành vùng chứa .card bằng các 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 phải dùng 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);
  }
}

Dưới đây là một ví dụ khác, ít dành riêng cho từng thành phần hơn và tìm hiểu thêm về tính chất 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, ở đây thứ tự là yếu tố quan trọng để xác định kiểu chiến thắng. Thông thường, điều này có nghĩa là kiểu giao diện tối xuất hiện sau giao diện sáng; điều này thiết lập ánh sáng làm kiểu mặc định và tối làm kiểu tuỳ chọn. Tránh tranh chấp theo thứ tự và 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. Không thể thực hiện việc này với bất kỳ quy ước đặt tên hoặc bộ tiền xử lý nào; đó là thao tác đặc biệt và chỉ CSS tích hợp trong trình duyệt mới có thể làm được. Trong ví dụ sau, kiểu img.content được áp dụng riêng khi thành phần con của .media-block là đồng cấp hoặc mẹ của .content:

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

  .content {
    padding: 1em;
  }
}

Tài nguyên

Không có cách CSS cho bố cục khối xây

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

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

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

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

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

Thật an tâm khi biết rằng đây là chiến lược bố cục còn thiếu trên rađa, ngoài ra bạn cò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

Hỗ trợ trình duyệt

  • x
  • x

Nguồn

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

Sau truy vấn phương tiện prefers-reduced-data, CSS có thể tham gia tính năng nâng cao trải nghiệm người dùng và đóng vai trò tiết kiệm dữ liệu.

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

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

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

Đố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, 40 yêu cầu và 700 kb tài nguyên được tải ban đầu. Khi người dùng cuộn phần lựa chọn nội dung nghe nhìn, thêm nhiều yêu cầu và tài nguyên sẽ được tải. Với CSS và truy vấn phương tiện dữ liệu giảm đi, 10 yêu cầu và 172 kb tài nguyên sẽ được tải. Đó là nửa megabyte tiết kiệm được và người dùng thậm chí không cuộn bất kỳ nội dung nghe nhìn nào, lúc đó 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 của một chương trình truyền hình, trong đó không có hình thu nhỏ và có nhiều tiêu đề xuất hiện.

Việc giảm trải nghiệm dữ liệu này có nhiều ưu điểm hơn so với việc chỉ tiết kiệm dữ liệu. Bạn có thể thấy nhiều tiêu đề hơn và không có ảnh bìa gây rối mắt để thu hút sự chú ý. Nhiều người dùng duyệt xem ở chế độ tiết kiệm dữ liệu vì họ trả phí cho mỗi megabyte dữ liệu. Thật tuyệt khi thấy CSS có thể trợ giúp bạn trong trường hợp này.

Tài nguyên

Các tính năng chụp nhanh khi cuộn bị hạn chế

Trước các đề xuất chụp nhanh thao tác 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à 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á theo tập lệnh, khiến hoạt động tương tác của người dùng cảm thấy hơi không tự nhiên và có thể khó hiểu.

API mới

snapChanging()

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

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

Ngay sau khi trình duyệt kết nối với một khung hiển thị con mới và thanh cuộn được dừng lại, sự kiện này sẽ kích hoạt. Đ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 đã chụp nhanh có thể cập nhật và phản ánh kết nối.

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

Thao tác cuộn không phải lúc nào cũng bắt đầu. Hãy cân nhắc các thành phần có thể vuốt, trong đó thao tác vuốt sang trái hoặc sang phải sẽ kích hoạt nhiều sự kiện, hoặc thanh tìm kiếm lúc tải trang ban đầu bị ẩn cho đến khi bạn cuộn lên trên cùng. Thuộc tính CSS này cho phép nhà phát triển chỉ định rằng trình cuộn phải 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 vùng chứa chụp nhanh của thao tác cuộn hiện đang được trình duyệt chụp.

.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 các đề xuất chụp nhanh như vậy, việc tạo thanh trượt, băng chuyền hoặc thư viện sẽ trở nên dễ dàng hơn nhiều vì trình duyệt hiện mang lại sự thuận tiện cho tác vụ, loại bỏ trình quan sát và mã sắp xếp cuộn để sử dụng API tích hợp sẵn.

Các tính năng CSS và JS này vẫn còn rất sớm, nhưng hãy chú ý đến các polyfill này có thể giúp bạn áp dụng và thử nghiệm các tính năng này trong thời gian sắp tới.

Tài nguyên

Đi xe đạp giữa các trạng thái đã biết

Trước toggle(), chỉ các trạng thái tích hợp sẵn trong trình duyệt mới có thể được tận dụng để định kiểu và tương tác. Ví dụ: đầu vào 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ể sử 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 bất kỳ phần tử nào để CSS thay đổi và sử dụng cho việc định kiểu. Chế độ này cho phép nhóm, đi xe đạp, bật/tắt chỉ đường và nhiều hoạt động khác.

Trong ví dụ sau, hiệu ứng tương tự của việc gạch ngang mục danh sách khi hoàn thành cũng đạt được 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 toggle() CSS có liên quan:

li {
  toggle-root: check self;
}

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

Nếu đã quen với máy trạng thái, bạn có thể thấy mức độ giao thoa với toggle(). Tính năng này cho phép nhà phát triển tạo nhiều trạng thái hơn vào CSS, hy vọng sẽ đưa ra những cách rõ ràng và có ngữ nghĩa hơn để điều phối hoạt động 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 phong phú hoặc thay đổi nhiều về cách hiển thị danh sách các tuỳ 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ái tạo nhiều chức năng của <select>, dẫn đến rất nhiều việc.

Sau <selectmenu>, nhà phát triển có thể cung cấp HTML đa dạng cho các phần tử tuỳ chọn và tạo kiểu cho chúng tuỳ ý, trong khi vẫn đáp ứng các yêu cầu về hỗ trợ tiếp cận và cung cấp HTML ngữ nghĩa.

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

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

CSS có thể nhắm mục tiêu 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;
}

Trình đơn chọn lọc với các màu nhấn màu đỏ.

Bạn có thể dùng thử phần tử <selectmenu> trên Chromium trong Canary khi cờ thử nghiệm web được bật. Hãy chú ý đến các phần tử trình đơn lựa chọn có thể tuỳ chỉnh trong năm 2023 trở đi.

Tài nguyên

Liên kết 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 để di chuyển các phần tử con trong phần tử mẹ.

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

Nếu bạn muốn tìm hiểu thêm, phần giải thích sẽ cung cấp một số ví dụ và mã mẫu hay nếu bạn muốn tìm hiểu thêm.

Tài nguyên