1 điểm bởi GN⁺ 1 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • CSS text-stroke chỉ nhận một giá trị, nhưng có thể tạo hiệu ứng văn bản nhiều đường viền kiểu retro bằng cách chồng nhiều lớp của cùng một ký tự và đặt độ dày đường viền cùng màu khác nhau cho từng lớp
  • Tham khảo hiệu ứng chữ trong Graphic Japan : from woodblock and zen to manga and kawaii, khi đặt text-stroke-width khác nhau cho nhiều phần tử thì cho ra kết quả gần hơn
  • Kết hợp text-stroke-width, text-stroke-color, z-index theo từng lớp để điều khiển thứ tự và màu của đường viền, đồng thời vẫn giữ nguyên hình dạng chữ gốc ngay cả khi độ dày tăng lên
  • Kết quả render khác nhau giữa các trình duyệt, và Firefox trông mượt hơn so với Chrome và Safari; nếu đặt nhiều ký tự trên cùng một dòng thì hình dạng chữ sẽ bị nhập vào nhau
  • Kết quả phụ thuộc nhiều vào phông chữ được chọn, và ở font-size lớn có thể xuất hiện hiện tượng nhấp nháy, nên phù hợp để thử nghiệm hoặc tạo ảnh bằng css-doodle hơn là dùng trong production

Cách triển khai

