Icons

Design and redlines

Note that the class naming scheme described in the linked design page is not correct. Icons are SVGs which get their fill colors from their parent element's color. To change an icon color, set its parent element color attribute to the color you wish. If the icon needs to be a different color than the text in the parent, wrap a new element around the SVG (<span> is usually best) and set the desired color on that.

In the examples below, the color is set inline using the style attribute. However in production we recommend using a regular CSS sheet.

The available icons includes the following:

Two methods of including icons

The icons above are called from a single larger SVG sprite, using the <use> tag and href attribute. In Internet Explorer 11 and the webkit version of some Android's default "Chrome" browser, this doesn't work due to a bug unless the sprite is actually on the HTML page where you want to use icons (as opposed to referencing the sprite from your filesystem).

The sprite is invisible on the page, however it is currently around 84kb large. Consumers of the SDK need to choose whether they want to

The advantage of the second method is that this treats the sprite file like any other external file: cachable. Adding 84kb to each page load (the first option) may affect users on slower connections, however it ensures the page never loads with a moment where icons don't appear.

To use the second method, include the JavaScript below to your page which uses icons. Ensure the path in the GET request is the right path for your sprite:

if (!document.getElementById('pe-icons-sprite')) {
  var pe_ajax=new XMLHttpRequest();
  pe_ajax.open("GET", "/icons/p-icons-sprite-1.1.svg", true);
  pe_ajax.responseType="document";
  pe_ajax.onload=function(e) {
    document.body.insertBefore(
      pe_ajax.responseXML.documentElement,
      document.body.childNodes[0]
    );
  }
  pe_ajax.send();
}

If you are using Babel or other ES5-to-ES6 transpiler for your JavaScript, you may wish to change var pe_ajax to const pe_ajax.

Remember that JavaScript's version of attribute names are camel-cased. For example if you are writing an SVG in JSX or building one in vanilla JavaScript, the xlink:href of HTML is called xlinkHref.

Making decorative icons

Decorative icons are sitting next to visible text as a decoration to that text. If they were HTML images, their alt attributes would be "" (empty string).

Warning! Stuff happened!

<h2 style="color:#db0020;background-color:pink;padding:5px;">
<svg style="vertical-align:baseline"
aria-hidden="true"
focusable="false"
class="pe-icon--warning-18">

<use xlink:href="#warning-18"></use>
</svg>
Warning! Stuff happened!</h2>

Making stand-alone icons

Stand-alone icons represent meaningful content on their own, and require their own internal alternative text. If they were HTML images, they would have alt="their meaning". Examples include icons used instead of text inside actionable controls like buttons (see the buttons documentation).

In order for the internal text to work in all assistive tech and browsers currently, a small hack is required: the title element must get an id (which of course must be unique on the page) and the svg element gets an aria-labelledby attribute pointing to that id. Text inside the title tag is not visible on the page. Additionally the role of "img" is added to ensure browsers expose the icon as an image.

<button type="button" class="pe-icon--btn">
<svg role="img"
aria-labelledby="r2"
focusable="false"
class="pe-icon--remove-sm-18">

<title id="r2">Close dialog</title>
<use xlink:href="#remove-sm-18"></use>
</svg>
</button>

Adding new icons to ElementsSDK

After a proposed icon has been accepted by the UX Framework team, an SVG can be created in whichever program you prefer. For a size-18 icon, set the viewBox attribute to "0 0 18 18". For the size-24 version, set the viewBox attribute to "0 0 24 24". This means if the icon you've created is a bit smaller either vertically or horizontally than those dimensions, empty space will be the result (and this is okay).

Don't forget to add the new icon to this page (not only in the list, but to update the main sprite in the docs.html page).

If you've generated an icon with the correct viewBox attribute and don't feel comfortable editing the Elements SVG file, send your icon file to the PDA team.

Making icons accessible

The major accessibility problem with icons in general is that users don't tend to know what they are or what they mean unless they are associated with a textual label. Textual labels particularly aid users with cognitive disabilities. This is especially important if the icons are the primary "text" of an interactive element (e.g. links, buttons).

High Contrast

When users turn on contrast settings (either in their OS or in their browsers), the color attribute on text switches automatically to comply with the new color scheme. However, hard-coded fill values in SVGs may not. To ensure SVG colors also switch with high contrast modes, in the CSS we've set the fill property to inherit from its parent element's color value. This means to have a specific color on any icon, developers should wrap it in something where they can set the appropriate color (usually, as in buttons, the icon doesn't differ from the surrounding text color).

The "new-notification" SVG as an example:

New:
<span style="color:#da0474;">
<svg role="img"
aria-labelledby="r3"
focusable="false"
class="pe-icon--new-notification-9">

<title id="r3">New: </title>
<use xlink:href="#new-notification-9"></use>
</svg>
</span>

Speech recognition

It's important to note that speech users (who interact with the page using voice commands) will not have access to the names of interactive elements whose text is visually hidden and only made available to screen readers. There are only a few icons where a user has a good chance of guessing the interactive element's name, such as "close" and "search," so it's important to show visible names of interactive elements as much as possible.

Screen readers

Screen readers may alert their users to the existence of decorative SVGs. When the icon is purely decorative, add aria-hidden="true" to the SVG to hide it from assistive technologies.


  <svg aria-hidden="true"
       focusable="false"
       class="pe-icon--warning-18">
    <use xlink:href="#warning-18"></use>
  </svg>

Do not use this attribute for icons that are content! Those icons with text inside them should have role=img instead:


  <svg role="img"
       aria-labelledby="r3"
       focusable="false"
       class="pe-icon--warning-18">
    <title id="r3">Text here!</title>
    <use xlink:href="#warning-18"></use>
  </svg>

The aria-labelledby is a fix for some older browsers and Assistive Tech, as is the role (some browsers and some AT see SVGs with other roles such as diagram or group).

Assistive Tech support for SVG icons

Browsers differ in how they present SVGs in general. Assistive technology (AT) is fairly dependent on the browser to give the user the correct awareness of what's available on a web page.

Internet Explorer

IE, up to and including version 11, implements parts of the Tiny SVG 1.2 spec which had a focusable boolean attribute for SVGs, for authors (developers) to state whether an SVG should be focusable. This spec never made it through. The upcoming SVG 2 spec will just use the normal tabindex attribute to set SVG focusability. Edge prior to version 14 used to support this focusable attribute, while later versions have removed this.

The upshot is that SVGs are in the tab order in IE by default, and causes keyboard users (including screen reader users) to have 2 tab stops when an icon is inside a control. Adding focusable="false" to your SVGs takes care of this.

Firefox

Firefox (as last checked) does not appear to offer the names of the SVGs as names of controls when an SVG is inside a button for example. Normally the name of a control like a button comes from the content inside. However some screen readers (Orca on Linux, JAWS for Windows) are leaving the SVGs silent and consider the buttons unnamed. We are still investigating if this is fully a bug on Mozilla's part or Freedom Scientific's (makes of JAWS), but in the meantime if you have a JAWS users on Firefox, know that buttons and other controls with only an SVG icon will be considered unlabelled buttons. Either recommend to your JAWS users to use Internet Explorer or Chrome/chromium (both of these read out the SVGs fine), or you can turn your SVG icons into the "decorative" version (see examples above) and use aria-label (value is a string, don't forget to include localisation) on the control. Be aware that aria-label overrides all labels and text inside a control, and is only appropriate for things like buttons where no additional inner content is present.