Tạo kiểu trang web thế hệ mới

Nắm bắt một số tính năng thú vị trong CSS hiện đại.

rất nhiều tính năng thú vị đang diễn ra trong CSS — và nhiều tính năng trong số đó đã được hỗ trợ trong các trình duyệt hiện nay! Buổi trò chuyện của chúng tôi tại CDS 2019 mà bạn có thể xem bên dưới đề cập đến một số tính năng mới và sắp ra mắt mà chúng tôi cho rằng nên chú ý.

Bài đăng này tập trung vào các tính năng bạn có thể sử dụng ngay hôm nay, vì vậy, hãy nhớ xem buổi trò chuyện để thảo luận sâu hơn về các tính năng sắp ra mắt như Houdini. Bạn cũng có thể tìm thấy bản minh hoạ cho tất cả các tính năng mà chúng ta thảo luận trên trang CSS@CDS.

Nội dung

Nút cuộn

Cuộn ảnh cho phép bạn xác định điểm chụp nhanh khi người dùng cuộn nội dung của bạn theo chiều dọc, chiều ngang hoặc cả hai. Nó cung cấp tính năng quán tính cuộn và giảm tốc tích hợp sẵn, cũng như hỗ trợ cảm ứng.

Mã mẫu này thiết lập tính năng cuộn theo chiều ngang trong phần tử <section> với các điểm chụp nhanh được căn chỉnh ở bên trái của phần tử con <picture>:

section {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}

section > picture {
  scroll-snap-align: start;
}

Cách hoạt động như sau:

  • Trên phần tử <section> mẹ,
    • overflow-x được thiết lập thành auto để cho phép cuộn theo chiều ngang.
    • overscroll-behavior-x được thiết lập thành contain để ngăn mọi phần tử mẹ cuộn khi người dùng đạt đến ranh giới của vùng cuộn của phần tử <section>. (Không thực sự cần thiết để chụp nhanh, nhưng thường là ý tưởng hay.)
    • scroll-snap-type được đặt thành x (để chụp nhanh theo chiều ngang) và mandatory để đảm bảo khung nhìn luôn bám theo điểm chụp gần nhất.
  • Trên các phần tử con <picture>, scroll-snap-align được đặt để bắt đầu, đặt các điểm chụp nhanh ở phía bên trái của mỗi hình ảnh (giả sử direction được đặt thành ltr).

Sau đây là bản minh hoạ trực tiếp:

Bạn cũng có thể xem bản minh hoạ về ảnh chụp nhanh khi cuộn theo chiều dọcảnh chụp nhanh khi cuộn.

:focus-within

:focus-within giải quyết vấn đề hỗ trợ tiếp cận thường xuyên: có nhiều trường hợp việc lấy tiêu điểm vào một thành phần con sẽ ảnh hưởng đến cách trình bày thành phần mẹ để người dùng công nghệ hỗ trợ có thể truy cập được vào giao diện người dùng.

Ví dụ: nếu bạn có trình đơn thả xuống có nhiều mục, trình đơn này sẽ vẫn hiển thị trong khi bất kỳ mục nào có tiêu điểm. Nếu không, trình đơn này sẽ biến mất đối với người dùng bàn phím.

:focus-within yêu cầu trình duyệt áp dụng một kiểu khi tiêu điểm nằm trên phần tử con bất kỳ của một phần tử cụ thể. Quay lại ví dụ về trình đơn, bằng cách đặt :focus-within trên phần tử trình đơn, bạn có thể đảm bảo thành phần này luôn hiển thị khi một mục trong trình đơn có tiêu điểm:

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

Hình minh hoạ cho thấy sự khác biệt về hành vi giữa tâm điểm và tiêu điểm bên trong.

Hãy thử duyệt qua các thành phần có thể làm tâm điểm trong bản minh hoạ bên dưới. Bạn sẽ nhận thấy các trình đơn vẫn hiển thị khi bạn đặt tiêu điểm vào các mục trong trình đơn:

Truy vấn phương tiện cấp 5

