Skip to content

Instantly share code, notes, and snippets.

@ondras
Last active January 21, 2026 09:31
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>
li {
display: flex;
align-items: center;
gap: 8px;
}
[data-icon]::before {
content: "";
width: 30px;
height: 30px;
}
[data-color=original] {
[data-icon=circle]::before { background-image: url(library.svg#circle); }
[data-icon=square]::before { background-image: url(library.svg#square); }
}
[data-color=lime] {
[data-icon]::before { background-color: lime; }
[data-icon=circle]::before { mask-image: url(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="8" 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" stroke-width="5" />
</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 background image library.svg#my-id to retain icon color
  • Use via mask-image to override color (specify color as background-color

Preview

https://gistcdn.githack.com/ondras/20393a5fc73293d8e01164325851dc79/raw/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment