Icons

Communicates meaning through the use of graphics

# Overview

# Inline Icon Components

The inline icon components are the recommended method for using Cedar icons in a Vue application. Cedar exports a component version of every SVG Icon in the Cedar Icon Library. These components are named using PascalCase, for example account-profile becomes IconAccountProfile or camping becomes IconCamping.

# SVG Sprite

A collection of SVG icon files composed into a single file. This method provides a single server download request and caches icons for display. This is the most efficient way of displaying large numbers of icons, but has an added maintenance cost in that every icon used in the application must be manually added to it's sprite sheet. We recommend using the inline icon components, and optimizing to use a sprite only if it would provide a measurable performance benefit.

See the Cedar Icon Library to generate a sprite sheet for your project. You will need to ensure that your sprite contains all the Cedar icons used in your application, including those used in shared components. The generated sprite sheet should be rendered inline at the root of your HTML. You should avoid rendering the sprite sheet in JavaScript/Vue, as that will cause it to be included twice (once in the server rendered HTML, and once in the client side bundle).

# Non-Cedar SVG

Create a new SVG icon using any valid SVG markup. The wrapping SVG element can be stripped (below) or maintained. Note that if it is not stripped, then viewBox, role, and xmlns attributes will not be preserved. Whereas, all other attributes will be preserved. This method creates an outer SVG wrapper for accessibility and styles. This is not recommended if using a large number of icons.

# Accessibility

To ensure that usage of this component complies with accessibility guidelines:

  • If an icon conveys meaning, there must be an aria-label that describes the action or idea that the icon represents
  • If an icon is decorative, use an empty alt attribute

Recommendations for writing screen reader text:

  • Be succinct. Exclude unnecessary words
  • Be informative and accurate
  • Write in the active voice
  • Avoid technical jargon

W3C recommends using <title> and <desc> elements in SVG for assistive technologies; however these elements have mixed support for screen readers as explained here. Cedar follows these recommendations by:

  • Adding role=’presentation’ to icons. This hides them from screen readers and causes the icon to be a nested image inside of a button or a link
  • Assigning the attribute focusable=’false’ to the SVG element
  • Using aria-label for buttons or Cedar’s hidden text CSS style for links

# Guidelines

# Use When

  • Communicating simple actions and concepts that are easily understood, such as printing a receipt or sending an email
  • Making navigation easier for common actions, such as return to home page or search
  • Representing an action, object, or concept at a high level of abstraction, such as using the snowflake icon to represent snow sports
  • Notifying users about status, such as the number of items in a shopping cart or a warning message
  • Conserving space for concepts that are difficult to depict, such as the progress icon or the 3-line “hamburger” menu

# The Basics

# Sizes

Icons are available in three sizes: small (16px), medium (24px), and large (32px). Default size is medium (24px); however, designers can choose a different size.

Cedar icon sizes

# Color

Ensure that icons use the ratio of 4.5:1 contrast between icon color and background color. Follow recommendations in the Color article for pairing light and dark color tokens.

Cedar icon color options

# Clearance

Adequate space around the icon allows for legibility and touch. A minimum touch target area of 40px is recommended for standalone iconography.

When the mouse and keyboard are the primary input methods or when icons are paired inline with text, measurements may be condensed to accommodate denser layouts. Icon size should align to the line-height of the paired text element.

Cedar icon clearance

# Icon Library

For a list of all available icons and their names, see the Icon Library.

# Behavior

When using icons with links or buttons, ensure that the icon communicates intended meaning.

box icon by text which reads use 'this item ships free'
Do use the appropriate icon.
box icon by text which reads 'write a review'
Don't change the meaning or intention of the Cedar icons.

Ensure that icons are sized to provide a minimum click or touch target.

icons with sufficient padding
Do provide at least 40 pixel target area.
icons with too little padding
Don't make click or touch target too small.

Ensure that icons use contrast ratio of 4.5:1 between icon color and background color.

icons with sufficient contrast
Do use primary color tokens for icon color.
icons with too little contrast
Don't create new color tokens for icons or use secondary color tokens.

# API

# Props

use

name

string

type

none

default

Only on CdrIcon. Sets the href attribute for use with SVG symbol sprite (see @rei/cedar-icons).

size

name

string

type

medium

default

Modifies the icon size; values can target responsive breakpoints. Breakpoint values are: xs, sm, md, and lg. Examples: { 'small' | 'medium' | 'large' | 'large@sm' }

inherit-color

name

boolean

type

false

default

Sets icon fill color to 'inherit'.

# Slots

Find more information about using Slots in the article Getting Started as a Developer.

default

name

Sets the innerHTML of SVG element. This includes <title>, <desc>, or any other valid SVG xml.