Truy vấn phương tiện mới mang đến cho chúng tôi những cách hiệu quả để điều chỉnh trải nghiệm người dùng trong ứng dụng dựa trên các lựa chọn ưu tiên của người dùng về thiết bị. Về cơ bản, trình duyệt hoạt động như một proxy cho các lựa chọn ưu tiên cấp hệ thống mà chúng ta có thể phản hồi trong CSS bằng nhóm prefers-* truy vấn nội dung nghe nhìn:

Sơ đồ cho thấy các truy vấn nội dung đa phương tiện diễn giải các lựa chọn ưu tiên của người dùng ở cấp hệ thống.

Sau đây là những cụm từ tìm kiếm mới mà chúng tôi cho rằng các nhà phát triển sẽ quan tâm nhất:

Các cụm từ tìm kiếm này giúp tăng khả năng tiếp cận. Trước đây, chúng tôi không có cách nào để biết, chẳng hạn như người dùng đã đặt hệ điều hành của họ ở chế độ tương phản cao. Nếu muốn cung cấp chế độ tương phản cao cho một ứng dụng web thể hiện đúng bản sắc thương hiệu của mình, bạn phải yêu cầu người dùng chọn chế độ đó từ giao diện người dùng trong ứng dụng. Giờ đây, bạn có thể phát hiện chế độ cài đặt độ tương phản cao trên hệ điều hành bằng cách sử dụng prefers-contrast.

Một ý nghĩa thú vị của các truy vấn phương tiện này là chúng tôi có thể thiết kế nhiều tổ hợp lựa chọn ưu tiên của người dùng ở cấp hệ thống để đáp ứng nhiều lựa chọn ưu tiên và nhu cầu hỗ trợ tiếp cận của người dùng. Nếu người dùng muốn có chế độ tối có độ tương phản cao trong môi trường ánh sáng yếu, bạn có thể thực hiện việc đó!

Điều quan trọng với Adam là "thích giảm chuyển động" không được thực hiện dưới dạng "không chuyển động". Người dùng nói rằng họ thích ít chuyển động hơn, chứ không phải là họ không muốn hoạt ảnh. Anh khẳng định rằng việc giảm chuyển động không phải là chuyển động. Dưới đây là ví dụ về cách sử dụng ảnh động chuyển động mờ khi người dùng muốn giảm chuyển động:

Thuộc tính logic

Thuộc tính logic giải quyết một vấn đề đã được thấy rõ khi ngày càng có nhiều nhà phát triển tham gia vào quá trình quốc tế hoá. Nhiều thuộc tính bố cục như marginpadding giả định ngôn ngữ đọc từ trên xuống dưới và từ trái sang phải.

Sơ đồ thể hiện các thuộc tính của bố cục CSS truyền thống.

Khi thiết kế các trang cho nhiều ngôn ngữ với nhiều chế độ viết, nhà phát triển phải điều chỉnh từng thuộc tính riêng lẻ trên nhiều thành phần. Việc này nhanh chóng trở thành cơn ác mộng về việc bảo trì.

Thuộc tính logic cho phép bạn duy trì tính toàn vẹn của bố cục trên các chế độ dịch và ghi. Chúng cập nhật linh hoạt dựa trên thứ tự ngữ nghĩa của nội dung thay vì cách sắp xếp không gian của nội dung. Với thuộc tính logic, mỗi phần tử có hai chiều:

  • Thứ nguyên khốivuông với luồng văn bản trong một dòng. (Trong tiếng Anh, block-size giống với height.)
  • Kích thước nội tuyến là kích thước song song với luồng văn bản trong một dòng. (Trong tiếng Anh, inline-size giống với width.)

Các tên phương diện này áp dụng cho tất cả thuộc tính bố cục logic. Vì vậy, ví dụ như trong tiếng Anh, block-start giống với topinline-end giống với right.

Sơ đồ cho thấy các thuộc tính bố cục logic CSS mới.

Với các thuộc tính logic, bạn có thể tự động cập nhật bố cục cho các ngôn ngữ khác chỉ bằng cách thay đổi thuộc tính writing-modedirection cho trang của mình, thay vì cập nhật nhiều thuộc tính bố cục trên từng phần tử riêng lẻ.

Bạn có thể xem cách hoạt động của thuộc tính logic trong bản minh hoạ bên dưới bằng cách đặt thuộc tính writing-mode trên phần tử <body> thành các giá trị khác nhau:

position: sticky

