Icon
<cs-icon>
Icons are scalable vector symbols that represent actions, content, or status throughout your application. They support Material Symbols and custom icon libraries with animation presets.
Cornerstone comes bundled with over 3,800 free icons courtesy of Material Symbols, which are licensed under Apache-2.0. These icons are part of the default icon library, and every one of them is drawn along three axes — style, variant and weight. Brand logos live in a separate brands library, and you can always register your own custom icon library.
Examples
Size
Icons are sized relative to the current font size. To change their size, set the font-size property on the icon itself or on a parent element — drag the slider to see it in action.
Color
Icons inherit their color from the current text color. Thus, you can set the color property on the <cs-icon> element or an ancestor to change the color.
Style, Variant & Weight
Material Symbols is a single typeface drawn along three independent axes, and <cs-icon> exposes each one as an attribute. Any combination of the three resolves.
| Axis | Attribute | Values | Preview |
|---|---|---|---|
| Style | family |
sharp outlined, rounded |
|
| Cut | variant |
regular fill |
|
| Weight | weight |
100–700 in steps of 100 (400 |
|
A weight between two steps snaps to the nearer one, and a weight outside the range clamps to the closest end — weight="350" resolves to 300, and weight="9000" to 700.
The defaults — sharp, regular (fill off) and weight 400 — are the artwork Cru’s brand guidelines specify, alongside grade 0 and optical size 24, which is what the @material-symbols/svg-400/sharp set ships.
Optical Size
Material Symbols draws every icon inside a 24dp box with a 20dp live area, so 4dp of padding is baked into the artwork. <cs-icon> cancels that with --icon-scale, which defaults to 1.2 (24 ÷ 20). It scales the artwork inside the canvas without changing the canvas, so raising it never reflows the layout around an icon.
Set it to 1 to render the artwork at its native size. The property inherits, so setting it on an ancestor retunes every icon beneath it. Note that Material Symbols varies the ink deliberately — a chevron is drawn smaller within its box than a gear is — so --icon-scale shifts every icon together rather than evening them out.
Brand Logos
Material Symbols ships no brand marks, so Cornerstone includes a small brands library of logos from Simple Icons, which are published under CC0-1.0. They’re inlined in the bundle, so they resolve with no network request. family, variant and weight don’t apply to them.
Need a logo that isn’t here?
The library covers the marks Cornerstone’s own documentation uses. Paste any other Simple Icons SVG into a
custom library, or point one at their CDN.
Canvas
The canvas is the box an icon sits in. Choose one of four mutually exclusive modes with the canvas attribute (the default is fixed). It follows the same idea as Font Awesome’s icon canvas, which these modes were ported from, and scales with font-size, independent of sizing. The tinted box below shows each canvas’s extent.
| Canvas | Box | Best For | Example |
|---|---|---|---|
fixed
|
1.25 × 1em |
Aligning icons in lists, menus, and toolbars |
|
auto |
auto × 1em |
Matching the icon's natural width |
|
square |
1.25 × 1.25em |
Standalone icons on a square footprint |
|
roomy |
1.5 × 1.5em |
Standalone icons that need more breathing room |
|
The auto-width attribute still works but is deprecated — prefer canvas="auto", which renders the same way.
Rotating & Flipping
Cornerstone ports Font Awesome’s rotation and flip utilities for adjusting icon orientation. Use the rotate attribute to turn an icon by any number of degrees — not just the quarter-turns below — and the flip attribute to mirror it across the x, y, or both axes.
| Attribute | Value | Preview |
|---|---|---|
rotate |
90 |
|
rotate |
180 |
|
rotate |
270 |
|
flip |
x |
|
flip |
y |
|
flip |
both |
|
Rotate by any angle — and combine rotate and flip on the same icon:
Animating
Cornerstone ports Font Awesome’s animation utilities for adding visual interest to icons. To select different types of animations, use the animation attribute when you reference an icon.
Every animation accepts the same timing controls — --animation-delay, --animation-direction, --animation-duration, --animation-iteration-count, and --animation-timing — plus the animation-specific custom properties shown in each example below. All animations respect prefers-reduced-motion (see Accessibility Considerations).
Beat
Use the beat animation to scale an icon up or down. This is useful for grabbing attention or for use with health/heart-centric icons.
Fade
Use the fade animation to fade an icon in and out visually to grab attention in a subtle (or not so subtle) way.
Beat-Fade
Use the beat-fade animation to grab attention by visually scaling and pulsing an icon in and out.
Bounce
Use the bounce animation to grab attention by visually bouncing an icon up and down.
Flip
Use the flip animation to rotate an icon in 3D space. By default, flip rotates an icon about the Y axis 180 degrees. Flipping is helpful for transitions, processing states, or for using physical objects that one flips in the real world.
Flip 360
Use the flip-360 animation to flip an icon all the way around in one smooth rotation — an extension of flip that gives it some extra oomph. It shares the same --flip-x, --flip-y, and --flip-z axis properties, plus --flip-angle, --flip-anticipation-scale, and --flip-overshoot.
Shake
Use the shake animation to grab attention or note that something is not allowed by shaking an icon back and forth.
Spin
Use the spin animation to get any icon to rotate, and use spin-pulse to have it rotate with eight steps. Use spin-reverse to rotate counter-clockwise. This works especially well with spinner and everything in the spinner icons category.
Spin Snap
Use spin-snap to rotate in distinct steps with a pause on each, like a clock’s second hand. spin-snap-4 stops at four positions and spin-snap-8 at eight. Unlike spin-pulse — a continuous eight-step rotation — the snap animations ease into each stop. Add --animation-direction: reverse to any of them to run counter-clockwise.
Buzz
Use the buzz animation for a fast, tight vibration with rapid decay — quick attention without being loud, like a phone buzzing on a table or an expiring timer. Set --buzz-distance to control how far it travels.
Float
Use the float animation for a slow, drifting motion — great for empty states, subtle attention, and adding a bit of playful lightness. Adjust --float-height, --float-drift, and --float-tilt to shape the motion.
Jello
Use the jello animation for a playful jiggle — great for calling attention to something new, fun, or interactive. Set --jello-scale-x and --jello-scale-y to control how far it deforms.
Swing
Use the swing animation for a subtle dangle with a slow decay — great for things that physically dangle, like keys or a price tag. Set --swing-angle to control the peak rotation.
Wag
Use the wag animation, a cousin of swing, for a bottom-anchored wag — the top of the icon sways back and forth with a slow decay. Set --wag-angle to control the peak rotation.
Custom Icons
Custom icons can be loaded individually with the src attribute. Only SVGs on a local or CORS-enabled endpoint are supported. If you’re using more than one custom icon, it might make sense to register a custom icon library.
Icon Libraries
An icon library is a named set of icons with a resolver that maps each name to an SVG URL. Cornerstone ships with three built-in libraries and lets you register any number of your own.
| Library | Contains | Resolves from | Customize it to… |
|---|---|---|---|
default | 3,800+ Material Symbols icons, shown when <cs-icon> has no library attribute | The Material Symbols CDN | Self-host the icons or swap in a different set |
system | Only the icons Cornerstone components use internally | Data URIs baked into the resolver | Replace the icons components use internally (you supply them all) |
brands | The brand logos Material Symbols doesn’t cover | Data URIs baked into the resolver | Add logos of your own |
sizing, color, the canvas, rotating and flipping, and animations work with icons from any library — they’re applied to the <cs-icon> host, so they don’t depend on where the icon comes from.
Customizing the Default Library
To resolve the default icons elsewhere (a different set, or your own server), register a library using the default name and a custom resolver.
For example, this will change the default icon library to use Bootstrap Icons loaded from the jsDelivr CDN.
<script type="module"> import { registerIconLibrary } from '/dist/cornerstone.js'; registerIconLibrary('default', { resolver: (name, family) => { const suffix = family === 'filled' ? '-fill' : ''; return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/icons/${name}${suffix}.svg`; }, }); </script>
Self-Hosting
By default, icons are loaded from the Material Symbols CDN. If you’d prefer to serve them from your own server, install the weights you need and use setIconPath() to point the default icon library at your self-hosted directory.
The expected layout mirrors the @material-symbols/svg-{weight} packages, nested one level deeper by weight — so copying node_modules/@material-symbols/svg-400 to assets/icons/400 is all it takes to serve weight 400.
npm install @material-symbols/svg-400 cp -R node_modules/@material-symbols/svg-400 public/assets/icons/400
<script type="module"> import { setIconPath } from '/dist/cornerstone.js'; setIconPath('/assets/icons'); </script>
After calling setIconPath(), icons resolve from your directory instead of the CDN. <cs-icon name="home"> loads /assets/icons/400/sharp/home.svg, and <cs-icon name="star" variant="fill" weight="700"> loads /assets/icons/700/sharp/star-fill.svg.
For more control over how icon URLs are constructed, use the getIconStyle(), getIconWeight() and getIconFileName() helpers with registerIconLibrary(). They apply the same style, weight-snapping and -fill suffix rules the default library uses, so you don’t have to replicate that logic yourself.
<script type="module"> import { getIconFileName, getIconStyle, getIconWeight, registerIconLibrary } from '/dist/cornerstone.js'; registerIconLibrary('default', { resolver: (name, family, variant, autoWidth, weight) => { const style = getIconStyle(family); const file = getIconFileName(name, variant); return `/assets/icons/${getIconWeight(weight)}/${style}/${file}.svg?v=2`; }, }); </script>
Call setIconPath() before Cornerstone components load.
Like setBasePath(), it has no effect once components have initialized.
SVG Sprites
To improve performance you can use a SVG sprites to avoid multiple trips for each SVG. The browser will load the sprite sheet once and then you reference the particular SVG within the sprite sheet using hash selector.
As always, make sure to benchmark these changes. When using HTTP/2, it may in fact be more bandwidth-friendly to use multiple small requests instead of 1 large sprite sheet.
Only use sprite sheets you self-host.
Browsers apply the same-origin policy to the <use> elements inside <cs-icon>’s shadow DOM and may refuse a cross-origin URL, with no way to override it. cs-load and cs-error also don’t fire for sprite-sheet icons.
<script type="module"> import { registerIconLibrary } from '/dist/cornerstone.js'; registerIconLibrary('sprite', { resolver: name => `/assets/images/sprite.svg#${name}`, mutator: svg => svg.setAttribute('fill', 'currentColor'), spriteSheet: true, }); </script>
Customizing the System Library
To change the icons Cornerstone uses internally, register a library using the system name and a custom resolver. You’re then responsible for providing every icon components require. See src/components/icon/library.system.ts for the full list.
<script type="module"> import { registerIconLibrary } from '/dist/cornerstone.js'; registerIconLibrary('system', { resolver: name => `/path/to/custom/icons/${name}.svg`, }); </script>
Third-Party Icon Libraries
Register any number of additional libraries with the registerIconLibrary() function exported from dist/cornerstone.js. Provide a name and a resolver that maps an icon name to its SVG URL (local or a CORS-enabled CDN). Icons are fetched only when used, so a registered library you don’t touch costs nothing.
Some libraries need a mutator to adjust each SVG on load, most often setting fill or stroke to currentColor so icons inherit the text color.
<script type="module"> import { registerIconLibrary } from '/dist/cornerstone.js'; registerIconLibrary('my-icons', { resolver: (name, family, variant) => `/assets/icons/${name}.svg`, mutator: svg => svg.setAttribute('fill', 'currentColor'), }); </script>
Then reference an icon by its library and name. (An icon used before its library registers stays blank until it does.)
<!-- This will show the icon located at /assets/icons/smile.svg --> <cs-icon library="my-icons" name="smile"></cs-icon>
The examples below register popular open-source libraries via CDN. Adapt them to your own origin or naming.
Bootstrap Icons
This will register the Bootstrap Icons library using the jsDelivr CDN. This library has two families: regular and filled.
Icons in this library are licensed under the MIT License.
Boxicons
This will register the Boxicons library using the jsDelivr CDN. This library has three variations: regular (bx-*), solid (bxs-*), and logos (bxl-*). A mutator function is required to set the SVG’s fill to currentColor.
Icons in this library are licensed under the Creative Commons 4.0 License.
Lucide
This will register the Lucide icon library using the jsDelivr CDN. This project is a community-maintained fork of the popular Feather icon library.
Icons in this library are licensed under the MIT License.
Heroicons
This will register the Heroicons library using the jsDelivr CDN.
Icons in this library are licensed under the MIT License.
Iconoir
This will register the Iconoir library using the jsDelivr CDN.
Icons in this library are licensed under the MIT License.
Ionicons
This will register the Ionicons library using the jsDelivr CDN. This library has three variations: outline (default), filled (*-filled), and sharp (*-sharp). A mutator function is required to polyfill a handful of styles we’re not including.
Icons in this library are licensed under the MIT License.
Jam Icons
This will register the Jam Icons library using the jsDelivr CDN. This library has two variations: regular (default) and filled (*-f). A mutator function is required to set the SVG’s fill to currentColor.
Icons in this library are licensed under the MIT License.
Material Icons
Material Icons is Google’s earlier icon set, and is not the same as the Material Symbols that back Cornerstone’s default library — register it only if you specifically want the older glyphs. This will register it using the jsDelivr CDN. This library has three variations: outline (default), round (*_round), and sharp (*_sharp). A mutator function is required to set the SVG’s fill to currentColor.
Icons in this library are licensed under the Apache 2.0 License.
Remix Icon
This will register the Remix Icon library using the jsDelivr CDN. This library groups icons by categories, so the name must include the category and icon separated by a slash, as well as the -line or -fill suffix as needed. A mutator function is required to set the SVG’s fill to currentColor.
Icons in this library are licensed under the Apache 2.0 License.
Tabler Icons
This will register the Tabler Icons library using the jsDelivr CDN. This library features over 1,950 open source icons.
Icons in this library are licensed under the MIT License.
Unicons
This will register the Unicons library using the jsDelivr CDN. This library has two variations: line (default) and solid (*-s). A mutator function is required to set the SVG’s fill to currentColor.
Icons in this library are licensed under the Apache 2.0 License. Some of the icons that appear on the Unicons website, particularly many of the solid variations, require a license and are therefore not available in the CDN.
Accessibility Considerations
Cornerstone hides an unlabeled <cs-icon> from assistive devices, so an icon is presentational unless you give it a name. The two things to get right are labeling icons that carry meaning and respecting users who prefer less motion.
Labeling Icons
Give an icon a label when it carries meaning on its own — when it’s the only content of a control, or conveys status. Omit it when nearby text already says the same; unlabeled icons are hidden from assistive devices.
| Scenario | Label? | In Context | Why |
|---|---|---|---|
| Icon-only control | Yes |
|
The icon is the button's only content, so the label gives it an accessible name. |
| Status icon | Yes |
|
The icon conveys status the nearby text doesn't. |
| Icon beside its own text | No |
|
The visible “Share” text already names the action; a label would be announced twice. |
| Decorative | No |
|
It only decorates text that already carries the meaning. |
Set the label attribute to the text a screen reader should announce:
Reduced Motion
All icon animations honor the user’s prefers-reduced-motion setting — when it’s set to reduce, Cornerstone disables them automatically so motion never becomes a barrier. See Font Awesome’s animation accessibility notes for more.
API
Importing
If you're using the autoloader or a hosted project, components load on demand — no manual import needed. To cherry-pick this component, use one of the following snippets.
import '@cruglobal/cornerstone-components/components/icon/icon.js';
import './cornerstone/components/icon/icon.js';
import CsIcon from '@cruglobal/cornerstone-components/react/icon/index.js';
Attributes & Properties
Learn more about attributes and properties.
| Property | Attribute | Description | Type | Default | Reflects |
|---|---|---|---|---|---|
animation | animation | Sets the animation for the icon | IconAnimation | undefined | — | Yes |
autoWidth | auto-width | Sets the width of the icon to match the cropped SVG viewBox. | boolean | false | Yes |
canvas | canvas | Sets the icon canvas — the box the icon is centered within. Unset renders as fixed (1.25em × 1em); auto hugs the icon's width; square is 1.25em × 1.25em; roomy is 1.5em × 1.5em. Scales with font-size. | IconCanvas | undefined | — | Yes |
family | family | The family of icons to choose from. For Material Symbols, this selects the style — valid options are sharp (the default), outlined, and rounded. Custom icon libraries may or may not use this property. | string | — | Yes |
flip | flip | Sets the flip direction of the icon along the 'x' (horizontal), 'y' (vertical), or 'both' axes. | 'x' | 'y' | 'both' | undefined | — | Yes |
label | label | An alternate description to use for assistive devices. If omitted, the icon will be considered presentational and ignored by assistive devices. | string | '' | — |
library | library | The name of a registered custom icon library. | string | 'default' | Yes |
name | name | The name of the icon to draw. Available names depend on the icon library being used. | string | undefined | — | Yes |
rotate | rotate | Sets the rotation degree of the icon | number | 0 | Yes |
src | src | An external URL of an SVG file. Be sure you trust the content you are including, as it will be executed as code and can result in XSS attacks. | string | undefined | — | — |
variant | variant | The name of the icon's variant. For Material Symbols, valid options are regular (the default), which draws the outlined cut, and fill, which draws the filled cut. Custom icon libraries may or may not use this property. | string | — | Yes |
weight | weight | The stroke weight of the icon. Material Symbols publishes seven weights from 100 to 700 in steps of 100; values in between snap to the nearest one. Defaults to 400, which is the weight Cru's brand guidelines specify. Custom icon libraries may or may not use this property. | number | 400 | Yes |
Events
Learn more about events.
| Name | Description |
|---|---|
cs-error | Emitted when the icon fails to load due to an error. When using spriteSheet: true this will not emit. |
cs-load | Emitted when the icon has loaded. When using spriteSheet: true this will not emit. |
CSS Custom Properties
Learn more about CSS custom properties.
| Name | Description | Default |
|---|---|---|
--animation-delay | Sets when the animation will start. | 0 |
--animation-direction | Defines whether or not the animation should play in reverse on alternate cycles. | normal |
--animation-duration | Defines the length of time that an animation takes to complete one cycle. | 1s |
--animation-iteration-count | Defines the number of times an animation cycle is played. | infinite |
--animation-timing | Describes how the animation will progress over one cycle of its duration. | — |
--beat-fade-opacity | Set lowest opacity value an icon with beat-fade animation will fade to and from. | — |
--beat-fade-scale | Set max value that an icon with beat-fade animation will scale. | — |
--beat-scale | Set the scale multiplier for an icon with beat animation. This multiplies the animation's 1.25× base pulse, so the default 1.25 peaks at ~1.56× and 2 roughly doubles the pulse. | — |
--bounce-anticipation | Set the downward squash distance before an icon with bounce animation jumps. | — |
--bounce-height | Set the max height an icon with bounce animation will jump to when bouncing. | — |
--bounce-jump-scale-x | Set the icon’s horizontal distortion (“squish”) at the top of the jump. | — |
--bounce-jump-scale-y | Set the icon’s vertical distortion (“squish”) at the top of the jump. | — |
--bounce-land-scale-x | Set the icon’s horizontal distortion (“squish”) when landing after the jump. | — |
--bounce-land-scale-y | Set the icon’s vertical distortion (“squish”) when landing after the jump. | — |
--bounce-rebound | Set the amount of rebound an icon with bounce animation has when landing after the jump. | — |
--bounce-start-scale-x | Set the icon’s horizontal distortion (“squish”) when starting to bounce. | — |
--bounce-start-scale-y | Set the icon’s vertical distortion (“squish”) when starting to bounce. | — |
--buzz-distance | Set the horizontal travel of an icon with buzz animation. | — |
--fade-opacity | Set lowest opacity value an icon with fade animation will fade to and from. | — |
--flip-angle | Set rotation angle of flip for an icon with flip or flip-360 animation. A positive angle denotes a clockwise rotation, a negative angle a counter-clockwise one. | — |
--flip-anticipation-scale | Set the scale of the wind-up before an icon with flip or flip-360 animation rotates. | — |
--flip-overshoot | Set how far past the final angle an icon with flip or flip-360 animation rotates before settling. | — |
--flip-x | Set x-coordinate of the vector denoting the axis of rotation (between 0 and 1) for an icon with flip or flip-360 animation. | — |
--flip-y | Set y-coordinate of the vector denoting the axis of rotation (between 0 and 1) for an icon with flip or flip-360 animation. | — |
--flip-z | Set z-coordinate of the vector denoting the axis of rotation (between 0 and 1) for an icon with flip or flip-360 animation. | — |
--float-drift | Set the horizontal drift of an icon with float animation. | — |
--float-height | Set the rise height of an icon with float animation. | — |
--float-squash-x | Set the horizontal squash of an icon with float animation at rest. | — |
--float-squash-y | Set the vertical squash of an icon with float animation at rest. | — |
--float-stretch-x | Set the horizontal stretch of an icon with float animation at its peak. | — |
--float-stretch-y | Set the vertical stretch of an icon with float animation at its peak. | — |
--float-tilt | Set the rotation of an icon with float animation. | — |
--icon-scale | Scales the icon artwork within its canvas without changing the canvas itself. Material Symbols pads each icon into a 24dp box with a 20dp live area; the default of 1.2 (24 / 20) cancels that padding. Set it to 1 to render the artwork at its native size. It inherits, so it can be set on any ancestor. | 1.2 |
--jello-scale-x | Set the horizontal stretch of an icon with jello animation. | — |
--jello-scale-y | Set the vertical stretch of an icon with jello animation. | — |
--swing-angle | Set the peak rotation of an icon with swing animation. | — |
--wag-angle | Set the peak rotation of an icon with wag animation. | — |
CSS Parts
Learn more about CSS parts.
| Name | Description | CSS selector |
|---|---|---|
svg | The internal SVG element. | ::part(svg) |
use | The <use> element generated when using spriteSheet: true | ::part(use) |

