Bài viết được sự cho phép của tác giả Lưu Bình An
File SVG
<svg class="icon">
<path />
</svg>
Thay đổi bằng giá trị fill
Cách dễ nhất, 1 dòng css duy nhất
.icon:hover {
fill: #DA4567;
}
Tuy nhiên cái này chỉ làm được khi chúng ta sử dụng file svg dạng inline, nếu dùng thẻ <img src='duong-dan-file.svg''/>
, để tách riêng file svg ra cho nó sạch sẽ file html, cached lại hình này trên trình duyệt, thì coi như chúng ta không thực hiện được cách ở trên.
CSS Filters
Với CSS filters chúng ta có trong tại kha khá đồ chơi như trong photoshop để vẽ hoa vẽ lá trên trình duyệt. Filter cũng sẽ được thực hiện sau khi trình duyệt render xong DOM, thực hiện xong bước paint (cái này các bạn phải xem lại critical render path để rõ hơn), nghĩa là nếu ko được hỗ trợ bởi trình duyệt thì cũng ko tới mức bể layout
- brightness();
- contrast();
- grayscale();
- invert();
- opacity();
- saturate();
- sepia();
- hue-rotate();
- blur();
- drop-shadow();
Chúng ta ko có filter nào để thay đổi cụ thể một giá trị màu, chỉ có hue-rotate
để chỉnh nhẹ cái màu đang hiển thị. May mắn là chúng ta có thể kết hợp nhiều giá trị filter cùng một lúc
.icon:hover {
filter: grayscale(100%) sepia(100%);
}
Nếu một trong số các filter ko được hỗ trợ, thì nó nhẹ nhàng cho qua, chứ ko bỏ hết thuộc tính filter. Nếu bạn dùng photoshop rồi, cũng hiểu là thứ tự áp dụng các filter sẽ ảnh hưởng đến kết quả cuối cùng.
Để sử dụng hue-rotate
chúng ta phải dùng một ảnh SVG có màu, lẽ nào bạn dùng ảnh gốc trắng đen rồi css đổ màu vào được?
Trước hết phải invert()
cái hình xuống, chuyển thành dạng medium grey
.icon:hover {
filter: invert(0.5)
}
Sau đó mới dùng sepia()
.icon:hover {
filter: invert(0.5) sepia(1);
}
Tiếp đến là thêm màu sắc mình yêu thích
.icon:hover {
filter: invert(0.5) sepia(1) hue-rotate(200deg);
}
Tinh chỉnh một chút nữa
.icon:hover {
filter:
invert(0.5)
sepia(1)
hue-rotate(200deg)
saturate(4)
brightness(1);
}
Để dễ hình dung hơn, dùng tool này của tác giả, kéo thả thấy kết quả
Tuy nhiên đây cũng chỉ cho được kết quả là một màu tương đối, không chỉ định một màu cụ thể được
SVG filters
Nếu cần hỗ trợ nhiều trình duyệt hơn, màu sắc cụ thể hơn, dùng đến SVG
Không giống với CSS, chúng ta phải đổ mồ hôi sôi nước miếng mới làm được
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
<defs>
<filter id="id-of-your-filter">
...
...
</filter>
...
</defs>
</svg>
Chúng ta định nghĩa bằng thẻ <filter />
, thẻ này phải nằm trong thẻ <defs/>
Trong CSS chúng ta trỏ đến thằng filter ở trên như sau
.icon:hover {
filter: url('assets/your-SVG.svg#id-of-your-filter');
}
Những filter có thể sử dụng
<feBlend>
<feColorMatrix>
<feComponentTransfer>
<feComposite>
<feConvolveMatrix>
<feDiffuseLighting>
<feDisplacementMap>
<feDropShadow>
<feFlood>
<feGaussianBlur>
<feImage>
<feMerge>
<feMorphology>
<feOffset>
<feSpecularLighting>
<feTile>
<feTurbulence>
Với yêu cầu đổi màu, chúng ta sẽ dùng feColorMatrix
<svg xmlns="<http://www.w3.org/2000/svg>" version="1.1">
<defs>
<filter id="id-of-your-filter">
<feColorMatrix
color-interpolation-filters="sRGB"
type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0 "/>
</filter>
...
</defs>
</svg>
Cùng xem xét kỹ hơn giá trị matrix chúng ta đã sử dụng ở trên
Các cột giá trị tương ứng là red, green, blue, alpha và multiplier. Chúng ta sẽ ko quan tâm đến giá trị multiplier với nhu cầu đổi màu, chỉ cần 4 giá trị ở đầu.
Ví dụ chúng ta muốn set giá trị rgba(0,128,128,1), chuyển nó về giá trị ma trận theo cách tính
Lưu ý: SVG filter không thực hiện được trên hình nền đen, nên nếu đang là hình đen thì invert nó thành trắng trước khi thực hiện
.icon:hover {
filter: invert(100%) url('assets/your-SVG.svg#id-of-your-filter');
}
Tiếp tục sử dụng công cụ kéo thả thấy kết quả của tác giả nếu bạn ko siêng làm toán mẫu giáo
The Many Ways to Change an SVG Fill on Hover (and When to Use Them)
Bài viết gốc được đăng tải tại vuilaptrinh.com
Có thể bạn quan tâm:
- Làm thế nào để sử dụng SVG như một Placeholder, và các phương pháp Image Loading khác
- SVG là gì? Tại sao nên dùng SVG để tăng tốc cho web
- Những thay đổi trong Python 3.9 mới nhất
Xem thêm các việc làm lập trình viên hấp dẫn tại TopDev