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

Tìm hiểu thông tin mới nhất về một số tính năng thú vị trong CSS hiện đại.

Có rất nhiều điều thú vị đang diễn ra trong CSS ngay lúc này và nhiều định dạng trong số này đã được hỗ trợ trong các trình duyệt hiện nay! Bài nói 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 cần được bạn chú ý.

Bài đăng này tập trung vào các tính năng mà bạn có thể sử dụng hiện nay, hãy nhớ xem bài nói 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

Di chuyển nút

Scroll Snap cho phép bạn xác định các đ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. Chế độ này cung cấp quán tính và giảm tốc cuộn tích hợp sẵn, đồng thời hỗ trợ chức năng cảm ứng.

Mã mẫu này thiết lập tính năng cuộn 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ử <picture> con:

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 đặt thành auto để cho phép cuộn theo chiều ngang.
    • overscroll-behavior-x được đặt thành contain để ngăn phần tử mẹ cuộn khi người dùng đến ranh giới vùng cuộn của phần tử <section>. (Việc này không thực sự cần thiết để chụp nhanh, nhưng thường là một ý 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 chụp với điểm chụp nhanh gần nhất.
  • Trên các phần tử con <picture>, scroll-snap-align được thiết lập để bắt đầu. Thao tác này sẽ thiết lập các điểm chụp nhanh ở bên trái của mỗi ả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ạ cho ảnh chụp nhanh cuộn dọcảnh chụp nhanh cuộn ma trận.

:focus-within

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

Ví dụ: nếu bạn có một trình đơn thả xuống có nhiều mục, thì trình đơn đó sẽ vẫn hiển thị khi bất kỳ mục nào được lấy tiêu điểm. Nếu không, trình đơn 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 bất kỳ phần tử con nào của một phần tử đã chỉ định. Quay lại ví dụ về trình đơn, bằng cách đặt :focus-within trên thành phần trình đơn, bạn có thể đảm bảo thành phần này luôn xuất hiện 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 tiêu điểm và tiêu điểm bên trong.

Hãy thử thay đổi thẻ cho các phần tử 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 xuất hiện khi bạn đặt tiêu điểm vào các mục trong trình đơn:

Truy vấn nội dung đa phương tiện cấp 5

Các truy vấn mới về nội dung nghe nhìn mang đến cho chúng ta những cách thức hiệu quả để điều chỉnh trải nghiệm người dùng trong ứng dụng dựa trên 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 đóng vai trò là 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 cách sử dụng nhóm prefers-* truy vấn nội dung đa phương tiện:

Sơ đồ hiển thị các truy vấn nội dung nghe nhìn diễn giải 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:

Những cụm từ tìm kiếm này mang lại lợi ích lớn về khả năng tiếp cận. Ví dụ: trước đây, chúng ta không có cách nào để biết được rằng một 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 thương hiệu của bạn, bạn phải yêu cầu người dùng chọn chế độ này 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 của 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 truyền thông 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 của người dùng và nhu cầu hỗ trợ tiếp cận. Nếu người dùng muốn sử dụng chế độ tối có độ tương phản cao trong môi trường thiếu sáng, thì bạn có thể làm điều đó!

Adam rất quan tâm đến việc "muốn giảm chuyển động" không được triển khai dưới dạng "không có chuyển động". Người dùng cho biết họ thích chuyển động ít hơn, không phải là họ không muốn bất kỳ hoạt ảnh nào. Anh khẳng định chuyển động giảm không phải là không có chuyển động. Dưới đây là một ví dụ về việc sử dụng ảnh động chuyển đổi mờ dần 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 đề ngày càng trở nên phổ biến khi ngày càng có nhiều nhà phát triển xử lý việc quốc tế hoá. Nhiều thuộc tính bố cục như marginpadding giả định một ngôn ngữ được đọc từ trên xuống dưới và từ trái sang phải.

Sơ đồ cho thấy các thuộc tính bố cục CSS truyền thống.

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

Các 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à viết. Chúng cập nhật động 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 các thuộc tính logic, mỗi phần tử có hai phương diện:

  • Kích thước khối vuông với luồng văn bản trong một đường. (Trong tiếng Anh, block-size giống với height.)
  • Phương diện cùng dòng là phương diện song song với luồng văn bản trên 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ả các thuộc tính bố cục logic. Ví dụ: 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 mới của CSS.

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 hàng chục 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 các thuộc tính logic qua 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 thoát khỏi màn hình, điểm nào nó ngừng cuộn cùng với phần còn lại của trang và gắn vào vị trí được chỉ định bởi giá trị top của phần tử. Không gian được phân bổ cho phần tử đó vẫn ở trong luồng, và phần tử đó sẽ quay trở lại khi người dùng cuộn lên trở 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 phải có JavaScript. Để cho thấy một số khả năng, chúng tôi đã tạo một số ví dụ minh hoạ. Mỗi bản minh hoạ sử dụng phần lớn CSS giống nhau và chỉ điều chỉnh một 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ó cùng một vùng chứa. Tức là mỗi thành phần 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 vị trí cố định.

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

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

Thử thách cố định

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à anh em họ hàng. Tuy nhiên, chúng được đặt trong các vùng chứa và có bố cục lưới gồm 2 cột.

backdrop-filter

Thuộc tính backdrop-filter cho phép bạn áp dụng hiệu ứng đồ hoạ cho khu vực phía sau một phần tử thay vì cho chính phần tử đó. Công cụ này tạo ra rất nhiều hiệu ứng thú vị mà trước đây chỉ đạt được bằng cách 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ó một bài đăng hay về backdrop-filter, hãy truy cập vào đó để biết thêm thông tin.

:is()

Mặc dù lớp giả lập :is() đã hơn 10 năm, nhưng nó không được sử dụng nhiều như chúng ta mong đợi. Phương thức này sẽ lấy một danh sách bộ chọn được phân tách bằng dấu phẩy làm đối số và khớp với bất kỳ bộ chọn nào trong danh sách đó. Tính linh hoạt đó giúp việc này vô cùng tiện lợi 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) được một thời gian. Bằng cách chỉ định khoảng cách bên trong của một phần tử chứa thay vì khoảng cách xung quanh các phần tử con, gap có thể 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 phải lo lắng về việc lề trên các phần tử con gây ra khoảng trắng không mong muốn xung quanh các cạnh của phần tử chứa:

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