# Usage

For a list of all available icons and their names, see the Icon Library.

There are 2 different options to display SVG icons on your page using the CdrIcon package.

# 1. SVG Sprite

Requires:

  • Icon sprite inline on page

Icon sprites can be generated using the Cedar Icon Library.

The sprite needs to be available on any page where the icons are being used. Add the sprite component at the base layout or index:

App.vue (base template)

<template>
  <div id="main">
    <div v-html="iconSprite" style="display: none;" />

    <router-view></router-view> // rest of app
  </div>
</template>

<script>
/* NOTE: you should create your own optimized sprite file for your project, `all-icons.svg` is only used here for convenience */
import { iconSprite } from '@rei/cedar-icons/dist/all-icons.svg';

...
data() {
  return {
    iconSprite
  }
}
...
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Child.vue (any descendant component of App.vue above)

<template>
  <div>
    <cdr-icon use="#caret-right" />
  </div>
</template>

<script>
import { CdrIcon } from '@rei/cedar';

...
components: {
  CdrIcon
}
...
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2. Non-Cedar SVG

The CdrIcon package is simply an SVG with default attributes set for accessibility and styling.

  • Any SVG markup can be used
  • All attributes, event listeners, classes, etc. will be carried over with the exception of viewBox, role, and xmlns
  • This method will increase HTML file size and slow down performance if using a lot of icons.

Requires:

  • None

Use any valid SVG markup in the CdrIcon slot.

The svg element in this example will be stripped, but the class and data atrribute will be preserved (and could be moved to cdr-icon also).

<template>
  ...
  <cdr-icon>
    <svg class="my-class" data-example="this stays">
      <title>My icon</title>
      <path d="M12 12c1.9329966 0 3.5-1.5670034 3.5-3.5C15.5 6.56700338 13.9329966 5 12 5S8.5 6.56700338 8.5 8.5c0 1.9329966 1.5670034 3.5 3.5 3.5zm6.7621385 7c-.8850139-2.8946791-3.5777143-5-6.7621387-5-3.1844245 0-5.87712493 2.1053209-6.76213876 5H18.7621385zM4 21c-.55228475 0-1-.4477153-1-1h-.00754862a9.07963802 9.07963802 0 0 1 .01314502-.1064258c.00185549-.0175393.0041644-.0349433.00691478-.0522001.43595408-3.2192393 2.56090871-5.9021068 5.45328094-7.1270196C7.26398091 11.7054407 6.5 10.191939 6.5 8.5 6.5 5.46243388 8.96243388 3 12 3c3.0375661 0 5.5 2.46243388 5.5 5.5 0 1.6919391-.763981 3.2054409-1.9657923 4.2143547 2.8923661 1.2249103 5.0173178 3.9077692 5.4532779 7.1269995.0027529.0172699.0050636.0346873.0069201.0522401A9.07834213 9.07834213 0 0 1 21.0075481 20H21c0 .5522847-.4477153 1-1 1H4z"/>
    </svg>
  </cdr-icon>
  ...
</template>

<script>
import { CdrIcon } from '@rei/cedar';

...
  components: {
    CdrIcon
  }
...

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

You can also omit the wrapping svg element.

<template>
  ...
  <cdr-icon>
    <title>My icon</title>
    <path d="M12 12c1.9329966 0 3.5-1.5670034 3.5-3.5C15.5 6.56700338 13.9329966 5 12 5S8.5 6.56700338 8.5 8.5c0 1.9329966 1.5670034 3.5 3.5 3.5zm6.7621385 7c-.8850139-2.8946791-3.5777143-5-6.7621387-5-3.1844245 0-5.87712493 2.1053209-6.76213876 5H18.7621385zM4 21c-.55228475 0-1-.4477153-1-1h-.00754862a9.07963802 9.07963802 0 0 1 .01314502-.1064258c.00185549-.0175393.0041644-.0349433.00691478-.0522001.43595408-3.2192393 2.56090871-5.9021068 5.45328094-7.1270196C7.26398091 11.7054407 6.5 10.191939 6.5 8.5 6.5 5.46243388 8.96243388 3 12 3c3.0375661 0 5.5 2.46243388 5.5 5.5 0 1.6919391-.763981 3.2054409-1.9657923 4.2143547 2.8923661 1.2249103 5.0173178 3.9077692 5.4532779 7.1269995.0027529.0172699.0050636.0346873.0069201.0522401A9.07834213 9.07834213 0 0 1 21.0075481 20H21c0 .5522847-.4477153 1-1 1H4z"/>
  </cdr-icon>
  ...
</template>

<script>
import { CdrIcon } from '@rei/cedar';

...
  components: {
    CdrIcon
  }
...

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19