跪拜 Guibai
← All articles
Frontend

Recoloring External SVGs in Mini-Programs with a Drop-Shadow Silhouette

By 陆枫Larry ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Mini-program teams chasing every kilobyte of main-package budget can replace heavy iconfonts with lightweight external SVGs without losing the ability to theme icons via CSS. The approach is a pure CSS workaround that avoids generating multiple color variants of the same SVG asset.

Summary

Mini-program iconfont bundles waste package space because the entire glyph set is packed, base64 inlining inflates size by roughly 33%, and tree-shaking cannot prune unused glyphs. Swapping to on-demand external SVGs solves the size problem but breaks CSS recoloring: `<image>` is a native replaced element, so `color` never reaches the SVG interior. The workaround hides the real image above a clipped container and uses `filter: drop-shadow(0 H 0 currentColor)` to project a solid silhouette back into the visible area. The silhouette inherits `currentColor`, restoring full CSS color control. The technique works for single-color icons, requires matching translate and shadow offsets, and demands real-device testing for filter support. Click targets must live on the outer container because the visible icon is a rendering effect, not a DOM node.

Takeaways
An iconfont bundles every glyph in the set; using 5 of 200 icons still ships all 200, and base64 inlining adds roughly 33% overhead.
Loading SVGs via `<image>` in mini-programs prevents CSS `color` from reaching the graphic because the native component renders a bitmap with no internal cascade.
Setting `overflow: hidden` on a container and pushing the `<image>` up with `translateY(-H)` hides the original icon.
Applying `filter: drop-shadow(0 H 0 currentColor)` projects a solid silhouette downward by the same height `H`, landing it exactly in the visible area.
The visible icon is the drop-shadow, not the `<image>` element itself, so click handlers must be bound to the outer container.
Rotation animations stay on the outer container while `translateY` stays on the inner image to avoid `transform` property conflicts.
The method only produces a single solid color; multi-color icons collapse to one hue.
Real-device testing is mandatory because `filter: drop-shadow` support varies across mini-program base library versions.
Conclusions

The technique decouples shape from color by treating the SVG purely as an alpha mask and letting CSS paint the visible result—a pattern that echoes shader-based rendering in a CSS property.

Mini-program architecture forces a workaround that would be unnecessary in a browser with inline SVG support, highlighting how platform constraints can resurrect clever CSS hacks that the web community largely retired.

The base64 size penalty (33% larger than raw binary) is often overlooked in iconfont discussions, yet it compounds when the same CSS is duplicated across sub-packages.

Concepts & terms
Replaced element
An HTML/CSS element whose rendering is determined by an external resource rather than CSS. `<img>`, `<video>`, and mini-program `<image>` are replaced elements; CSS properties like `color` cannot penetrate their internal rendering.
currentColor
A CSS keyword that resolves to the computed value of the `color` property on the same element. It allows SVG `fill` or `stroke` attributes, and CSS filter functions like `drop-shadow`, to inherit the text color dynamically.
drop-shadow() filter
A CSS filter function that generates a shadow matching the alpha channel shape of the input image, unlike `box-shadow` which follows the element's box edges. It can accept a color argument, including `currentColor`.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