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:
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
.
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).
<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>
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>
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).
Open the SVG icons file found in the /assets/icons/
folder in a text editor
Open your new icon SVG file in a text editor
In the Elements icon file, insert a <symbol> tag with an id attribute matching the name of the new icon and its size; add in the viewBox attribute
Example: <symbol id="my-newIcon-18" viewBox="0 0 18 18">
...
<symbol>
From your new icon, copy the <path> into the Elements file, inside the <symbol> tags.
Test your new icon out locally
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.
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).
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:
<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>
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 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
).
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.
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 (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.