Các tính năng tạo kiểu web hiện tại và trong tương lai, như đã thấy tại Google IO 2022, cùng một số tính năng khác.
Năm 2022 được coi là một trong những năm thành công nhất của CSS, cả về tính năng và các bản phát hành tính năng hợp tác cho trình duyệt, với mục tiêu cộng tác là triển khai 14 tính năng!
Tổng quan
Bài đăng này là bản viết của bài nói tại Google IO 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à thông tin tổng quan ngắn gọn để kích thích sự quan tâm của bạn, cung cấp thông tin rộng rãi thay vì chuyên sâu. Nếu bạn hứng thú, hãy xem các đường liên kết đến tài nguyên ở cuối phần để biết thêm thông tin.
Mục lục
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
Một lý do chính khiến nhiều tính năng CSS được thiết lập để phát hành theo cách cộng tác là nhờ 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
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 của 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 đạt của trình duyệt cho 5 tính năng:
- Vị trí
sticky
- Định cỡ
aspect-ratio
- Bố cục
flex
- Bố cục
grid
- Vị trí và ảnh động
transform
Điểm kiểm thử tăng lên trên toàn bộ, cho thấy độ ổn định và độ tin cậy được nâng cấp. Xin chúc mừng các nhóm tại đây!
Interop 2022
Năm nay, các trình duyệt đã gặp nhau để thảo luận về các tính năng và ưu tiên mà họ dự định thực hiện, thống nhất những nỗ lực của họ. Họ dự định cung cấp các tính năng web sau đây cho nhà phát triển:
@layer
- Không gian màu và hàm
- Vùng chứa
<dialog>
- Khả năng tương thích của biểu mẫu
- Thao tác cuộn
- Lưới con
- Kiểu chữ
- Đơn vị khung nhìn
- 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 không thể chờ đợi để xem diễn ra.
Mới mẻ cho năm 2022
Không có gì đáng ngạc nhiên khi trạng thái của CSS 2022 bị ảnh hưởng đáng kể bởi công việc Interop 2022.
Lớp xếp chồng
Trước @layer
, thứ tự phát hiện được của biểu định kiểu được 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 được tải trước đó. Điều này dẫn đến việc quản lý cẩn thận các tệp kiểu mục nhập, trong đó các 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 mục nhập có thể xác định trước các lớp và thứ tự của các lớp đó trước khi bắt đầu. Sau đó, khi các kiểu tải, được tải hoặc được xác định, bạn có thể đặt các kiểu đó trong một lớp, cho phép duy trì mức độ quan trọng của kiểu ghi đè nhưng không cần phải quản lý quá trình tải một cách cẩn thận.
Video này cho thấy cách các lớp dạng thác nước đượ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ì thác nước khi cần.
Công cụ của Chrome cho nhà phát triển rất hữu ích để hình dung kiểu nào đến từ lớp nào:
Tài nguyên
- Quy cách CSS Cascade 5
- Nội dung giải thích về lớp xếp chồng
- Lớp xếp chồng trên MDN
- Una Kravets: Các lớp Cascade
- Ahmad Shadeed: Xin chào, Lớp CSS Cascade
Lưới con
Trước subgrid
, lưới bên trong lưới khác không thể tự căn chỉnh với các ô mẹ hoặc đường lưới của nó. Mỗi bố cục lưới đều riêng biệt. Nhiều nhà thiết kế đặt một lưới duy nhất trên toàn bộ thiết kế và liên tục căn chỉnh các mục trong lưới đó, điều này không thể thực hiện được trong CSS.
Sau subgrid
, một phần tử con của lưới có thể sử dụng cột hoặc hàng của phần tử mẹ làm cột hoặc hàng của chính nó, đồng thời căn chỉnh chính nó hoặc các phần tử con với các cột hoặc hàng đó!
Trong bản minh hoạ sau, phần tử body tạo 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 trái và cột phải gọi tên
các dòng của chúng
fullbleed
. Sau đó, mỗi phần tử trong phần nội dung, <nav>
và <main>
, sẽ sử dụng các dòng được đặt tên từ 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, các phần tử con của <nav>
hoặc <main>
có thể tự căn chỉnh hoặc tự định kích thước bằng cách sử dụng các cột và dòng fullbleed
và main
.
.main-content {
grid-column: main;
}
.fullbleed {
grid-column: fullbleed;
}
Công cụ dành cho nhà phát triển có thể giúp bạn xem các đường và lưới con (hiện chỉ có trên Firefox). Trong hình sau, lưới mẹ và các lưới phụ đã được phủ lên. Bố cục hiện tại giống với cách các nhà thiết kế nghĩ về bố cục.
Trong bảng điều khiển phần tử của devtools, bạn có thể xem 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.
Tài nguyên
Truy vấn vùng chứa
Trước @container
, các phần tử của 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ô, trong đó vùng chứa bên ngoài không phải là toàn bộ khung nhìn, 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ẹ!
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 phần tử sự kiện có thể truy vấn các cột Mon (Thứ Hai), Tues (Thứ Ba), Wed (Thứ Tư), Thurs (Thứ Năm) và Fri (Thứ Sáu) trong video sau.
Dưới đây là CSS để truy vấn vùng chứa calendar-day
về kích thước của vùng chứa đó, 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;
}
}
Sau đâ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 đó được kéo đến:
Una đã đánh giá chính xác tình huống này là tính năng thích ứng mới. Có rất nhiều quyết định thiết kế thú vị và có ý nghĩa cần đưa ra khi sử dụng @container
.
Tài nguyên
- Thông số kỹ thuật của Truy vấn vùng chứa
- Nội dung giải thích về Truy vấn vùng chứa
- Truy vấn vùng chứa trên MDN
- Trang web thích ứng mới trên web.dev
- Bản minh hoạ về Lịch của Una
- Bộ sưu tập truy vấn vùng chứa tuyệt vời
- Cách chúng tôi xây dựng Designcember trên web.dev
- Ahmad Shadeed: Xin chào các truy vấn vùng chứa CSS
accent-color
Trước accent-color
, khi muốn 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ù các thành phần này cung cấp cho bạn tất cả các tuỳ chọn và hy vọng bao gồm cả tính năng hỗ trợ tiếp cận, nhưng việc tiếp tục chọn sử dụng các thành phần tích hợp sẵn hoặc sử dụng thành phần của riêng bạn sẽ trở nên tẻ nhạt.
Sau accent-color
, một dòng CSS sẽ mang màu sắc thương hiệu đến các thành phần tích hợp. Ngoài sắc thái màu, trình duyệt còn chọn màu tương phản phù hợp cho các phần phụ của thành phần một cách thông minh và điều chỉnh theo 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;
}
Để tìm hiểu thêm về accent-color
, hãy xem bài đăng của tôi trên web.dev để 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
- quy cách accent-color
- màu nhấn trên MDN
- accent-color trên web.dev
- Bramus: Tint User-Interface Controls with CSS accent-color (Tô màu các thành phần điều khiển trên giao diện người dùng bằng CSS accent-color)
Cấp màu 4 và 5
Trong những thập kỷ qua, web đã bị sRGB thống trị, nhưng trong một thế giới kỹ thuật số đang mở rộng với màn hình độ phân giải cao và các 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, cần có những 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 ngày càng trở nên lo ngại đối với các nhà thiết kế, hệ thống thiết kế và người bảo 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 đáp ứng khả năng màu HD của màn hình. – Hệ 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 hiệu ứng 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 kết hợp và tạo độ tương phản, đồng thời chọn không gian để thực hiện công việc.
Trước khi có tất cả các tính năng màu sắc này, các hệ thống thiết kế cần 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 phù hợp, tất cả trong khi trình xử lý trước hoặc JavaScript thực hiện công việc nặng.
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 mọi công việc một cách linh động và đúng lúc. Thay vì gửi nhiều KB CSS và JavaScript cho người dùng để bật giao diện và màu sắc trực quan hoá dữ liệu, CSS có thể điều phối và tính toán. CSS cũng được trang bị hiệu quả hơn để kiểm tra khả năng hỗ trợ trước khi sử dụng hoặc xử lý 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()
HWB là viết tắt của màu sắc, độ trắng và độ đen. Đây là một cách dễ hiểu để diễn đạt màu sắc, vì nó chỉ là một sắc thái và một lượng màu trắng hoặc đen để làm sáng hoặc tối. Những nghệ sĩ kết hợp màu sắc với màu trắng hoặc đen có thể sẽ cảm thấy hài lòng với 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 trong không gian màu sRGB, giống như HSL và RGB. Về tính mới mẻ cho năm 2022, điều này không mang lại cho bạn 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 tinh thần thực hiện một số nhiệm 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 cung cấp nhiều tính năng và sự đánh đổi để xử lý màu. Một số người có thể gói tất cả màu sắc tươi sáng lại với nhau; một số người có thể sắp xếp các màu sắc đó trước dựa trên độ sáng của chúng.
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 hiển thị, chọn và pha trộn màu sắc. 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à không gian màu mặc định mới, LCH.
color-mix()
Trước color-mix()
, nhà phát triển và nhà thiết kế cần có trình xử lý trước như Sass để pha trộn màu sắc trước khi trình duyệt nhìn thấy.
Hầu hết các hàm pha màu cũng không cung cấp tuỳ chọn chỉ định không gian màu để pha màu, đôi khi dẫn đến kết quả khó hiểu.
Sau color-mix()
, 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 các quy trình xây dựng hoặc kể cả JavaScript. Ngoài ra, các lớp này có thể chỉ định hệ màu nào để kết hợp, hoặc sử dụng hệ màu kết hợp mặc định của LCH.
Thường thì màu thương hiệu được dùng làm màu cơ sở 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 không gian màu đó:
.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ạ giao diện bằng color-mix()
. Hãy thử thay đổi màu thương hiệu
và xem thông tin cập nhật về giao diện:
Hãy tận hưởng việc kết hợp màu sắc trong nhiều không gian màu trong các tệp kiểu của bạn trong năm 2022!
Tài nguyên
- Quy cách color-mix()
- color-mix() trên MDN
- Bản minh hoạ về giao diện
- Một bản minh hoạ khác về giao diện
- Fabio Giolito: Tạo giao diện màu bằng các tính năng CSS sắp ra mắt này
color-contrast()
Trước color-contrast()
, tác giả của bảng đị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 bảng màu, để cho người dùng biết hệ thống màu cần màu văn bản nào để tương phản đúng cách với bảng màu đó.
Sau color-contrast()
, tác giả biểu định kiểu có thể chuyển hoàn toàn tác vụ sang 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 danh sách các 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 đáp ứng tỷ lệ tương phản mà bạn mong muốn.
Dưới đây là ảnh chụp màn hình bản minh hoạ bộ bảng màu HWB, trong đó trình duyệt tự động chọn màu văn bản dựa trên màu của bảng màu:
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 sẽ xác định xem màu đen hay trắng có độ tương phản cao nhất hay không:
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 sắc, từ đó hàm sẽ chọn màu tương phản cao nhất trong danh sách:
color: color-contrast(gray vs indigo, rebeccapurple, hotpink);
Cuối cùng, trong trường hợp bạn không nên chọn màu 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 đáp ứng 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 */
);
Hàm này có thể 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ễ tiếp cận và dễ đọc 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
Trước khi sử dụng cú pháp màu tương đối, để tính toán màu sắc và thực hiện đ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. Giới hạn này cũng khiến HSL trở thành hàm màu chính để thao tác với màu sắc 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, bạn có thể phân tích, sửa đổi và trả về bất kỳ màu nào trong bất kỳ không gian nào 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ể thao tác trong bất kỳ không gian màu nào 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 đây, một mã màu cơ sở được cung cấp và hai màu mới được tạo tương ứng với mã màu đó. Màu đầu tiên --absolute-change
tạo một màu mới trong LCH từ màu cơ sở, sau đó tiến hành thay thế độ sáng của màu cơ sở bằng 75%
, duy trì sắc độ (c
) và sắc độ (h
). Màu thứ hai --relative-change
tạo một màu mới trong LCH từ màu cơ sở, nhưng lần này giảm sắc độ (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ư việc pha màu, nhưng giống với việc sửa đổi hơn là pha màu. Bạn có thể truyền một màu từ một màu khác, nhận quyền truy cập vào 3 giá trị kênh theo tên của hàm màu được sử dụng, đồng thời có thể điều chỉnh các kênh đó. Nhìn chung, đây là một cú pháp rất thú vị 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 và tối hơn của màu cơ bản, đồng thời sử dụng color-contrast()
để đảm bảo nhãn có độ tương phản phù hợp:
Hàm này cũng có thể dùng để tạo bảng màu. Dưới đây là một bản minh hoạ trong đó toàn bộ bảng màu được tạo từ một màu cơ sở đã cung cấp. Một bộ 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ỉ cung cấp một cơ sở khác nhau. Ngoài ra, vì tôi đã sử dụng LCH, hãy xem bảng màu trông như thế nào – không có điểm nóng hoặc điểm chết nào xuất hiện, nhờ không gian 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);
}
Hy vọng đến nay, bạn có thể hiểu cách hệ thống màu và các hàm màu khác nhau có thể được sử dụng cho những mục đích khác nhau, dựa trên điểm mạnh và điểm yếu của chúng.
Tài nguyên
- Quy cách cú pháp màu tương đối
- Tạo bảng màu bằng cú pháp màu tương đối
- Tạo biến thể màu bằng cú pháp màu tương đối
Hệ màu chuyển màu
Trước khi có không gian màu chuyển màu, sRGB là không gian 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.
Sau không gian màu chuyển màu, hãy cho trình duyệt biết không gian màu nào sẽ dùng để nội suy màu. Điều này giúp 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 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
);
Dưới đây là một 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 không gian màu. Một số loại chuyển sang màu đen sẫm sớm hơn những loại khác, một số chuyển sang màu trắng quá muộn.
Trong ví dụ tiếp theo, màu đen chuyển sang màu xanh dương vì đây là không gian có vấn đề đã biết đối với hiệu ứng 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 muốn gọi là khi màu sắc di chuyển bên trong không gian màu của chúng từ điểm A đến điểm B. Vì độ chuyển màu sẽ đi theo đường thẳng từ điểm A đến điểm B, nên hình dạng của không gian màu làm thay đổi đáng kể các điểm dừng mà đường dẫn thực hiện trên đường.
Để xem thêm các bài khám phá chuyên sâu, ví dụ và bình luận, hãy đọc chuỗi bài đăng này trên Twitter.
Tài nguyên
- Thông số kỹ thuật về nội suy màu chuyển tiếp
- Bản minh hoạ so sánh độ dốc trong không gian
- Sổ tay Observable so sánh độ dốc
inert
Trước inert
, bạn nên hướng người dùng tập trung vào những phần trên trang hoặc ứng dụng cần chú ý ngay lập tức. Chiến lược tiêu điểm có hướng dẫn này được gọi là tiêu điểm bẫy 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 thành tác vụ trước khi tiếp tục.
Sau inert
, bạn không cần phải chặn vì 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. Bạn sẽ không thể nhấp và thay đổi tiêu điểm khi các phần đó của tài liệu không hoạt động. Bạn cũng có thể coi đây là các nhân viên bảo vệ thay vì bẫy, trong đó inert
không quan tâm đến việc khiến bạn ở lại một nơi nào đó, mà là khiến các 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()
của JavaScript:
Hãy lưu ý trong video trước cách truy cập trang bằng chuột và bàn phím cho đến khi alert()
được gọi. Sau khi cửa sổ bật lên của hộp thoại cảnh báo xuất hiệ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. Sau khi người dùng tương tác và hoàn tất yêu cầu hàm cảnh báo, trang sẽ tương tác trở lại. inert
giú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ã mẫu 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ụ tuyệt vời, nhưng inert
cũng hữu ích cho những trải nghiệm người dùng như trình đơn bên trượt ra. Khi người dùng trượt ra trình đơn bên, việc cho phép chuột hoặc bàn phím tương tác với trang phía sau là một việc phức tạp. Thay vào đó, khi trình đơn bên xuất hiện, hãy làm cho trang không hoạt động. Giờ đây, người dùng phải đóng hoặc điều hướng trong trình đơn bên đó và sẽ không bao giờ bị lạc ở nơi khác trong trang có trình đơn đang mở.
Tài nguyên
- Quy cách không hoạt động
- Không hoạt động trên MDN
- Nhà phát triển Chrome: Giới thiệu về tính năng không hoạt động
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, các 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 phạm vi tuỳ chỉnh không có nhiều.
Sau phông chữ COLRv1, web có kích thước nhỏ hơn, có thể mở rộng vectơ, có thể đặt lại vị trí, sử dụng phông chữ chuyển màu và hỗ trợ chế độ kết hợp. Các phông chữ này 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.
Dưới đây là ví dụ trong bài đăng trên blog dành cho 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 tăng cỡ chữ trên biểu tượng cảm xúc thì biểu tượng cảm xúc sẽ không được sắc nét. Đó là hình ảnh chứ không phải hình minh hoạ vectơ. Thông thường, trong các ứng dụng, biểu tượng cảm xúc sẽ được hoán đổi bằng một thành phần có chất lượng cao hơn. Với phông chữ COLRv1, biểu tượng cảm xúc sẽ là vectơ và đẹp mắt:
Phông chữ biểu tượng có thể làm được một số điều tuyệt vời với định dạng này, cung cấp bảng màu hai tông màu tuỳ chỉnh và nhiều tính năng khác. Việc tải 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 CSS đặc biệt để nhóm và đặt tên cho một tập hợp các tuỳ chọn tuỳ chỉnh thành một gói để tham khảo sau. 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àm bí danh cho các 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;
}
Với ngày càng nhiều phông chữ biến thiên và phông chữ màu, kiểu chữ trên web đang 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
- Thông số kỹ thuật Colrv1 trên GitHub
- Nhà phát triển Chrome: Phông chữ Colrv1
- Video giải thích dành cho nhà phát triển về BlinkOn
Đơn vị khung nhìn
Trước các biến thể khung nhìn mới, web cung cấp các đơn vị thực để hỗ trợ việc điều chỉnh khung nhìn. Có một cho chiều cao, chiều rộng, kích thước nhỏ nhất (vmin) và bên lớn nhất (vmax). Các phương thức này hoạt động tốt cho nhiều việc, nhưng trình duyệt di động lại gây ra 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ẽ chiếm một số không gian 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 để cho phép người dùng có trải nghiệm khung nhìn lớn hơn. Tuy nhiên, khi thanh đó trượt ra, chiều cao của khung nhìn sẽ 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 của chúng thay đổi.
Trong những năm sau này, đơn vị vh
cần phải quyết định cụ thể sẽ sử dụng kích thước khung nhìn nào trong số hai kích thước, vì điều này đang gây ra các vấn đề về bố cục hình ảnh 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 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ị thực. Ý tưởng là mang lại 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 nhất định. Có thể bạn nên 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ờ đó dvh
(chiều cao khung nhìn linh động) có thể được sử dụng mà không phải lo lắng.
Dưới đây là danh sách đầy đủ tất cả các tuỳ chọn đơn vị khung nhìn mới được cung cấp cùng với các biến thể khung nhìn mới:
.new-height-viewport-units { height: 100vh; height: 100dvh; height: 100svh; height: 100lvh; block-size: 100vb; block-size: 100dvb; block-size: 100svb; block-size: 100lvb; }
.new-width-viewport-units { width: 100vw; width: 100dvw; width: 100svw; width: 100lvw; inline-size: 100vi; inline-size: 100dvi; inline-size: 100svi; inline-size: 100lvi; }
.new-min-viewport-units { --size: 100vmin; --size: 100dvmin; --size: 100svmin; --size: 100lvmin; }
.new-max-viewport-units { --size: 100vmax; --size: 100dvmax; --size: 100svmax; --size: 100lvmax; }
Hy vọng những tính năng này sẽ giúp nhà phát triển và nhà thiết kế có được sự linh hoạt cần thiết để đạt được thiết kế thích ứng với khung nhìn.
Tài nguyên
:has()
Trước :has()
, tiêu đề của bộ chọn luôn ở cuối. Ví dụ: chủ đề của bộ chọn này là một mục 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 chủ thể cao hơn trong cây phần tử có thể vẫn là chủ thể đó trong khi đưa ra truy vấn về phần tử con: ul:has(> li)
. Dễ dàng hiểu cách :has()
có tên thường gọi là "bộ chọn mẹ", vì chủ đề của bộ chọn giờ đây là mẹ trong trường hợp này.
Dưới đâ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) {...}
Dưới đây là ví dụ về trường hợp phần tử <section>
là chủ đề, 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 sau khi các trường hợp sử dụng thực tế hơn trở nên rõ ràng. Ví dụ: hiện tại, bạn không thể chọn thẻ <a>
khi các thẻ này gói hình ảnh, khiến bạn khó dạy thẻ neo cách thay đổi kiểu của thẻ đó trong trường hợp sử dụng đó. Tuy nhiên, bạn có thể thực hiện việc này với :has()
:
a:has(> img) {...}
Đây đều là những ví dụ mà :has()
chỉ trông giống như một bộ chọn mẹ.
Hãy xem xét trường hợp sử dụng hình ảnh bên trong 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ó chú thích hình ảnh được chọn, sau đó là hình ảnh trong ngữ cảnh đó. :has()
được sử dụng và không thay đổi đối tượng, vì đối tượng mà chúng ta đang nhắm đến là hình ảnh chứ không phải hình dạng:
figure:has(figcaption) img {...}
Có vẻ như có vô số cách kết hợp. 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.
Bạn có thể dễ dàng kiểm tra khả năng hỗ trợ bằng @supports
và hàm selector()
. Hàm này sẽ kiểm tra 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
Từ năm 2022 trở đi
Vẫn còn rất nhiều điều 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 chúng. Các giải pháp này mang tính 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ẽ giúp bạn yên tâm rằng các 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 các 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ó kiểu lỏng
Các thuộc tính tuỳ chỉnh của CSS rất tuyệt vời. Các biến này cho phép lưu trữ mọi thứ bên trong một biến được đặt tên, sau đó có thể mở rộng, tính toán, chia sẻ và làm nhiều việc khác. Trên thực tế, chúng rất linh hoạt, do đó sẽ tốt hơn nếu có một số thành phần kém linh hoạt hơn.
Hãy xem xét trường hợp box-shadow
sử dụng các thuộc tính tuỳ chỉnh cho giá trị của nó:
box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);
Tất cả đề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ộ bóng sẽ bị gián đoạn nếu thiếu bất kỳ biến lồng nào hoặc bị đặt thành loại giá trị không hợp lệ.
Đây là lúc @property
xuất hiện: --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, nhưng an toàn với một số ranh giới xác định:
@property --x {
syntax: '<length>';
initial-value: 0px;
inherits: false;
}
Bây giờ, khi box-shadow
sử dụng var(--x)
và sau đó là --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, ngay cả khi bạn đã cung cấp một giá trị không hợp lệ cho một trong các thuộc tính tuỳ chỉnh của bóng đổ.
Thay vì không thành công, hàm này sẽ khôi phục về initial-value
là 0px
.
Hoạt ảnh
Ngoài tính năng an toàn về kiểu, tính năng này cũng mở ra nhiều cơ hội cho ảnh động. Sự linh hoạt của cú pháp CSS khiến việc tạo ảnh động không thể thực hiện được, chẳng hạn như độ dốc. @property
sẽ giúp ích ở đâ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 quá trình nội suy quá phức tạp. Về cơ bản, tính năng 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 không thể.
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 hiệu ứng tiêu điểm ánh sáng. JavaScript đặt x và y của chuột khi nhấn phím alt/opt, 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 của đèn sân khấu tại vị trí của chuột:
.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, không thể tạo ảnh động cho màu chuyển tiếp. Các lớp này quá linh hoạt và quá phức tạp đến mức trình duyệt không thể "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 được ý định.
Các 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ừ vòng tròn lớn đến 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;
}
Trình duyệt hiện có thể tạo ảnh động cho kích thước độ dốc vì chúng tôi đã giảm diện tích bề mặt của 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 thế, nhưng những tính năng nhỏ này có thể giúp ích rất nhiều.
Tài nguyên
- @property specification
- @property trên MDN
- @property trên web.dev
- Minh hoạ tiêu điểm thu phóng
- Mẹo CSS: Khám phá @property và các tính năng tạo ảnh động của thuộc tính này
Đã ở 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-width
và max-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ể có dạng như sau:
@media (width >= 320px) {
…
}
Truy vấn nội dung nghe nhìn CSS sử dụng cả min-width
và max-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ể 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ẽ trông dễ đọc hơn nhiều so với nền tảng còn lại. Nhờ những thông số kỹ thuật được bổ sung, các nhà phát triển sẽ có thể chọn công cụ họ thích hay thậm chí sử dụng thay thế cho nhau.
Tài nguyên
- Quy cách về cú pháp phạm vi truy vấn nội dung đa phương tiện
- Cú pháp phạm vi truy vấn nội dung nghe nhìn trên MDN
- Trình bổ trợ PostCSS cú pháp phạm vi truy vấn nội dung đa phương tiện
Không có biến truy vấn nội dung nghe nhìn
Trước @custom-media
, các truy vấn đa phương tiệ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 gán biệt hiệu cho truy vấn nội dung nghe nhìn và tham chiếu các truy vấn đó, giống như một thuộc tính tuỳ chỉnh.
Việc đặt tên rất quan trọng: nó có thể điều chỉnh mục đích với cú pháp, giúp mọi người dễ dàng chia sẻ và sử dụng trong nhóm. Dưới đây là một số truy vấn đa phương tiệ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, khi đã xác định xong, tôi có thể sử dụng một trong các giá trị đó như sau:
@media (--OSdark) {
:root {
…
}
}
Tìm danh sách đầy đủ các truy vấn nội dung đa phương tiệ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
- Thông số kỹ thuật của truy vấn nội dung đa phương tiện tuỳ chỉnh
- Trình bổ trợ PostCSS cho các truy vấn đa phương tiện tuỳ chỉnh
Bộ chọn lồng nhau rất đẹp
Trước @nest
, có rất nhiều nội dung lặp lại trong các tệp định kiểu. Điều này trở nên đặc biệt khó sử dụng khi bộ chọn dài và mỗi bộ chọn 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 trình xử lý trước.
Sau @nest
, tần suất lặp lại sẽ biến mất. Hầu hết tính năng của tính năng lồng ghép hỗ trợ trình xử lý trước 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 đối với tôi về việc lồng nhau, ngoài việc không lặp lại article
trong bộ chọn lồng nhau, là ngữ cảnh tạo kiểu vẫn nằm trong một khối kiểu.
Thay vì thoát 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 sở hữu các đường liên kết bên trong đó. Mối quan hệ và ý định về kiểu được đóng gói với nhau, vì vậy article
sẽ xuất hiện như thể sở hữu các kiểu riêng.
Quyền sở hữu cũng có thể được coi là tập trung. Thay vì tìm kiếm các kiểu liên quan trong một tệp kiểu, bạn có thể tìm thấy tất cả các kiểu đó lồng ghép với nhau trong một ngữ cảnh. Phương thức này hoạt động với mối quan hệ mẹ con, nhưng cũng hoạt động với mối quan hệ con với mẹ.
Hãy xem xét một thành phần con muốn tự điều chỉnh 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ổng thể việc sắp xếp, tập trung và sở hữu kiểu tốt hơn. Các thành phần có thể nhóm và sở hữu kiểu riêng, thay vì phân phát giữa các khối kiểu khác. Trong các ví dụ này, điều này có vẻ như không đáng kể, nhưng có thể có tác động rất lớn, cả về sự tiện lợi và khả năng đọc.
Tài nguyên
Rất khó để xác định phạm vi của kiểu
Trước @scope
, nhiều chiến lược đã tồn tại vì các kiểu trong CSS phân 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 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 toàn cục và bản chất của thác nước có thể khiến các kiểu bị rò rỉ.
Sau @scope
, các kiểu không chỉ có thể được đặt trong một ngữ cảnh, chẳng hạn như một lớp, mà còn có thể chỉ rõ vị trí kết thúc của các kiểu và không tiếp tục xếp chồng hoặc kế thừa.
Trong ví dụ sau, bạn có thể đảo ngược phạm vi quy ước đặt tên BEM 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 phải tuân theo 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à nhiều hơn về bản chất phạm vi toàn cục của CSS. Giao diện tối và sáng phải cùng tồn tại bên trong một tệp kiểu, trong đó thứ tự đóng 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; việc này sẽ thiết lập giao diện sáng làm giao diện mặc định và giao diện tối làm giao diện không bắt buộc. Tránh việc sắp xếp và phạm vi xung đột với @scope
:
@scope (.light-theme) {
a { color: purple; }
}
@scope (.dark-theme) {
a { color: plum; }
}
Để hoàn tất câu chuyện tại đâ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 với bất kỳ quy ước đặt tên hoặc bộ tiền xử lý nào. Đây là tính năng đặc biệt và chỉ tính năng CSS tích hợp sẵn trong trình duyệt mới có thể làm được. Trong ví dụ sau, kiểu img
và .content
được áp dụng riêng khi phần tử 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 nào dùng CSS cho bố cục kiểu xếp kề
Trước khi CSS có kiểu xếp kề bằng lưới, JavaScript là cách tốt nhất để tạo bố cục xếp kề, 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 xây dựng CSS có lưới, bạn không cần thư viện JavaScript và thứ tự nội dung sẽ chính xác.
Bản minh hoạ trước được thực hiện bằng CSS sau:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
Bạn có thể yên tâm vì chúng tôi đang xem xét chiến lược bố cục bị thiếu này, ngoài ra, bạn có thể thử ngay trong Firefox.
Tài nguyên
- Thông số kỹ thuật của bố cục kiểu xếp kề
- Bố cục kiểu xếp kề trên MDN
- Smashing Magazine: Bố cục kiểu xếp kề CSS gốc bằng Lưới CSS
CSS không thể giúp người dùng giảm dữ liệu
Trước truy vấn nội dung đa 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 nội dung đa phương tiện prefers-reduced-data
, CSS có thể tham gia vào việc cải thiện 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ước đó được sử 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ó thể rất lớn. Tuỳ thuộc vào độ lớn của khung nhìn truy cập, lượng tiết kiệm càng lớ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ả 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à không bao giờ có yêu cầu mạng nào cho hình ảnh.
Trong quá trình thử nghiệm, trên khung nhìn có kích thước trung bình, ban đầu, 40 yêu cầu và 700 KB tài nguyên đã được tải. Khi người dùng cuộn lựa chọn nội dung nghe nhìn, nhiều yêu cầu và tài nguyên hơn sẽ được tải. Với CSS và truy vấn nội dung đa phương tiện dữ liệu giảm, 10 yêu cầu và 172 kb tài nguyên được tải. Đó là 500 KB tiết kiệm được và người dùng thậm chí chưa cuộn bất kỳ nội dung đa phương tiện nào, tại thời điểm này không có yêu cầu nào khác được thực hiện.
Việc giảm mức sử dụng dữ liệu này có nhiều lợi thế hơn so với việc chỉ tiết kiệm dữ liệu. Người dùng có thể xem nhiều đầu sách hơn và không có hình ảnh bìa gây mất tập trung. 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 ở đây.
Tài nguyên
- Thông số kỹ thuật về tính năng ưu tiên giảm dữ liệu
- prefers-reduced-data trên MDN
- prefers-reduced-data trong Thử thách giao diện người dùng
- Smashing Magazine: Cải thiện Core Web Vitals, Nghiên cứu điển hình của A Smashing Magazine
Các tính năng cuộn nhanh quá hạn chế
Trước khi có các đề xuất 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ể gây khó chịu.
API mới
snapChanging()
Ngay khi trình duyệt phát hành một phần tử con của ảnh chụp nhanh, 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 thiếu thành phần con chụp nhanh và trạng thái chụp nhanh không xác định của thanh cuộn, vì thanh cuộn hiện đang được sử dụng và sẽ chuyển đến một vị trí mới.
document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()
Ngay khi trình duyệt đã chụp nhanh một thành phần con mới và thanh cuộn được đặt 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 được 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
Không phải lúc nào thao tác cuộn cũng bắt đầu 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 các sự kiện khác nhau, hoặc thanh tìm kiếm trên trang tải ban đầu sẽ 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 thanh 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 chụp nhanh cuộn hiện được trình duyệt chụp 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 các đề xuất chụp nhanh cuộn này, việc tạo thanh trượt, băng chuyền hoặc thư viện sẽ dễ dàng hơn nhiều vì trình duyệt hiện mang lại sự tiện lợi cho tác vụ, loại bỏ trình quan sát và mã sắp xếp cuộn mà ưu tiên sử dụng API tích hợp.
Các tính năng CSS và JS này vẫn còn ở giai đoạn rất sớm, nhưng hãy chú ý đến các polyfill có thể giúp bạn sớm áp dụng và thử nghiệm các tính năng này.
Tài nguyên
- Thông số kỹ thuật của bản nháp Cuộn Snap 2
- Video giải thích về tính năng Cuộn nhanh 2
- Chụp bản minh hoạ
Luân phiên 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 đã tích hợp trong trình duyệt để tạo kiểu và tương tác. Ví dụ: dữ liệu đầ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 tạo kiểu. Chế độ này cho phép nhóm, luân phiên, bật/tắt có hướng và nhiều tính năng khác.
Trong ví dụ sau, bạn có thể đạt được hiệu ứng tương tự của một mục danh sách bị gạch ngang khi hoàn tất nhưng không có 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 thuộc với máy trạng thái, bạn có thể nhận thấy mức độ tương đồng giữa toggle()
. Tính năng này sẽ cho phép nhà phát triển xây dựng nhiều trạng thái hơn vào CSS, hy vọng sẽ mang lại cách điều phối tương tác và trạng thái rõ ràng và ngữ nghĩa hơn.
Tài nguyên
Tuỳ chỉnh một số phần tử
Trước <selectmenu>
, CSS không thể tuỳ chỉnh các phần tử <option>
với HTML phong phú hoặc thay đổi nhiều về cách hiển thị danh sách 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ái tạo phần lớn chức năng của <select>
, nhưng rốt cuộc thì 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ử tuỳ chọn và định 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ề 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 <selectmenu>
, một trình đơn chọn mới đượ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 đế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;
}
Bạn có thể dùng thử phần tử <selectmenu>
trên Chromium trong Canary khi cờ thử nghiệm web đã bật. Hãy chú ý đến các phần tử trình đơn 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ới 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ể định vị các phần tử cho các phần tử khác, bất kể các phần tử đó có phải là phần tử con hay không. API này cũng cho phép nhà phát triển chỉ định cạnh nào để đặt vào vị trí và các đặc điểm khác để tạo mối quan hệ vị trí giữa các phần tử.
Phần giải thích có một số ví dụ và mã mẫu tuyệt vời, nếu bạn muốn tìm hiểu thêm.