20 điểm bởi GN⁺ 2025-07-01 | 3 bình luận | Chia sẻ qua WhatsApp
  • Cách tái tạo các hiệu ứng cốt lõi của ngôn ngữ thiết kế Liquid Glass mà Apple công bố tại WWDC25 bằng cách kết hợp CSS và bộ lọc SVG
  • Triển khai từng bước bằng CSS/SVG nhiều lớp khác nhau để mô phỏng chất liệu kính thật như Specular Highlights, Blur, Color Filter, Refraction, Edge/Ripple Distortion, Chromatic Aberration
  • Việc hiện thực các hiệu ứng chính sử dụng các kỹ thuật CSS·SVG nâng cao như backdrop-filter, box-shadow, SVG DisplacementMap, Turbulence, ColorMatrix, Offset, Blend
  • Khả năng tương thích trình duyệt chủ yếu xoay quanh Chrome; trên Safari/Firefox, bộ lọc SVG không hoạt động nên chỉ áp dụng Blur·Shadow
  • Với các hiệu ứng càng phức tạp thì mức sử dụng GPU càng lớn, và nếu lạm dụng trên toàn bộ UI có thể làm giảm hiệu năng, nên chỉ nên dùng ở các vùng trọng tâm

Liquid Glass là gì?

  • Đây là ngôn ngữ thiết kế mới nhất của Apple, hướng tới các hiệu ứng đồ họa cao cấp mô phỏng phản xạ/khúc xạ ánh sáng, biến đổi màu sắc, chiều sâu như kính thật
  • Nó được dùng để tăng cảm giác chiều sâu và độ sống động cho các thành phần UI, với đặc trưng là hình ảnh mượt mà và gợi cảm giác chạm mang tính vật lý

Các lớp hiệu ứng chính và cách triển khai

1. Specular Highlights (ánh phản chiếu trên kính)

  • Thêm highlight ở viền kính để nhấn mạnh chiều sâu và cảm giác khối
  • Chồng nhiều inset box-shadow của CSS để thể hiện cảm giác ánh sáng phản xạ theo từng góc
    box-shadow:  
        inset 10px 10px 20px rgba(153, 192, 255, 0.1),  
        inset 2px 2px 5px rgba(195, 218, 255, 0.2),  
        inset -10px -10px 20px rgba(229, 253, 190, 0.1),  
        inset -2px -2px 30px rgba(247, 255, 226, 0.2);  
    
  • Tham khảo [Fresnel Effect] để điều chỉnh cường độ phản xạ ánh sáng một cách tự nhiên

2. Blur (làm mờ nền)

  • Dùng backdrop-filter: blur(20px); để chỉ áp dụng blur cho nội dung phía sau kính
  • Hiệu ứng chỉ áp dụng lên nội dung nền, không phải chính bản thân phần tử

3. Color Filter (nhấn màu)

  • Áp dụng thêm các backdrop-filter như contrast(80%) saturate(120%) để tạo màu sắc rõ nét thông qua tăng độ bão hòa, giảm độ tương phản của nội dung phía sau kính
    backdrop-filter: blur(20px) contrast(80%) saturate(120%);  
    

4. Mô phỏng khúc xạ (Refraction)

  • Hiệu ứng khúc xạ khiến nền phía sau bị bẻ cong theo bề mặt cong của kính khó có thể triển khai chỉ bằng CSS, nên được hiện thực bằng cách kết hợp với bộ lọc SVG

  • Displacement Map: sử dụng gradient của SVG để tạo distortion map (Identity Map) trong đó pixel bị nén ở mép và giãn ra ở phần trung tâm

    • Gradient đỏ/xanh trong ví dụ SVG xác định lượng dịch chuyển pixel theo trục X/Y
    • Điều chỉnh ramp của gradient để thiết kế mẫu nén ở viền và giãn ở trung tâm
    • Chuyển SVG thành Data URL để tải bằng feImage, rồi dùng cho biến đổi tọa độ trong feDisplacementMap
  • Ripple Distortion: kết hợp feTurbulence (texture nhiễu) và feDisplacementMap bổ sung để mô tả cả những gợn sóng nhỏ trên bề mặt kính

  • Chromatic Aberration (quang sai sắc): kết hợp feColorMatrix, feOffset, feBlend để tách và dịch từng kênh RGB rồi trộn lại, mô phỏng hiện tượng tán sắc ánh sáng quan sát được ở kính thật

Cách áp dụng hiệu ứng CSS/SVG

  • Sau khi định nghĩa SVG filter, áp dụng nó vào phần tử DOM bằng filter: url(#filterId);
  • Chuỗi filter kết hợp tất cả hiệu ứng có thể tái tạo đồng thời chất cảm của tấm kính thật, độ méo ánh sáng và biến đổi màu sắc

Lưu ý về tương thích và hiệu năng

  • SVG displacement filter chỉ được hỗ trợ đầy đủ trên Chrome. Trên Safari, Firefox... hiệu ứng sẽ bị giới hạn (chỉ còn Blur/Shadow)
  • Khi có nhiều thành phần kính hoặc áp dụng animation, tải GPU sẽ lớn và hiệu năng render giảm
  • Trên thực tế, phù hợp nhất là chỉ dùng cho một số UI cần nhấn mạnh như Hero/Feature area

Tham khảo và ghi công

3 bình luận

 
geek12356 2025-07-01

Phần người này triển khai có vẻ tự nhiên hơn đấy
https://v0.dev/chat/dynamic-frame-layout-1VUCCecq7Uy

 
zabefofoon 2025-08-01

Cái này có vẻ không áp dụng được trên Safari.

 
bobross0 2025-07-01

Triển khai trên web vẫn còn hơi gượng gạo nhỉ haha