- Khi CSS
@property đã được hỗ trợ trên hầu hết các trình duyệt hiện đại, có thể khai báo rõ cú pháp, giá trị khởi tạo, khả năng kế thừa cho custom property và cho phép trình duyệt nội suy giá trị một cách tự nhiên
- Nút CTA trong ví dụ định nghĩa
--gradient-angle là kiểu <angle> để chuyển từ 0deg sang 360deg, rồi dùng conic-gradient để tạo viền bóng xoay
- Hiệu ứng hover gán kiểu cho các thuộc tính như
--gradient-percent, --gradient-angle-offset, --gradient-shine để độ dài và độ sáng của vùng bóng thay đổi mượt mà
- Tốc độ xoay được xử lý bằng cách khai báo cùng một animation hai lần, animation thứ hai ở trạng thái chạy ngược và tạm dừng, rồi khi hover sẽ chậm lại còn một nửa tốc độ ngay tại vị trí hiện tại
- Việc định nghĩa custom property dựa trên
@property mở ra các biểu đạt CSS trước đây khó triển khai, đồng thời có nhiều tiềm năng áp dụng trong ứng dụng quy mô lớn và design system
Hoạt ảnh custom property được mở ra bởi @property
@property là quy tắc dùng để khai báo cú pháp được phép, giá trị khởi tạo và khả năng kế thừa cho CSS custom property
- Đây là tính năng gắn với CSS Properties and Values API của CSS Houdini, và gần đây đã được hỗ trợ trên tất cả trình duyệt hiện đại
- Khi trình duyệt biết kiểu của custom property, nó có thể nội suy giữa các giá trị, nhờ đó dễ tạo transition và animation mượt hơn so với khi chỉ dùng CSS variable thông thường
Viền bóng xoay của nút CTA
- Ví dụ này triển khai bằng CSS kiểu nút CTA lấp lánh thường thấy trên web
- Custom property cốt lõi là
--gradient-angle, và được khai báo bằng @property với cú pháp <angle> cùng giá trị khởi tạo 0deg
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
- Nhờ định nghĩa này, trình duyệt có thể chuyển mượt từ
0deg đến 360deg, khiến conic-gradient được render như đang xoay
@keyframes rotate-gradient {
to { --gradient-angle: 360deg; }
}
.rotate-gradient {
background: conic-gradient(from var(--gradient-angle), transparent, black);
animation: rotate-gradient 10s linear infinite;
}
- Có thể xem khái niệm này với lượng mã tối thiểu trong demo CodePen
Tạo viền bóng bằng các lớp nền
- Viền bóng được tạo bằng cách đưa cả
linear-gradient và conic-gradient vào background, rồi đặt điểm gốc khác nhau cho từng nền
linear-gradient dùng padding-box nên không tràn sang vùng viền
conic-gradient dùng border-box nên mở rộng đến cả phần không gian do độ dày viền tạo ra
- Thêm viền trong suốt
1px để phần conic-gradient đang xoay lộ ra
.border-gradient {
background:
linear-gradient(black, black) padding-box,
conic-gradient(from var(--gradient-angle), transparent 25%, white, transparent 50%) border-box;
border: 1px solid transparent;
}
Gradient thay đổi mượt khi hover
- Với mỗi custom property cần cho transition khi hover,
syntax được khai báo trong @property để trình duyệt có thể nội suy sự thay đổi giá trị
- Nền của nút gồm
linear-gradient phụ trách màu bên trong và conic-gradient phụ trách phần bóng ở viền
--gradient-percent quyết định kích thước vùng bóng, và khi hover sẽ tăng lên để vùng bóng dài hơn
--gradient-angle-offset được dùng để căn lại góc gradient, tránh cảm giác vùng bóng giật về trước hoặc sau trong lúc hover
- Độ sáng
--gradient-shine được giảm xuống để hòa trộn tự nhiên hơn với màu highlight xung quanh
Cách làm chậm tốc độ xoay khi hover
- Mẹo CSS để giảm tốc độ xoay là khai báo cùng một animation xoay hai lần
- Animation thứ hai được đặt chạy ngược, chia đôi thời lượng, và ở trạng thái mặc định là
paused
- Khi hover,
animation-play-state: running sẽ ghi đè trạng thái paused, làm chuyển động xoay chậm lại còn một nửa tốc độ
- Khi kết thúc hover, animation không bị giật về điểm bắt đầu mà tăng tốc lại từ đúng vị trí hiện tại
- Animation của nút CTA dùng cách này để giữ cho chuyển động xoay và các chuyển động khác vẫn ăn khớp với nhau ngay cả khi tốc độ thay đổi
Những tia lấp lánh nhỏ và highlight bên trong
- Mẫu chấm nhỏ bên trong nút được render bằng nền
radial-gradient trên pseudo-element ::before
--gradient-angle cũng được dùng lại ở đây, khi mask conic-gradient xoay sẽ chỉ làm lộ ra một phần của mẫu chấm
- Góc gradient của mask được lệch
45deg để khớp với chuyển động xoay của viền bóng
.shiny-cta::before {
mask-image: conic-gradient(
from calc(var(--gradient-angle) + 45deg),
black,
transparent 10% 90%,
black
);
}
- Pseudo-element
::after được thêm một gradient chứa màu highlight để cùng xoay với vùng bóng
- Highlight bên trong giúp tăng cảm giác ánh sáng đang chảy ở mặt trong của nút
Điều chỉnh màu hover và độ hoàn thiện
- Vì
::before và ::after của nút đã được dùng, phần chữ của nút được bọc trong span
- Một trong các pseudo-element của
span được áp dụng box-shadow mờ chứa màu highlight và mở rộng đến kích thước của nút
- Khi hover, pseudo-element này từ từ phóng to rồi thu nhỏ lại, tạo cảm giác như một nhịp thở nhẹ
- Kết hợp với màu highlight đang xoay bên trong, hiệu ứng cuối cùng của nút CTA được hoàn thiện
Tiềm năng mở rộng sang design system
1 bình luận
Ý kiến trên Hacker News
Tôi không phải là lập trình viên web, nhưng cũng từng làm vài website nhỏ không dùng framework và làm các tác vụ cơ bản trong một số framework web; hồi CSS mới xuất hiện thì tôi còn cảm giác chỉ cần thêm chút thời gian là có thể ghi nhớ hết trong đầu rồi dùng được.
CSS trong ví dụ CodePen đầu tiên trông gần như là một cú pháp khó hiểu không thể nhận ra nổi, và tôi cũng băn khoăn liệu trong hệ thống style có thật sự cần cả một ngôn ngữ lập trình animation thu nhỏ như vậy không.
Cảm giác như đây là việc JavaScript có thể làm được; tôi hiểu sự phản cảm với việc dùng JS cho mọi thứ, nhưng nếu đã là ngôn ngữ lập trình thì có vẻ mấy việc như thế này lại gần với đúng chuyên môn của nó hơn.
Dĩ nhiên cũng có thể làm bằng JavaScript, hoặc đặt
canvasvào rồi lập trình hiệu ứng trên GPU bằng WebGL. Đổi lại thì bạn sẽ phải tự làm lại toàn bộ tính năng trợ năng của nút HTML, và tôi không chắc như vậy có dễ hơn không.Dù các engine JS hiện đại rất ấn tượng, chúng vẫn không hiệu quả bằng native code, nên CPU sẽ bị dùng nhiều hơn, và cuối cùng cũng không tốt cho thời lượng pin.
Cũng vì lý do đó mà tôi luôn trân trọng những trang không bắt JavaScript là bắt buộc.
Một số nền tảng hosting vì lý do bảo mật cho phép cá nhân hóa HTML và CSS nhưng chặn JS. Những nơi như Itch.io, nơi có thể trang trí game và hồ sơ cá nhân, là ví dụ như vậy; dùng animation CSS thì có thể tạo hiệu ứng đẹp mà không cần cấp quyền truy cập JS, nên hoàn toàn hợp lý và hữu ích.
Khi đọc bài này tôi có cảm giác não mình đang kháng cự trước một khái niệm lạ. Trước khi xem các ví dụ trong blog, tôi khuyên nên đọc trước bài MDN được link ngay ở câu đầu tiên.
@propertycó lẽ phải tự nghịch thử mới ngấm, và nếu bạn muốn giảm phụ thuộc vào JS khi làm UI phức tạp thì biết những tính năng CSS khó nhằn như thế này sẽ là một vũ khí rất mạnh.Biến CSS vốn cũng cascade và có thể bị ghi đè bởi class các kiểu rồi mà; mấy thứ như
bg-opacitycủa Tailwind chẳng phải cũng theo cách đó sao?Đọc MDN thì tôi hiểu nó gần như giống biến CSS trước đây, nhưng có thêm phạm vi theo phần tử cụ thể hoặc phần tử con, cùng một số ràng buộc để nhận biết các đơn vị CSS như góc, phần trăm, v.v.
Dù vậy tôi vẫn không nghĩ mình sẽ dùng. Những lợi ích nhỏ như vậy không đủ để biện minh cho độ phức tạp và chi phí tương thích, và tôi cố tránh cú pháp mới không cần thiết. Từ sau biến CSS thì tôi cũng không còn mặn mà lắm với các tính năng CSS mới.
Tôi không rõ nó có ưu điểm gì so với việc dùng CSS
transform.Tôi rất thích làm việc với CSS, nhưng cũng làm cùng các đồng nghiệp thấy CSS khó nhằn, nên tôi cực kỳ khuyên xem kênh YouTube của Kevin Powell.
Anh ấy đã nói về tính năng này vài lần, và trong video đăng một tuần trước có chỉ ra một khả năng hữu ích mà registered properties mang lại: https://youtu.be/U8NykwZNbGs
Cũng có một bài viết diễn giải registered properties bằng ví dụ dễ theo dõi: https://moderncss.dev/providing-type-definitions-for-css-wit...
Gần đây tôi rất hào hứng với các công việc CSS, đặc biệt là Houdini. Từ lần xem sách tính năng của IE 5.5 đến giờ tôi mới lại có cảm giác này.
Trong 14 năm qua CSS đúng là có thêm nhiều tính năng mới, nhưng phần lớn thiên về các nền tảng cơ bản mà framework style nào cũng mong đợi, như tùy chọn layout mới hay biến.
Nhưng các lập trình viên IE ngày xưa thực sự rất liều, thậm chí còn có thể đóng gói code JS thành module rồi gắn vào phần tử bằng CSS. Cuối cùng tôi có cảm giác những tính năng táo bạo như vậy đang quay trở lại.
Ví dụ: https://developer.chrome.com/docs/css-ui/houdini
Bài ngắn mà hay. Nếu muốn xem thêm ví dụ, nhất là những ví dụ đơn giản hơn nhiều để bắt nhịp nhanh hơn, tôi khuyên đọc bài trên CSS-Tricks cũ này.
Dù là bài từ năm 2021 nhưng vẫn còn giá trị và được làm rất tốt: https://css-tricks.com/exploring-property-and-its-animating-...
Tôi nghĩ bạn sẽ đặc biệt thích ví dụ flip display kiểu bảng số sân bay/timer lật số.
Tôi đã rời xa phát triển web một thời gian, và mất quá lâu mới hiểu được tính năng này thực sự làm gì. Có vẻ bài viết giải thích chưa tốt
Theo cách tôi hiểu thì thay vì dùng giá trị thô như
360deg, bạn sẽ viết kiểufrom var(--gradient-angle), và giá trị đó sẽ được thay thế bằng giá trị lấy từ nơi nó được định nghĩa trong khối@property --gradient-angle {...}Cũng có
inherits: false;, tôi hiểu nó hoạt động như thế nào nhưng không rõ vì sao lại cần. Với bộ chọn CSS thì đã có thể kiểm soát kế thừa rồi, nên khó theo kịp ý là bây giờ còn có thể kiểm soát ở chỗ khác nữa hay saoTôi cũng thắc mắc vì sao phải định nghĩa kiểu trong khối
@property. Những chỗ khác trong CSS đâu có định nghĩa kiểu, nên tôi tự hỏi liệu trình duyệt không thể suy luận từ nơi@propertyđược dùng hay saoTrước đây, trong một thử nghiệm biến giao diện YouTube thành kiểu neon, tôi đã để màu chủ đạo được điều khiển bằng một biến CSS duy nhất và cho sắc độ của nó dịch chuyển chậm qua toàn bộ phổ màu
Nếu không có
@propertythì không thể animate biến CSS, nên đây không chỉ là dùng biến thay cho giá trị thô, mà còn cho phép animate chính biến đó cùng mọi nơi tham chiếu đến nó. Chỉ với@keyframes neon-flow { from { --dc-neon-hue: 0; } to { --dc-neon-hue: 360; } }là có thể làm chuyển động toàn bộ màu chủ đạo, bóng đổ, v.v.inherits: falsekiểm soát cách thuộc tính tự định nghĩa được kế thừa. Bạn có thể để nó truyền xuống phần tử con nhưcolor: red, hoặc chỉ áp dụng cho chính phần tử đó nhưdisplay: flexKiểu có vẻ cần thiết để biết sẽ animate cái gì tại thời điểm tĩnh. Biến CSS có thể là bất cứ thứ gì, còn thuộc tính CSS thông thường thì bản thân thuộc tính đã mang thông tin kiểu, như
colorchẳng hạnĐiều thú vị là cú pháp kiểu này giống hệt cú pháp chính thức bạn thấy trên MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/color#forma... Có cảm giác như phần nội bộ của CSS được lộ ra thành một API để lập trình viên có thể dùng
@property, ví dụ bạn có thể khai báo--my-prop: 10pxrồi dùngvar(--my-prop)ở nơi khácTính năng mới
@propertycho phép định nghĩa trước thuộc tính để chỉ rõ nó phải nhận kiểu cú pháp nào, có kế thừa giá trị từ cha hay không, vàinitial-valuemặc định là gìVì vậy nếu một phần tử gán
--my-prop: 5pxcho một thuộc tính đã được khai báo là kiểu góc, giá trị đó sẽ bị bỏ qua. Trước đây nó vẫn là một giá trị hợp lệ và có thể gây tác dụng phụ ngoài ý muốn tùy theo nơi được dùngNgoài ra, khi viết
--my-prop: initialthì có thể dùnginitial-valuemà không cần biết chính xác giá trị mặc định là gì@propertylà gì hay dùng như thế nàoVí dụ quá phức tạp đã che lấp hoàn toàn điều đó
Trang web này làm tôi thấy vui
Ban đầu tôi vốn đã thích mày mò CSS, nhưng sau hơn 10 năm làm web và biến công việc liên quan đến web thành nghề, tôi cũng biết mọi người ghét CSS đến mức nào
Tôi có thể dành vô tận thời gian để khám phá và thử nghiệm HTML+CSS viết tay, thậm chí còn deploy chỉ để xem cảm giác trên điện thoại thật ra sao. 99% trong số đó chẳng bao giờ được dùng ở đâu cả
Với phần lớn mọi người thì đó là lãng phí thời gian, nhưng trang này thực sự làm ngày của tôi vui hơn
Trong 10 năm qua nó có phức tạp hơn, nhưng những việc từng làm 10 năm trước giờ có thể làm đơn giản hơn rất nhiều, và mã của thời đó vẫn chạy bình thường
Mà thế cũng không sao. Tôi cũng không hiểu APEX, APL hay framework mới nhất hôm nay. Nhưng tôi hiểu CSS, và vì vậy tôi khá thích nó
Có người hợp với nó, có người thì không. Vấn đề là khi ai đó không hợp với CSS nhưng vì công việc vẫn phải làm CSS, thì đương nhiên họ sẽ ghét nó. Nếu công việc của tôi bắt tôi bảo trì cài đặt Active Directory thì tôi cũng sẽ ghét thôi. Nhưng bản thân CSS không có gì xấu
Chắc hẳn ở đâu đó có diễn đàn thảo luận nghiêm túc, nhưng có lẽ tôi đã bỏ lỡ
Trong môi trường production, đặc biệt là frontend, trước giờ tôi gần như viết mọi thứ bằng JSX, nhưng từ khi sa vào rabbit hole về web scraping thì khả năng hiểu logic bộ chọn của tôi đã tốt hơn nhiều
Một suy nghĩ hơi khiêu khích liên quan là nếu trong thực tế người ta dùng phần tử ngữ nghĩa nhiều hơn, thì có lẽ logic bộ chọn đã không đau đầu như bây giờ. Những thứ như modal, vốn HTML thuần đã định nghĩa sẵn hành vi, cũng không cần tự bảo trì thủ công nữa
Trước đây Microsoft là bên nổi tiếng vi phạm đặc tả nhất, còn bây giờ theo tôi là Apple
Những animation này khiến mọi thứ trông như quảng cáo hiển thị của thập niên 2000. Theo nghĩa xấu
Tôi thực sự hy vọng kiểu thẩm mỹ này sẽ không thành xu hướng
Những thứ này mang cảm giác rất marketing và thao túng. Tôi muốn được đọc trang web và tự quyết định mình sẽ làm gì. Tôi không muốn bị phân tâm bởi việc cố cưỡng ép sự chú ý vào thứ tạo ra tiền
Nếu không thì mọi người sẽ triển khai tất cả bên trong hệ sinh thái đóng
PFM, tức “ma thuật thuần túy”, đúng là cảm giác nảy ra khi nhìn thấy những gì có thể làm được với animation CSS
Nhưng nó quá chuyên biệt cho CSS và chỉ dành cho CSS, nên còn khó học và khó khái niệm hóa hơn cả việc triển khai theo kiểu thủ tục bằng JS. Kiểu tư duy đó không dễ hình thành, và chỉ riêng các tùy chọn dùng CSS
flexcũng đã đủ khiến người ta quá tảiNhưng nó mạnh mẽ, thực sự cực kỳ mạnh mẽ, và rất hiệu quả trên hầu hết trình duyệt. Đại đa số áp đảo các nhà phát triển ứng dụng web không cần đến 99% những gì CSS cung cấp, nhưng biết rằng các tính năng đó tồn tại vẫn rất hay
Chỉ cần ném các phần tử không có style nhưng đã gắn với business logic lên trang, rồi designer có thể style theo ý muốn. Nếu cần thì sau đó cứ lặp lại việc tinh chỉnh UI
Nếu chỉ nhìn từ góc độ mệnh lệnh thuần túy thì sẽ cần chút thời gian để đọc đặc tả và thử nghiệm, nhưng tôi nghĩ đó là một lối tư duy đáng giá vượt ra ngoài việc chỉ dùng SQL và CSS. Tất nhiên bản thân SQL và CSS cũng đã đủ giá trị
Tôi sẽ rất vui nếu họ chỉ cần chốt tên[1] cho tính năng CSS “masonry” để có thể dùng nó mà không cần script
[1] https://github.com/w3c/csswg-drafts/issues/9733
propertylà một phần của CSS Houdini API, cho phép thao tác CSS từ JavaScript mạnh hơn rất nhiều so với trước đâyhttps://developer.mozilla.org/en-US/docs/Web/API/Houdini_API...
Mức độ nhiệt huyết mà tác giả thể hiện với mẩu CSS mới này là thứ tôi gần như chưa thấy lại suốt 10 năm qua, và điều đó thật tuyệt
Nếu còn ở tuổi 20, có lẽ tôi đã mày mò với tiềm năng của tính năng này hàng giờ, thậm chí hàng ngày. Việc làm cho thứ gì đó hoạt động trong CSS từng rất thú vị
Bây giờ thì nhờ
flexbox,grid, và việc phần lớn website cùng ứng dụng tuân theo các nguyên tắc thiết kế tiêu chuẩn, mọi thứ đã trở nên khá dễ hơn, và tôi cho rằng UI web phần lớn đã gần như là một bài toán đã được giảiTôi vẫn có lúc phải đọc lại những phần mơ hồ của
flexvàgrid. Định vịstickylà một trong những tính năng hữu ích nhất, nhưng nếu vì lý do nào đó mà nó không hoạt động thì việc debug và hiểu nguyên nhân rất khó, gần như bất khả thi. Ví dụ như chuyện ở đâu đó trong phần tử cha cóoverflowCũng khó tìm được tài liệu giải thích tốt các ca góc cạnh như vậy, và việc debug CSS chỉ bằng source code mà không có công cụ dev gần như là không thể, nên phải kiểm tra phần tử lúc runtime
Phần lớn các phần tử input native vẫn còn rất hạn chế về khả năng styling, còn modal và popover native thì cũng đã phải chờ nhiều năm. Lần cuối tôi kiểm tra thì vẫn chưa thể animate chiều cao từ
display: nonesangblockTôi có cảm giác chúng ta đã quá quen với các vấn đề khác nhau của CSS đến mức đánh mất sự tỉnh táo để phê phán nó