building a svg icon system

@eehayman

Why SVG?

  • Rendering
  • Control
  • Sizing
  • Accessibility
  • Ease of Use

OK... but how?

background images

 direct images (<img>)

The Sprite Bit

<svg class="svg-sprite">
    <defs>
        <symbol id="logo" viewBox="0 0 336 335">
            <path d="c 50,0 50,100 100,100 50,0 50,-100 100,-100"/>
        </symbol>
    </defs>
</svg>
  • Each icon defined in a <symbol>
  • viewBox information required

then.... AJAX and Inject!

actually using it

<svg>
    <use xlink:href="#logo"></use>
</svg>

"xlink:href" value corresponds to icon's symbol ID in the sprite

but what about react?

As of v.14, xlink:href is available in JSX!

<svg>
  <use xlinkHref='#logo' />
</svg>

No more dangerouslySetInnerHTML!

We can do better!

make the icon... A component

flexible

reusable

dynamic

the nitty-gritty

  • "Dumb" component (no lifecycle methods!)
  • Written as a simple function
function IconLogo() {
  return (
    <svg className="logo" viewBox="0 0 336 335">
      <path d="c 50,0 50,100 100,100 50,0 50,-100 100,-100"/>
    </svg>
  )
}
render() {
   return (
      <IconLogo />
   );
}

leverage those props

function IconLogo(props) {
  const iconFill = props.iconFill || 'red';
  return (
    <svg className="logo" viewBox="0 0 336 335">
      <path fill={iconFill} d="c 50,0 50,100 100,100 50,0 50,-100 100,-100"/>
    </svg>
  )
}

We can now dynamically update SVG properties based on their relative context.

Accessibility

function IconLogo(props) {
  const iconTitle = props.iconTitle;
  return (
    <svg className="logo" viewBox="0 0 336 335" aria-labelledby={iconTitle}>
      <title>{iconTitle}</title>
      <path d="c 50,0 50,100 100,100 50,0 50,-100 100,-100"/>
    </svg>
  )
}

The title should contain relevant, specific text to indicate the meaning of the icon.

the world is your oyster!

  • Stroke
  • Width
  • Fill
  • Animations

Questions?

Building a SVG Icon System with React

By ehayman

Building a SVG Icon System with React

  • 3,174