Một phần tử có position: sticky vẫn ở trong luồng khối cho đến khi bắt đầu rời khỏi màn hình. Lúc đó, phần tử này sẽ ngừng cuộn với phần còn lại của trang và bám vào vị trí do giá trị top của phần tử chỉ định. Không gian được phân bổ cho phần tử đó vẫn còn trong luồng và phần tử sẽ trở về trạng thái này khi người dùng cuộn lên lại.

Vị trí cố định cho phép bạn tạo nhiều hiệu ứng hữu ích mà trước đây yêu cầu JavaScript. Để thể hiện một số khả năng, chúng tôi đã tạo một số bản minh hoạ. Mỗi bản minh hoạ sử dụng phần lớn cùng một CSS và chỉ điều chỉnh đôi chút mã đánh dấu HTML để tạo từng hiệu ứng.

Ngăn xếp cố định

Trong bản minh hoạ này, tất cả các phần tử cố định đều có chung một vùng chứa. Tức là mỗi phần tử cố định sẽ trượt qua phần tử trước khi người dùng cuộn xuống. Các phần tử cố định có cùng một vị trí bị cố.

Trang trình bày cố định

Ở đây, các phần tử cố định là anh em họ. (tức là cha mẹ của chúng là anh chị em ruột.) Khi phần tử cố định tiếp cận ranh giới dưới của vùng chứa, phần tử đó sẽ di chuyển lên cùng vùng chứa, tạo ấn tượng rằng các phần tử cố định thấp hơn đang đẩy các phần tử cao hơn lên. Nói cách khác, các đường liên kết này có vẻ cạnh tranh để giành vị trí mắc lỗi.

Quảng cáo cố định (desperado)

Giống như Trang trình bày cố định, các thành phần cố định trong bản minh hoạ này là hai thành phần anh em họ. Tuy nhiên, các trình xử lý này đã được đặt trong các vùng chứa được đặt thành bố cục lưới gồm hai cột.

backdrop-filter

Thuộc tính backdrop-filter cho phép bạn áp dụng hiệu ứng đồ hoạ cho vùng phía sau của một phần tử thay vì cho chính phần tử đó. Điều này tạo ra rất nhiều hiệu ứng thú vị mà trước đây chỉ có thể đạt được bằng cách sử dụng các bản tấn công CSS và JavaScript phức tạp có thể thực hiện được với một dòng CSS.

Ví dụ: bản minh hoạ này sử dụng backdrop-filter để làm mờ kiểu hệ điều hành:

Chúng tôi đã có bài đăng tuyệt vời về backdrop-filter, vì vậy, hãy truy cập vào đó để biết thêm thông tin.

:is()

Mặc dù lớp giả :is() thực sự đã hoạt động được hơn 10 năm, nhưng vẫn chưa được sử dụng nhiều như chúng tôi nghĩ. Phương thức này lấy một danh sách các bộ chọn được phân tách bằng dấu phẩy làm đối số và so khớp với mọi bộ chọn trong danh sách đó. Nhờ sự linh hoạt này, công cụ này cực kỳ tiện dụng và có thể làm giảm đáng kể số lượng CSS mà bạn vận chuyển.

Dưới đây là một ví dụ nhanh:

button.focus,
button:focus {
  …
}

article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
  …
}

/* selects the same elements as the code above */
button:is(.focus, :focus) {
  …
}

article > :is(h1,h2,h3,h4,h5,h6) {
  …
}

gap

Bố cục lưới CSS đã có gap (trước đây là grid-gap) trong một khoảng thời gian. Bằng cách chỉ định khoảng cách bên trong của một phần tử vùng chứa thay vì khoảng cách xung quanh các phần tử con, gap giải quyết nhiều vấn đề thường gặp về bố cục. Ví dụ: với khoảng trống, bạn không cần lo lắng về lề của các thành phần con gây ra khoảng trắng không mong muốn xung quanh các cạnh của một thành phần chứa:

Hình minh hoạ cho thấy cách thuộc tính khoảng cách tránh khoảng cách ngoài ý muốn xung quanh các cạnh của phần tử vùng chứa.

