- Nguyên nhân chính khiến hiệu năng website suy giảm gần đây là lạm dụng JavaScript và các script theo dõi; trong nhiều trường hợp, chỉ với HTML/CSS cũng đã có thể thay thế đầy đủ
- Những tính năng mới được bổ sung gần đây như CSS nesting, relative colors, các đơn vị viewport mới (lvh, svh, dvh) giúp giải quyết đơn giản các tác vụ trước đây phải phụ thuộc vào JS hoặc preprocessor
- CSS không chỉ là công cụ tạo kiểu đơn thuần mà còn là một ngôn ngữ mạnh mẽ có thể triển khai animation, kiểm tra đầu vào, giao diện dark mode, menu accordion
- Xét về hiệu năng, CSS được tăng tốc bằng GPU và chạy trên luồng riêng nên mượt mà và hiệu quả hơn JS trong animation và hiệu ứng chuyển tiếp
- Tác giả nhấn mạnh CSS không chỉ là công cụ thực dụng mà còn là phương tiện biểu đạt và nghệ thuật, đồng thời khuyến khích các lập trình viên web khai thác nhiều hơn tiềm năng của CSS hiện đại
Mở đầu: Sự phức tạp của web, và những thử nghiệm mới
- Nhiều website đang gặp vấn đề suy giảm hiệu năng và độ phức tạp do lạm dụng framework JavaScript
- Ứng dụng React mất vài giây để tải, còn NextJS thì phát sinh lỗi hydration
- Thư mục
node_moduleschiếm tới vài gigabyte dung lượng
- Ngay cả không có JavaScript, vẫn có thể triển khai các chức năng mạnh mẽ chỉ với HTML và CSS
- Ngoài các giỏ hàng phức tạp của trang thương mại điện tử hay dashboard, JavaScript có thể không thực sự là thứ bắt buộc
- Bài viết này giới thiệu các tính năng mới nhất của CSS, nhằm khuyến khích lập trình viên khám phá nhiều khả năng đa dạng mà không chỉ phụ thuộc vào JavaScript
Những hiểu lầm và nhận thức về CSS
CSS có thật sự khó và bất tiện không?
- Cái nhìn tiêu cực về CSS bắt nguồn từ thiếu nền tảng học tập cơ bản
- Nhiều lập trình viên bỏ qua kiến thức nền tảng về CSS và chỉ tập trung vào JavaScript hoặc TypeScript
- CSS không phải chỉ là công cụ styling đơn giản, mà là một ngôn ngữ chuyên biệt theo miền với những khả năng mạnh mẽ
- CSS có thể triển khai dễ dàng các layout phức tạp bằng công cụ như flexbox
- Ví dụ: chỉ với
display: flexvàjustify-content: centerlà có thể căn giữa div một cách đơn giản - Developer tools của trình duyệt cung cấp widget để điều chỉnh trực quan các thuộc tính flexbox
- Ví dụ: chỉ với
- Nếu chỉ đào sâu một phía (ví dụ JS) và xem nhẹ CSS thì việc cảm thấy gánh nặng cũng là điều dễ hiểu
Nỗi khổ khi viết CSS, và sự thay đổi
- Trước đây CSS không thật sự tiện dụng, nên các công cụ như Sass hay Tailwind đã xuất hiện
- Ví dụ: phải quản lý các chuỗi selector dài như
.post > .buttons .like:hover
- Ví dụ: phải quản lý các chuỗi selector dài như
- Gần đây, các tính năng cải thiện chất lượng (như nesting) đã được bổ sung, giúp việc phát triển trở nên thoải mái hơn chỉ với CSS thuần
- CSS nesting giúp gom các style liên quan vào một chỗ, tăng khả năng đọc
- Ví dụ:
.post { & > .buttons { .like { &:hover { ... } } } } - Quan hệ cha-con trở nên rõ ràng hơn, nên có thể dùng tên class ngắn và đơn giản
- Ví dụ:
- CSS nesting giúp gom các style liên quan vào một chỗ, tăng khả năng đọc
- Relative colors giúp việc điều chỉnh màu sắc trở nên dễ dàng
- Có thể chỉnh độ sáng bằng
hsl(from #123456 h s calc(l + 10)) - Tạo màu động bằng cách trộn hai màu với
color-mix()
- Có thể chỉnh độ sáng bằng
- Cú pháp phạm vi media query cho phép viết điều kiện trực quan như
(width <= 768px) - Đơn vị lh hỗ trợ tạo style theo chiều cao dòng
- Thuộc tính scrollbar-gutter giải quyết vấn đề layout bị xô lệch do thanh cuộn
- Baseline bảo đảm khả năng tương thích tính năng trên các trình duyệt chính
- newly available là các tính năng hoạt động trên trình duyệt mới nhất
- widely available là các tính năng được hỗ trợ tới cả trình duyệt từ 2,5 năm trước
- Ví dụ: CSS nesting đã được mọi trình duyệt hỗ trợ từ tháng 12/2023
Vì sao phát triển chỉ với CSS/HTML?
- Một số người dùng tắt JavaScript theo mặc định (vì lý do bảo mật, quyền riêng tư, v.v.)
- Nếu cung cấp website chỉ bằng CSS/HTML thuần, những người dùng đó cũng có khả năng sử dụng trang cao hơn
- Từ góc độ phát triển lẫn người dùng, việc chỉ dùng CSS/HTML có lợi ích lớn về tốc độ, khả năng truy cập, mức dùng CPU và pin
- CSS animation chạy trên compositor thread, giúp giảm tải cho CPU
- JavaScript chạy qua event loop nên có thể phát sinh độ trễ nhỏ
- Cải thiện khả năng truy cập và tính dễ sử dụng
- Hiệu ứng hover cho nút, animation toast, kiểm tra đầu vào đều có thể triển khai đơn giản bằng CSS
Ví dụ thực tế và các tính năng chính của CSS
Tạo animation khởi đầu tự nhiên với @starting-style
- Trước đây, để tạo animation khi phần tử xuất hiện cần cấu trúc phức tạp như keyframes, JS trigger, v.v.
- Việc bổ sung @starting-style giúp chỉ định trạng thái ban đầu trở nên đơn giản. Có thể dễ dàng tạo animation cho trạng thái khởi đầu của phần tử (ví dụ: fade-in)
- Thiết lập bằng
transition: opacity 1s; @starting-style { opacity: 0; } - Hoạt động mà không cần
@keyframeshay JavaScript riêng
- Thiết lập bằng
- Chỉ cần khai báo trạng thái ban đầu cùng với transition là animation sẽ được áp dụng tự nhiên
- Ví dụ: xử lý mượt mà việc chuyển đổi độ trong suốt và vị trí của thông báo toast
Thiết lập giao diện dark/light mode một cách dễ dàng
- color-scheme: light dark tự động chuyển theme theo tùy chọn của người dùng
- Hàm light-dark(#000, #FFF) cho phép chỉ định màu phù hợp với chế độ sáng/tối
- Dùng radio button và selector :has để hỗ trợ người dùng tự chọn theme
- Có thể chuyển theme chỉ bằng CSS mà không cần JavaScript
- Có thể bổ sung JavaScript tùy chọn để lưu/tải theme
Tạo UI tùy biến với radio/checkbox và :has, :checked
- Các tương tác phức tạp như tab, accordion, toggle cũng có thể triển khai mà không cần JavaScript
- Radio button có thể được custom styling bằng :checked và :has
- Ví dụ: chỉ định style cho nút đã chọn bằng
label:has(input:checked) - Ẩn phần tử input bằng
opacity: 0nhưng vẫn giữ được khả năng truy cập cho trình đọc màn hình
- Ví dụ: chỉ định style cho nút đã chọn bằng
- Phần tử details phù hợp để tạo menu accordion như FAQ
- Có thể điều khiển trạng thái chỉ mở một mục bằng thuộc tính
name - Có thể thêm animation theo trạng thái
[open]
- Có thể điều khiển trạng thái chỉ mở một mục bằng thuộc tính
Kiểm tra đầu vào và phản ánh trạng thái
- Kết hợp các thuộc tính HTML như pattern, required với pseudo-class CSS (:valid, :invalid, :user-valid, v.v.) để cung cấp kiểm tra theo thời gian thực và phản hồi trực quan
- Cải thiện trải nghiệm người dùng bằng cách thay đổi style outline/border của trường nhập liệu
- Dùng thuộc tính pattern của HTML để kiểm tra tính hợp lệ của trường nhập
- Ví dụ:
\w{3,16}cho phép từ 3 đến 16 ký tự chữ cái/số/gạch dưới
- Ví dụ:
- Dùng :valid và :invalid của CSS để styling theo tính hợp lệ
- :user-valid và :user-invalid chỉ áp dụng style sau khi người dùng đã nhập
- Có thể styling phần tử khác theo trạng thái input bằng selector :has
- Trong một số trường hợp (ví dụ điều kiện nhập phức tạp), JS vẫn cần thiết, nhưng phần lớn trường hợp CSS/HTML là đủ
Cách dùng đúng các đơn vị viewport
- Đơn vị vw/vh gặp vấn đề độ chính xác trên di động do thanh địa chỉ (thanh điều hướng) xuất hiện/biến mất
- Khuyến nghị dùng các đơn vị viewport mới như lvh/svh/dvh (largest/smallest/dynamic viewport height)
- lvh: dùng cho toàn màn hình (ví dụ nền toàn trang)
- svh: dùng cho các nút, liên kết luôn phải hiển thị trên màn hình
- dvh: phân bổ kích thước linh hoạt theo thay đổi như cuộn trang
- Overlay bàn phím có thể xử lý bằng thuộc tính interactive-widget hoặc VirtualKeyboard API
<meta name="viewport" content="width=device-width, interactive-widget=resizes-content">- Trên các trình duyệt dựa trên Chromium có thể dùng
navigator.virtualKeyboard.overlaysContent = true
Wishlist cho CSS (những gì còn thiếu hoặc mong muốn có)
- Khối có thể tái sử dụng: áp dụng class khác bên trong một class (ví dụ
@apply border) - Selector kết hợp media query: kết hợp
@mediavới selector class - Biến nth-child:
span { --nth: nth-child(); }để styling động - Selector nth-letter: styling ký tự cụ thể (ví dụ
p::nth-letter(2)) - Loại bỏ đơn vị: tạo giá trị không đơn vị bằng
calc(100vw / 1px) - Hàm image(): hỗ trợ màu thay thế và mảnh ảnh
- Thẻ style trong body: hỗ trợ tiêu chuẩn chính thức để giảm vấn đề FOUC
Kết lại: CSS, và tính nghệ thuật của web
- CSS không chỉ là một công cụ đơn thuần mà còn là phương tiện biểu đạt sáng tạo
- Công cụ AI hay chuỗi build (linter, công cụ minify) có thể hạn chế tính sáng tạo
- CSS đồng thời đáp ứng hiệu năng, khả năng truy cập và biểu đạt nghệ thuật
- Bài viết này được tạo bằng khoảng 49kB HTML/CSS không có JavaScript
- Mọi widget tương tác và yếu tố thị giác đều được triển khai thủ công
- Ví dụ: trò chơi click bằng CSS chứng minh tiềm năng mang tính ngôn ngữ lập trình của CSS
3 bình luận
Tôi từng là full-stack, nhưng có lẽ càng lên cao trong sự nghiệp thì càng ít có cơ hội làm FE, nên đã gần 10 năm không đụng vào. Gần đây có dịp phải giảng ngắn cho một công ty nên xem lại để tiện giới thiệu sơ qua, và thật sự tôi rất ngạc nhiên vì nó đã thay đổi quá nhiều. Nếu kết hợp cả
scssthì còn tiện hơn nữa. Nhưng phạm vi của CSS này quả thật rất đặc biệt. Học thì dễ, nhưng để dùng đủ giỏi đến mức được công nhận thì theo tôi lại phụ thuộc vào cảm quan thẩm mỹ và sự sáng tạo của mỗi người. Thật đáng tiếc khi trong thời đại web coi trọng tính khả dụng và thiết kế hơn, giá trị của các publisher dường như vẫn chưa được đánh giá cao hơn.Lần này tôi thử làm một bảng tin cơ bản như một hoạt động sở thích để nếm thử công nghệ phát triển web, kiểu lao đầu vào từ con số 0 không có lấy chút nền tảng nào, dùng nextjs, authjs, tailwind và shadcn... nhưng độ khó học cao nhất hóa ra lại là CSS.
Ý kiến trên Hacker News
Tôi biết ơn tính năng nesting mới được thêm vào CSS, nhưng nhìn tổng thể thì CSS thật sự rất kỳ quặc và cá nhân tôi thấy đây là một ngôn ngữ tệ, có thể cũng vì tôi không dùng nó đủ giỏi, nhưng nó quá phức tạp và lộn xộn, như thể đang thử di chuyển những ký tự rune khó hiểu từ chỗ này sang chỗ khác, hệ thống styling và layout bị trộn lẫn với nhau, mà quan hệ kế thừa và bao hàm lại khác nhau nên càng rối hơn, tôi nghĩ việc gộp styling với layout là một sai lầm, và tôi không thấy việc cứ tiếp tục thêm tính năng vào một hệ thống vốn đã hỏng từ gốc có thể là lời giải
Điều tệ nhất ở CSS là có quá nhiều người chưa thực sự học nó mà chỉ bị ép dùng trong một ngày rồi bắt đầu đưa ra quan điểm rất mạnh
Tôi không thực sự bị thuyết phục bởi lập luận "một số người dùng không muốn JavaScript" trong bài này, tôi cũng là người dùng Arch và rất hăng với đủ loại scripting và crawling, nhưng tôi không thấy việc tập trung vào môi trường "NoScript" là điều đặc biệt quan trọng, đó là một sở thích của thiểu số rất nhỏ nên nhìn chung có thể bỏ qua, cảm giác giống thời người ta nói "10% còn dùng IE6", dù vậy tôi vẫn nghĩ có rất nhiều lý do khác khiến CSS vượt trội hơn, dẫu sao đây không phải trọng tâm chính nhưng tôi thấy mạch bài mang hơi hướng như vậy
Tôi không biết nesting giờ đã trở thành tiêu chuẩn chính thức rồi, cho tới gần đây tôi vẫn nghĩ nó còn ở giai đoạn đề xuất, CSS có nhiều điểm kỳ quặc thật nhưng cũng có cảm giác nó đang tiến hóa thành một ngôn ngữ ngày càng tốt hơn, giống JavaScript, nhờ Flexbox, selector :has và nesting mà rất nhiều điểm đau cũ đã được giải quyết
Có hai tính năng CSS trong wishlist thực ra đã tồn tại trong spec
Tôi thấy cú pháp CSS rất tệ, tôi dùng khoảng 10-15 ngôn ngữ nhưng CSS là thứ khó đọc và khó hiểu nhất, còn khó hơn cả x86 assembly, CSS là đầu vào được token hóa sẵn cho renderer nhưng lại không hẳn là token và cũng rất kỳ quặc để con người viết, nó giống kiểu phản diện để dùng làm ví dụ "đừng làm như thế này", như ASN.1 trong RFC vậy
Tôi tò mò không biết ví dụ radio tab này có ổn về mặt accessibility không, theo tiêu chuẩn WAI-ARIA thì hình như các thuộc tính aria-selected, tabindex, aria-controls phải được JS cập nhật khi chuyển tab, nhưng tôi không chắc, accessibility thường hay bị xếp sau, và đôi khi người ta còn nhầm rằng chỉ cần dùng HTML/CSS là accessibility sẽ tự được đảm bảo, đây là một điều cần cân nhắc thêm khi chọn cách tiếp cận
Có thể triển khai những hiệu ứng tương tác như thế này mà không cần JS (trang ví dụ)
Với tư cách một web developer 10 năm kinh nghiệm, tôi thấy những bài như thế này cần làm lung lay các niềm tin mặc định của chúng ta, tiêu đề không hay lắm nên suýt nữa tôi đã bỏ qua, nhân tiện nói luôn thì không thể render bản đồ chỉ bằng CSS
Có thể vì cái tên Vega mà tôi có chút thiên kiến, nhưng tôi thực sự rất thích site này, tổng thể thiết kế rất ổn và nội dung của trang này cũng rất tuyệt, sau này chắc chắn tôi sẽ chia sẻ link này cho những người làm web, tôi cũng rất thích arrupted, trước đây nó từng tạo ra những kết quả rất ấn tượng, nên lần này thấy lại một domain quen thuộc trên trang chủ thật đáng mừng