-webkit-text-stroke-color: @pn(--c, #f4e1e8);
-webkit-text-stroke-width: $em(.08n+.02(1-(-1)^n));
  • Gán màu khác nhau cho từng lớp và chồng chúng theo thứ tự mong muốn để điều khiển màu sắc và thứ tự của đường viền
-webkit-text-stroke-color: @pn(#f4e1e8, #cc0d55);
-webkit-text-stroke-width: @i(*3px);

Kết xuất và giới hạn

  • Firefox cho kết quả render mượt hơn Chrome và Safari
  • Nếu đặt nhiều ký tự trên cùng một dòng thì hình dạng chữ sẽ bị nhập vào nhau
@content: '秋收冬藏';
  • Để thử nghiệm nhanh nhiều phông chữ khác nhau, đã thêm hàm @google-font để tăng tốc việc tải phông chữ
font-family: @google-font(Matemasie);
@content: 'b';
font-family: @google-font(Tangerine);
@content: 'Love';
font-family: @google-font('Cherry Bomb One');
@content: '+';
  • Hiệu năng không tốt như CSS filter, và đặc biệt khi font-size càng lớn thì càng có thể thấy hiện tượng nhấp nháy
  • Các ví dụ bổ sung được tạo bằng css-doodle, và có thể xem CodePen của ví dụ đầu tiên tại https://codepen.io/yuanchuan/pen/ogzarGo

1 bình luận

 
Ý kiến trên Hacker News
  • Bài này do chính tác giả của css-doodle tạo ra bằng css-doodle. Web component này cho phép chèn trực tiếp cú pháp CSS biến thể dùng trong bài blog vào trong HTML
    Ví dụ như sau:
    @grid: 15 / 90%;
    border-radius: 50%;
    background: hsl(@t(/20), 70%, 60%);
    scale: sin(@atan2(@dx, @dy) + @ts);
    Không cần JavaScript ngoài việc tải định nghĩa component, và nó hoạt động trong HTML thông thường, Markdown, framework, v.v.
    https://css-doodle.com/

    • Cảm ơn vì lời giải thích. Từ khi rời công việc frontend vào năm 2018, tôi gần như không còn biết CSS giờ có thể làm được những gì nữa
      Khá nhiều CSS trên trang này với tôi trông như mật mã. Xin dành lời khen cho tác giả vì đã đăng thứ gì đó mới mẻ và ngầu trong thời đại mà rất nhiều style đã được chuẩn hóa
  • Tôi thắc mắc vì sao engine render CSS của Firefox lại ưu tiên cách xử lý mượt hơn. Cách triển khai trông khác biệt rõ rệt, nhưng cũng có thể chỉ vì đây là một trường hợp biên của render nên mới như vậy

    • Mở rộng nét viền là một chủ đề phức tạp, không chỉ có một kết quả hợp lý duy nhất, mà còn xen lẫn sở thích chủ quan, vô số trường hợp biên và cả những đáp án sai
      Firefox chọn mở rộng dựa trên khoảng cách tại mọi điểm, đây là một trong những đáp án hợp lý và có lẽ là cách tổng quát nhất. Vì vậy các cusp nhọn được mở rộng thành đường cong
      Các trình duyệt khác chọn giữ nguyên cusp, điều này cũng có thể là hợp lý và tôi nghĩ chi phí tính toán cũng thấp hơn nhiều. Nhưng nếu mở rộng vượt quá kích thước đặc trưng, tức khoảng cách giữa các node, thì sẽ xuất hiện nhiều trường hợp suy biến, nên đến khoảng vòng đỏ thứ tư thì trông rõ ràng là sai
      box-shadow cũng là một trường hợp khác có hiện tượng mở rộng. Đó là giá trị độ dài thứ tư là spread distance. Nếu góc là cusp thì góc bóng cũng là cusp, còn nếu bo tròn thì góc bóng cũng bo tròn. Có một hình minh họa hữu ích tại https://drafts.csswg.org/css-backgrounds/#shadow-shape
      Với một mẹo nhỏ, đặt 0.1px border-radius thì hộp vẫn trông như hình chữ nhật nhưng bóng được mở rộng sẽ thành đường cong. Thỉnh thoảng khá hữu ích. Quay lại nội dung bài gốc, nếu dùng một font có đường cong cực nhỏ thay vì node cusp, thì Chromium/Safari cũng sẽ gần Firefox hơn
    • Tôi không hoàn toàn thích hiệu ứng bo tròn của Firefox, nhưng cách diễn giải của Chrome tạo ra các mũi nhọn giả tạo nên nhìn đơn giản là sai
      Theo trực giác, viền ngoài của hình ngôi sao lẽ ra sẽ gần với một hình lục giác bình thường, nhưng không trình duyệt nào làm được điều đó
    • miter join là phía Safari, còn round join là phía Chrome
    • Firefox trông giống SDF. Có vẻ như là kiểu render dựa trên khoảng cách ngắn nhất đến đối tượng, còn phía Chrome thì tôi không rõ là gì
    • Phía Firefox trông đúng y như những gì có thể mong đợi từ việc cắt từng mức của kết quả SDF của ký tự đó
      Các góc bo tròn của layer đầu tiên sẽ đều cách cạnh gần nhất của ký tự gốc cùng một khoảng
  • Tôi thật sự thích thiết kế blog này. Nó đơn giản, rõ ràng và ưu tiên nội dung

    • Đúng vậy. Có nhiều bài viết trình bày CSS/SVG/canvas rất rõ ràng
      Loạt Daily Sketch hay CSS Animation with offset-path cũng thú vị y như vậy
  • Đọc bài này tôi mới biết đến https://css-doodle.com lần đầu
    Vài tháng trước tôi từng làm thứ tương tự bằng HTML Canvas API, nhưng không ngờ CSS cũng có thể làm những trò nhỏ thú vị như thế này. Tôi rất thích nó

  • Tôi thử đổi fiddle thành logo và màu của Apple thì vòng đầu tiên ăn mất một phần quả táo. Phần trên của quả táo bị cắt mất, không biết có ai hiểu vì sao không
    --c: #5EBD3E,#FFB900,#F78200,#E23838,#973999,#009CDF;
    @content: '';

  • Tôi muốn biết cách tốt nhất để tạo chữ viền kép mà không dùng các ký tự Unicode màu mè, đồng thời vẫn giữ cách hiển thị mà font khuyến nghị
    Hiện tại tôi đang dùng các ký tự đẹp trên my blog, nhưng điều đó gây hại cho kết quả tìm kiếm. Tôi đang chuyển blog từ HTML viết tay sang 11ty, nên cũng muốn cải thiện blog cùng lúc
    Nhân tiện, tôi cũng muốn nhận ý kiến về thiết kế blog hiện tại

  • Ngầu đấy. Chỉ tiếc là khác biệt render giữa các trình duyệt lại lớn quá
    Tôi cũng tò mò không biết có ai thử làm điều tương tự bằng shadow chưa. Có vẻ shadow cũng có thể xếp chồng được

    • Để tạo viền thì phải làm shadow lan tỏa theo hình tròn, nên hình dạng tổng thể cuối cùng sẽ gần như hội tụ về hình tròn và hầu như không còn bám theo hình chữ nữa
  • Điều đầu tiên tôi nghĩ đến là đưa emoji vào content. Nhưng rồi chỉ hiện ô vuông ký tự không xác định. Chắc tôi đã kỳ vọng có điều gì đó như phép thuật

    • Bên tôi emoji có render, nhưng hoàn toàn không có hiệu ứng viền, chỉ thấy mỗi emoji gốc thôi
    • Dùng Noto Emoji làm font thì sẽ hoạt động