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
<svg xmlns="http://www.w3.org/2000/svg">
<style>use:not(:target) {display: none}</style>
<symbol id="circle-def" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="10" fill="red" />
</symbol>
<symbol id="square-def" viewBox="0 0 50 50">
<path d="M 10 10 v 30 h 30 v -30 Z" stroke="blue" fill="none" />
</symbol>
<use href="#circle-def" id="circle" />
<use href="#square-def" id="square" />
</svg>

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