Tin vui hơn nữa là gap sắp ra mắt trên flexbox, mang đến mọi đặc quyền về khoảng cách giống như những đặc quyền của lưới:

  • Có một nội dung khai báo dấu cách thay vì nhiều nội dung.
  • Bạn không cần thiết lập quy ước cho dự án của mình về các phần tử con nên có khoảng cách. Thay vào đó, phần tử chứa sẽ sở hữu khoảng cách.
  • Đoạn mã này sẽ dễ hiểu hơn so với các chiến lược cũ như con cú bị tự kích động.

Video sau đây trình bày các lợi ích của việc sử dụng một thuộc tính gap cho hai phần tử, một phần tử có bố cục lưới và một phần tử có bố cục linh hoạt:

Hiện tại, chỉ FireFox hỗ trợ gap trong bố cục linh hoạt, nhưng hãy xem bản minh hoạ này để xem cách thức hoạt động:

Dịch vụ so sánh giá (CSS) Houdini

Houdini là một tập hợp các API cấp thấp cho công cụ hiển thị của trình duyệt, cho phép bạn cho trình duyệt biết cách diễn giải CSS tuỳ chỉnh. Nói cách khác, nó cho phép bạn truy cập vào Mô hình đối tượng CSS, cho phép bạn mở rộng CSS qua JavaScript. Việc này có một số lợi ích:

  • Công cụ này giúp bạn có nhiều sức mạnh hơn để tạo các tính năng CSS tuỳ chỉnh.
  • Dễ dàng tách biệt các vấn đề về kết xuất khỏi logic ứng dụng.
  • Nó hiệu quả hơn so với CSS polyfilling mà chúng tôi hiện đang thực hiện với JavaScript do trình duyệt sẽ không còn phải phân tích cú pháp tập lệnh và thực hiện chu kỳ hiển thị thứ hai; mã Houdini được phân tích cú pháp trong chu kỳ hiển thị đầu tiên.

Hình minh hoạ cho thấy cách Houdini hoạt động so với các polyfills JavaScript truyền thống.

Houdini là tên chung cho một số API. Nếu bạn muốn biết thêm thông tin về họ và trạng thái hiện tại của họ, hãy xem Houdini đã sẵn sàng chưa? Trong buổi trò chuyện, chúng ta đã đề cập đến API Thuộc tính và Giá trị, API Paint và Worklet ảnh động vì những API này hiện được hỗ trợ nhiều nhất. Chúng tôi có thể dễ dàng dành riêng một bài đăng đầy đủ cho từng API thú vị này, nhưng bây giờ, hãy xem buổi nói chuyện của chúng tôi để có tổng quan và một số phần minh hoạ thú vị bắt đầu để cho bạn biết những gì bạn có thể làm với các API này.

Trình đơn mục bổ sung

Còn một vài chủ đề khác mà chúng tôi muốn thảo luận, nhưng không có thời gian đi sâu vào chi tiết, nên chúng tôi sẽ trình bày ngắn gọn.⚡ Nếu bạn chưa biết đến một vài tính năng trong số này, hãy nhớ xem phần cuối của buổi trò chuyện!

  • size: một thuộc tính cho phép bạn đặt chiều cao và chiều rộng cùng lúc
  • aspect-ratio: một thuộc tính thiết lập tỷ lệ khung hình cho các thành phần nội tại không có tỷ lệ khung hình
  • min(), max()clamp(): các hàm cho phép bạn thiết lập các điều kiện ràng buộc về số trên bất kỳ thuộc tính CSS nào, không chỉ chiều rộng và chiều cao
  • list-style-type là một thuộc tính hiện có, nhưng sẽ sớm hỗ trợ nhiều giá trị hơn, bao gồm cả biểu tượng cảm xúc và SVG
  • display: outer inner: Thuộc tính display sẽ sớm chấp nhận hai tham số, qua đó cho phép bạn chỉ định rõ bố cục bên ngoài và bên trong thay vì sử dụng các từ khoá kết hợp như inline-flex.
  • Các vùng CSS: cho phép bạn lấp đầy một vùng không phải hình chữ nhật cụ thể mà nội dung có thể di chuyển vào và ra khỏi
  • Mô-đun CSS: JavaScript sẽ có thể yêu cầu một mô-đun CSS và lấy lại đối tượng đa dạng thức giúp bạn dễ dàng thực hiện các thao tác trên đó