Tin vui hơn nữa là: gap sắp có mặt trong flexbox và mang đến tất cả các đặc quyền về khoảng cách tương tự như lưới có:

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

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 2 phần tử, mộ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 ở bố cục linh hoạt, nhưng hãy thử bản minh hoạ này để xem cách hoạt động của trình mô phỏng này:

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, công cụ này cấp cho bạn quyền truy cập vào Mô hình đối tượng CSS, cho phép bạn mở rộng CSS thông qua JavaScript. Việc này có một số lợi ích:

  • Điều này giúp bạn có nhiều quyền lực hơn để tạo các tính năng CSS tuỳ chỉnh.
  • Bạn có thể dễ dàng tách biệt các mối lo ngại về kết xuất khỏi logic ứng dụng.
  • Cách này hiệu quả hơn so với chèn polyfill CSS mà chúng tôi hiện đang thực hiện với JavaScript vì trình duyệt sẽ không còn phải phân tích cú pháp các 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ỳ kết xuất đầu tiên.

Hình minh hoạ cho thấy cách hoạt động của Houdini so với các polyfill 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 trang Is Houdini đã sẵn sàng chưa? Trong buổi nói chuyện, chúng ta đã đề cập đến API Thuộc tính và Giá trị, API Paint và Worklet ảnh động vì chúng hiện được hỗ trợ nhiều nhất. Chúng ta có thể dễ dàng dành riêng một bài đăng đầy đủ về từng API thú vị này. Tuy nhiên, bây giờ, hãy xem bài nói chuyện của chúng tôi để biết tổng quan và một số bản minh hoạ thú vị giúp bạn hiểu được những việc bạn có thể làm với những API này.

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

Có một vài điều nữa mà chúng tôi muốn thảo luận nhưng không có thời gian để đi sâu, vì vậy chúng tôi đã thảo luận nhanh về chúng.⚡ Nếu bạn chưa biết về một số tính năng 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 một lúc
  • aspect-ratio: một thuộc tính thiết lập tỷ lệ khung hình cho các phần tử không có tỷ lệ về bản chất
  • min(), max()clamp(): các hàm cho phép bạn thiết lập các quy tắc ràng buộc về số đối với mọi thuộc tính CSS, không chỉ chiều rộng và chiều cao
  • list-style-type 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 2 tham số, cho phép bạn chỉ định rõ ràng bố cục bên ngoài và bên trong thay vì sử dụng các từ khoá phức hợp như inline-flex.
  • Khu vực CSS: cho phép bạn lấp đầy một vùng được chỉ định, không phải hình chữ nhật mà nội dung có thể chuyển vào và ra khỏi
  • Mô-đun CSS: JavaScript có thể yêu cầu mô-đun CSS và nhận lại một đối tượng đa dạng thức dễ dàng thực hiện các thao tác trên