Skip to content

Instantly share code, notes, and snippets.

@ondras
Last active November 6, 2025 08:17
Show Gist options
  • Select an option

  • Save ondras/20393a5fc73293d8e01164325851dc79 to your computer and use it in GitHub Desktop.

Select an option

Save ondras/20393a5fc73293d8e01164325851dc79 to your computer and use it in GitHub Desktop.
Themeable CSS-only icons
<!doctype html>
<html>
<head>
<style>
[data-color=lime] {
[data-icon]::before {
content: "";
width: 30px;
height: 30px;
background-color: lime;
mask-size: 30px;
}
[data-icon=circle]::before { mask-image: url(?20393a5fc73293d8e01164325851dc79/library.svg#circle); }
[data-icon=square]::before { mask-image: url(library.svg#square); }
}
</style>
</head>
<body>
<h2>Original colors</h2>
<ul data-color="original">
<li data-icon="circle">Item with circle icon</li>
<li data-icon="square">Item with square icon</li>
</ul>
<h2>Lime colors</h2>
<ul data-color="lime">
<li data-icon="circle">Item with circle icon</li>
<li data-icon="square">Item with square icon</li>
</ul>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Requirements

  1. adding without additional markup
  2. css-based styling
  3. reduce amount of http requests
  4. per-icon viewBox

Solution

  • SVG library file with:
    • Icons in <symbol> elements (with individual viewBoxes)
    • Referenced via <use>
    • <use> nodes with public IDs
    • Only one visible via :not(:target) CSS-in-SVG styling
  • Use via library.svg#my-id to retain icon color
  • Use via mask-image to override color:
    1. specify color as background-color
    2. specify size via mask-size

Alteranative approaches

  • SVG <mask> -- does not support setting mask-size
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment