Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Accessible Salesforce
Write Visualforce, Lightning and declarative
Salesforce pages that work for everyone!
Hello! We’ll be your presenters today.
Jesse Hausler
Principal Accessibility Specialist, Salesforce
@jessehausler
Shannon ...
Defining web accessibility
Accessibility enables people with disabilities to perceive, understand,
navigate, interact with...
Assistive Technology
Keyboards and switches
Switches
Switches
Cheek Switch
Switches
Cheek Switch
Scanning with switches
● Cycle through rows
● Activate switch
● Cycle through columns
● Activate switch
● Profit
Making Things Work with
Assistive Technology
Forms
The most common and important
task in a CRM is entering data, so
accessible forms are critical.
Form labels
When labels aren’t programmatically
associated to inputs, assistive technology
users have no information about...
Form labels
When labels aren’t programmatically
associated to inputs, assistive technology
users have no information about...
<label/> tags associate inputs with their purpose
All <input/>, <textarea/> and <select/> HTML elements need labels
● Matc...
<label/> tags, great for mouse users too!
Click on a label to:
● Place focus inside of an input field or textarea
● Open a...
Good Bad
Placeholder attributes are not substitutes for labels
Labels in Visualforce
Salesforce Classic Layout/Styling
● For fields on a Salesforce object, <apex:inputField/> automatica...
Visualforce label example: Salesforce Classic styling
Visualforce label example: Salesforce Classic styling
<apex:page docType="html-5.0" standardController="Contact" extension...
Visualforce label example: Bootstrap form
Visualforce label example: Bootstrap form
<div class=”container”>
<apex:form>
<div class="form-group">
<apex:outputLabel f...
But what happened to the ‘required’ indicator?
<div class="form-group">
<apex:outputLabel for="LastName" value="{!$ObjectT...
A note about required fields
The Salesforce Classic red bar or other styling on its own is not enough to
indicate a requir...
Lightning label example
Lightning label example
<form class="slds-form--stacked">
<div class="slds-form-element slds-is-required">
<div class="sld...
Labels in other frameworks
In other frameworks (React, Angular, SLDS outside of Lightning, etc.), always use
<label/> with...
Hiding labels (or other content) visually on a page
Sometimes you want to visually hide a label, heading or other content ...
Hiding content visually on a page with custom CSS
If you’re using another framework or rolling your own styles in Visualfo...
Lightning accessible hidden label example
<form class="slds-form">
<div class="slds-form-element">
<div class="slds-form-e...
aria-describedby associates
help text and error messages with input controls
While <label> tags are used to associate form...
Using aria-describedby in Visualforce
● Visualforce <apex:input*/> tags don’t have native aria-* attribute
● Leverage HTML...
Visualforce aria-describedby example
Visible inline help text is great for settings like this one in the
Nonprofit Starter...
Visualforce aria-describedby example
STG_PanelContacts: right now, the help text isn’t semantically associated with the fi...
Visualforce aria-describedby example
STG_PanelContacts: now with accessible help text!
<div class="form-group">
<apex:outp...
Errors and aria-describedby in Lightning
Set errors on a field using the component’s .errors attribute to dynamically
crea...
Errors and aria-describedby in Lightning
This is what the generated markup looks like from the previous example:
<div clas...
Help and aria-describedby in Lightning
<div class="slds-form-element slds-is-required">
<div class="slds-form-element__con...
Using aria-describedby in other frameworks
In other frameworks, just use the aria-describedby attribute on the
<input/> el...
Group related radio buttons within a <fieldset/>
Consider that a set of radio buttons are an answer to a question.
Group related radio buttons within a <fieldset/>
<label> associates answer choices to their radio buttons.
<input type=”ra...
Group related radio buttons within a <fieldset/>
The <legend/> of the <fieldset/> associates the question to the answer
ch...
Other use cases for <fieldset/>
● Group related fields -- consider
Shipping Address vs Billing Address
in compound fields
...
Using <fieldset/> in Visualforce
● Specify the legendText attribute on <apex:selectCheckboxes/> and
<apex:selectRadio/> to...
Using <fieldset/> in Visualforce: Classic Styling
<apex:page controller="CheckboxTestControllerVF">
<apex:form>
<apex:sele...
Using <fieldset/> in Lightning with SLDS
<aura:component implements="force:appHostable" controller="CheckboxTestController...
Using <fieldset/> in other frameworks
<fieldset>
<legend>My Legend</legend>
<!-- Form fields and other grouped content go ...
If an element behaves like a button, it’s a <button/>
Generally speaking, if an element submits a form, executes some code...
Why semantic <button/> use is important
● Buttons have different interaction behaviors than links and are announced
differ...
Images
Describe non-text content to
assistive technologies
Informational vs decorative images
<img/> requires the presence of the alt attribute
The alt attribute helps assistive technologies describe the purpose of a...
alt attributes in Visualforce
Use the alt attribute on <apex:image/> for accessible images in Visualforce:
<h1 class="h4">...
alt attributes in Lightning
<ui:image/> has an imageType attribute with two possible values:
● informational: the alt attr...
alt attributes in Lightning: SLDS Example
If you want to leverage the SVGs in SLDS inside Lightning
Components, you may ne...
alt attributes in Lightning: SLDS example
recentItemsList.cmp
<aura:component implements="force:appHostable" controller="R...
alt attributes in Lightning: SLDS example
sObjectHyperlink.cmp
<aura:component >
<aura:attribute name="sObjectId" type="Id...
Image links and buttons need text content
With icon fonts, this is too common:
<a href="http://www.facebook.com/">
<span c...
Image links and buttons need text content
How a screen reader announces this:
“Link”
“Link”
“Link”
“Link”
Image links and buttons need text content
How to fix it:
<a href="http://www.facebook.com/">
<span class="icon-facebook"><...
Image links and buttons need text content
Bootstrap image example:
<button class="btn btn-link">
<span class="glyphicon gl...
Interactivity
Make all interactive content
accessible from the keyboard.
Ensure interactive elements are accessible using
keyboard and assistive technology
These components all follow the W3C spe...
Use hyperlinks and buttons for click targets
Only <a/>, <button/>, and <input/> types should be:
○ Click targets
○ Hover t...
Use hyperlinks and buttons for click targets
Don't make <div/>, <span/>
and other non-focusable
elements “clickable”.
Use hyperlinks and buttons for click targets
Navigation options:
● add onclick to a card for a
larger tap/click target, bu...
Using hover
● Behaviors which occur on mouse hover
must also occur with keyboard focus
● Triggers need to be focusable
In ...
Using hover
Don’t use hover to reveal actionable
content, such as buttons or links. Just
show them.
In Lightning Experienc...
Color Usage
Color is a key part of visual design
-- but not everyone using your page
will see it the same way you do
Text color contrast ratio
must meet the minimum requirement
According to the WCAG,
● Contrast ratio between text and backg...
Don’t use color as the only means of differentiation
Don’t use color as the only means of differentiation
Other
Considerations
These are other items that test
automation can be used to find.
Other
● Have a descriptive page <title/>
○ This is good not only for assistive tech, but for those of us who like to have ...
Testing and
Debugging
How can you tell if you’re doing the
right thing?
Testing and Debugging
● Unplug your mouse
● Test with users with disabilities
● Chrome Accessibility Developer Tools
● Mac...
Questions?
Resources
How to Meet WCAG 2.0
7 Things Every Designer Needs to Know about Accessibility
Colorsafe.co
Microsoft Inclusive ...
Upcoming SlideShare
Loading in …5
×

Accessible Salesforce

1,764 views

Published on

Much of the Salesforce user interface is accessible out of the box to users who require assistive technologies. Here's how can you ensure that your custom Visualforce or Lightning pages also have the best possible experience for everyone -- even users who are blind or have vision impairments, or have impaired motor control and can't use a mouse.

Published in: Software
  • Hi All, We are planning to start new Salesforce Online batch on this week... If anyone interested to attend the demo please register in our website... For this batch we are also provide everyday recorded sessions with Materials. For more information feel free to contact us : siva@keylabstraining.com. For Course Content and Recorded Demo Click Here: http://www.keylabstraining.com/salesforce-online-training-hyderabad-bangalore
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Accessible Salesforce

  1. 1. Accessible Salesforce Write Visualforce, Lightning and declarative Salesforce pages that work for everyone!
  2. 2. Hello! We’ll be your presenters today. Jesse Hausler Principal Accessibility Specialist, Salesforce @jessehausler Shannon Hale Director of UX, Skuid (+ former Accessibility Workgroup member @ Salesforce) @shannonsans
  3. 3. Defining web accessibility Accessibility enables people with disabilities to perceive, understand, navigate, interact with and contribute to the Web. ● Vision ● Mobility impairments ● Deafness and hard of hearing ● Cognitive
  4. 4. Assistive Technology
  5. 5. Keyboards and switches
  6. 6. Switches
  7. 7. Switches Cheek Switch
  8. 8. Switches Cheek Switch
  9. 9. Scanning with switches ● Cycle through rows ● Activate switch ● Cycle through columns ● Activate switch ● Profit
  10. 10. Making Things Work with Assistive Technology
  11. 11. Forms The most common and important task in a CRM is entering data, so accessible forms are critical.
  12. 12. Form labels When labels aren’t programmatically associated to inputs, assistive technology users have no information about what to type in each field.
  13. 13. Form labels When labels aren’t programmatically associated to inputs, assistive technology users have no information about what to type in each field.
  14. 14. <label/> tags associate inputs with their purpose All <input/>, <textarea/> and <select/> HTML elements need labels ● Match the for attribute of <label/> tags to the id attribute of the corresponding input control ● Remove orphaned labels (<label/> without an associated input control)
  15. 15. <label/> tags, great for mouse users too! Click on a label to: ● Place focus inside of an input field or textarea ● Open a picklist ● Check a checkbox ● Select a radio button
  16. 16. Good Bad Placeholder attributes are not substitutes for labels
  17. 17. Labels in Visualforce Salesforce Classic Layout/Styling ● For fields on a Salesforce object, <apex:inputField/> automatically associates labels and input controls as a child of <apex: pageBlockSection/> ● For fields not on a Salesforce object, use <apex:outputLabel/> with <apex:input/>, <apex:inputText/>, etc. inside <apex: pageBlockSectionItem/> and match the for attribute of <apex: outputLabel/> with the id attribute of <apex:input*/> Custom Layout/Styling ● For Bootstrap or other custom layouts, use <apex:outputLabel/> with <apex:inputField/>, <apex:input/> etc. as above
  18. 18. Visualforce label example: Salesforce Classic styling
  19. 19. Visualforce label example: Salesforce Classic styling <apex:page docType="html-5.0" standardController="Contact" extensions="ContactAccessibility"> <apex:form > <apex:pageBlock title="Contact" mode="edit"> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="Save"/> </apex:pageBlockButtons> <apex:pageBlockSection title="Contact Details" columns="1"> <apex:inputField value="{!contact.lastName}"/> <apex:pageBlockSectionItem> <apex:outputLabel for="NumGuests" value="Number of Guests" /> <apex:input type="number" id="NumGuests" value="{!numGuests}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem> <apex:outputPanel layout="none" /> <apex:outputPanel layout="none"> <apex:inputCheckbox id="OkToContact" value="{!contactOK}" /> <apex:outputLabel for="OkToContact" value="Contact with special offers" /> </apex:outputPanel> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
  20. 20. Visualforce label example: Bootstrap form
  21. 21. Visualforce label example: Bootstrap form <div class=”container”> <apex:form> <div class="form-group"> <apex:outputLabel for="LastName" value="{!$ObjectType.Contact.fields.LastName.Label}" styleClass=”control-label” /> <apex:inputField id="LastName" value="{!contact.lastName}" required="true" styleClass="form- control" /> </div> <div class="form-group"> <apex:outputLabel for="NumGuests" value="Number of Guests" styleClass=”control-label” /> <apex:input type="number" id="NumGuests" value="{!numGuests}" styleClass="form-control" /> </div> <div class="form-group"> <div class="checkbox"> <apex:inputCheckbox id="OkToContact" value="{!contactOK}" /> <apex:outputLabel for="OkToContact" value="Contact with special offers" /> </div> </div> <div class="form-group"> <apex:commandButton action="{!save}" value="Save" styleClass="btn btn-default" /> </div> </apex:form> </div>
  22. 22. But what happened to the ‘required’ indicator? <div class="form-group"> <apex:outputLabel for="LastName" value="{!$ObjectType.Contact.fields.LastName.Label} *" styleClass=”control-label” /> <apex:inputField id="LastName" value="{!contact.lastName}" required="true" styleClass="form- control" /> </div> We set required=”true” on <apex: input/> but Bootstrap doesn’t know what to do with this. Provide a text indicator such as an asterisk on the label, so it’s accessible to assistive tech.
  23. 23. A note about required fields The Salesforce Classic red bar or other styling on its own is not enough to indicate a required field. If you’re rolling your own page markup, make sure to provide some text indication of field requiredness inside the <label> tags. What you don’t see here is that Visualforce- and Salesforce Classic-generated required field labels have an asterisk in the label that’s visually hidden, but still available to assistive technology. <label for="j_id0:j_id1:j_id2:j_id5:j_id6"> <span class="assistiveText">*</span> Last Name </label>
  24. 24. Lightning label example
  25. 25. Lightning label example <form class="slds-form--stacked"> <div class="slds-form-element slds-is-required"> <div class="slds-form-element__control"> <ui:inputText aura:id="lastName" label="Last Name" class="slds-input" labelClass="slds- form-element__label" value="{!v.newContact.LastName}" required="true" /> </div> </div> <div class="slds-form-element"> <div class="slds-form-element__control"> <ui:inputNumber aura:id="numGuests" label="Number of Guests" class="slds-input" labelClass="slds-form-element__label" value="{!v.newContact.NumberOfGuests}" /> </div> </div> <div class="slds-form-element"> <ui:inputCheckbox aura:id="reimbursed" label="Contact with special offers" class="slds- checkbox" labelClass="slds-form-element__label" value="{!v.newContact.OKToContact}" /> </div> <div class="slds-form-element"> <ui:button label="Save" class="slds-button slds-button--neutral" press="{!c.createContact}" /> </div> </form>
  26. 26. Labels in other frameworks In other frameworks (React, Angular, SLDS outside of Lightning, etc.), always use <label/> with <input/>, <textarea/> and <select/> HTML elements. <div ng-controller="ExampleController"> <form novalidate class="simple-form"> <label for="name">Last Name *</label> <input type="text" id="name" ng-model="contact.lastname" required /><br /> <label for="numGuests">Number of Guests</label> <input type="number" id="numGuests" ng-model="contact.numberOfGuests" /><br /> <input type="checkbox" id="okToContact" ng-model="contact.okToContact" value="okToContact" /> <label for="okToContact">Contact with special offers</label><br /> <input type="submit" ng-click="update(contact)" value="Save" /> </form> </div>
  27. 27. Hiding labels (or other content) visually on a page Sometimes you want to visually hide a label, heading or other content while still making the label available to assistive technologies. Don’t use display: none or visibility: hidden in the CSS. Both of these will hide the content from assistive technologies -- use them only when you want to hide the content from EVERYONE. To do it right, add a class to the element you want hidden: ● Lightning Design System: slds-assistive-text ● Bootstrap: sr-only ● Visualforce and other frameworks: create a custom class (see next slide)
  28. 28. Hiding content visually on a page with custom CSS If you’re using another framework or rolling your own styles in Visualforce, create a custom class and add it to the content you want to hide: .assistive-text { position: absolute; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); padding: 0; border: 0; height: 1px; width: 1px; overflow: hidden; z-index: -1000; }
  29. 29. Lightning accessible hidden label example <form class="slds-form"> <div class="slds-form-element"> <div class="slds-form-element__control"> <div class="slds-input-has-icon slds-input-has-icon--left"> <c:svgIcon svgPath="/resource/slds0121/assets/icons/utility-sprite/svg/symbols.svg#search" category="utility" size="x-small" name="search" class="slds-input__icon slds-icon-text-default" /> <ui:inputText aura:id="q" label="Search" class="slds-input" labelClass="slds-assistive-text" /> </div> </div> </div> </form>
  30. 30. aria-describedby associates help text and error messages with input controls While <label> tags are used to associate form fields with their label, aria- describedby is used to associate information beyond a label to an input ● When a user places focus on an input, both the label and the help or error text will be available to screen readers
  31. 31. Using aria-describedby in Visualforce ● Visualforce <apex:input*/> tags don’t have native aria-* attribute ● Leverage HTML pass through attributes and add html-aria-describedby ● Use the $Component global merge field to get the generated id of the related element if it’s an <apex:outputPanel/> or other Visualforce component Unfortunately, neither Salesforce Classic or Visualforce set aria-describedby automatically for errors, so this is a manual exercise. If the user has Accessibility Mode enabled, then labels of fields with errors prepend “Error -” to the label. Lightning handles this better, as you’ll see.
  32. 32. Visualforce aria-describedby example Visible inline help text is great for settings like this one in the Nonprofit Starter Pack, which aren’t edited very frequently and can be hard to understand from just the label.
  33. 33. Visualforce aria-describedby example STG_PanelContacts: right now, the help text isn’t semantically associated with the field it describes <div class="form-group"> <apex:outputLabel value="{!$ObjectType.npe01__Contacts_And_Orgs_Settings__c.Fields. npe01__Account_Processor__c.Label}" for="slAP" styleClass="col-sm-4 control-label" /> <div class="col-sm-8 form-control-column"> <apex:outputField value="{!stgService.stgCon.npe01__Account_Processor__c}" rendered="{! isReadOnlyMode}" /> <apex:selectList value="{!stgService.stgCon.npe01__Account_Processor__c}" multiselect=" false" size="1" rendered="{!isEditMode}" id="slAP" styleClass="form-control"> <apex:selectOptions value="{!listSOAccountModels}"/> </apex:selectList> </div> <div class="col-sm-offset-4 col-sm-8 help-block"> <apex:outputText value="{!$Label.stgHelpAccountModel}" /> </div> </div>
  34. 34. Visualforce aria-describedby example STG_PanelContacts: now with accessible help text! <div class="form-group"> <apex:outputLabel value="{!$ObjectType.npe01__Contacts_And_Orgs_Settings__c.Fields. npe01__Account_Processor__c.Label}" for="slAP" styleClass="col-sm-4 control-label" /> <div class="col-sm-8 form-control-column"> <apex:outputField value="{!stgService.stgCon.npe01__Account_Processor__c}" rendered="{! isReadOnlyMode}" /> <apex:selectList value="{!stgService.stgCon.npe01__Account_Processor__c}" multiselect=" false" size="1" rendered="{!isEditMode}" id="slAP" html-aria-describedby="{!$Component. slAPHelp}" styleClass="form-control"> <apex:selectOptions value="{!listSOAccountModels}"/> </apex:selectList> </div> <apex:outputPanel id="slAPHelp" layout="block" styleClass="col-sm-offset-4 col-sm-8 help- block"> <apex:outputText value="{!$Label.stgHelpAccountModel}" /> </apex:outputPanel> </div>
  35. 35. Errors and aria-describedby in Lightning Set errors on a field using the component’s .errors attribute to dynamically create and insert the error message and aria-describedby tag into the field DOM: createExpense : function(component, event, helper) { var amtField = component.find("amount"); var amt = amtField.get("v.value"); if (isNaN(amt) || amt==''){ amtField.set("v.errors", [{message:"Enter an expense amount."}]); } else { amtField.set("v.errors", null); var newExpense = component.get("v.newExpense"); helper.createExpense(component, newExpense); } } More on error handling: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_throw_error.htm
  36. 36. Errors and aria-describedby in Lightning This is what the generated markup looks like from the previous example: <div class="slds-form-element slds-is-required"> <div class="slds-form-element__control"> <div class="uiInput uiInputNumber uiInput--default uiInput--input has-error"> <label class="slds-form-element__label uiLabel-left form-element__label uiLabel" for=" 34:2;a" ><span class="">Amount</span><span class="required">*</span></label> <input class="slds-input input" max="99999999999999" step="1" type="text" min=" -99999999999999" aria-describedby="112:c" placeholder="" required="" id="34:2;a"> </div> <ul class="has-error uiInputDefaultError uiInput uiInputNumber uiInput--default uiInput-- input" id="112:c"> <li class="form-element__help">Enter an expense amount.</li> </ul> </div> </div>
  37. 37. Help and aria-describedby in Lightning <div class="slds-form-element slds-is-required"> <div class="slds-form-element__control"> <ui:inputText aura:id="expname" label="Expense Name" class="slds-input" labelClass="slds-form-element__label" value="{!v.newExpense.Name}" required="true" /> </div> <div class="custom-help-block"> <p>Please use the format: Date - last name - purpose</p> </div> </div> Unfortunately, the ariaDescribedBy attribute hasn’t been surfaced in the Lightning Component framework on the platform as of Winter ‘16 (more info)
  38. 38. Using aria-describedby in other frameworks In other frameworks, just use the aria-describedby attribute on the <input/> element to associate it with the element containing the message. You can use Element.setAttribute() to set the attribute dynamically via JavaScript during error handling. <label for=”myFieldId”>Field Label</label> <input id=”myFieldId” type=”text” value=”fieldValue” aria- describedby=”myMessageId” /> <span id=”myMessageId”>More information or an error message about this field</span>
  39. 39. Group related radio buttons within a <fieldset/> Consider that a set of radio buttons are an answer to a question.
  40. 40. Group related radio buttons within a <fieldset/> <label> associates answer choices to their radio buttons. <input type=”radio” id=”color-blue” name=”color” value=”blue” /> <label for=”color-blue”>Blue</label>
  41. 41. Group related radio buttons within a <fieldset/> The <legend/> of the <fieldset/> associates the question to the answer choices. <fieldset> <legend>What is your favorite color?</legend> <!-- blue/red/green/orange radio buttons go here --> </fieldset>
  42. 42. Other use cases for <fieldset/> ● Group related fields -- consider Shipping Address vs Billing Address in compound fields ● Group checkboxes to allow multiple possible answers (“check all that apply”)
  43. 43. Using <fieldset/> in Visualforce ● Specify the legendText attribute on <apex:selectCheckboxes/> and <apex:selectRadio/> to properly group the input controls in a fieldset with a legend ● If needed, hide the legend from sighted users by setting legendInvisible=”true” -- this adds class=”assistiveText” to the <legend/> tag, which keeps to the legend accessible to assistive technologies but hides it visually
  44. 44. Using <fieldset/> in Visualforce: Classic Styling <apex:page controller="CheckboxTestControllerVF"> <apex:form> <apex:selectCheckboxes layout="pageDirection" legendText="Contacts to invite:" value="{!contactIds}"> <apex:selectOptions value="{!items}" /> </apex:selectCheckboxes> </apex:form> </apex:page> public List<SelectOption> getItems() { List<SelectOption> options = new List<SelectOption>(); for (Contact c : [SELECT Id, Name FROM Contact]) { options.add(new SelectOption(c.Id, c.Name)); } return options; }
  45. 45. Using <fieldset/> in Lightning with SLDS <aura:component implements="force:appHostable" controller="CheckboxTestController"> <aura:attribute name="contacts" type="Contact[]" /> <aura:attribute name="checkedContacts" type="String[]" /> <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> <div class="slds-form--stacked"> <fieldset class="slds-form-element"> <span class="slds-form-element__label slds-form-element__label-top"> <legend>Contacts to invite:</legend> </span> <div class="slds-form-element__control"> <aura:iteration var="con" items="{!v.contacts}"> <label for="{!'c' + con.Id}" class="slds-checkbox"> <input type="checkbox" id="{!'c' + con.Id}" value="{!con.Id}" onchange="{!c.updateCheckboxes}" /> <span class="slds-checkbox--faux"></span> <span class="slds-form-element__label">{!con.Name}</span> </label> </aura:iteration> </div> </fieldset> </div> </aura:component> Note that we’re not using <ui:inputCheckbox/> here: as of Winter ‘16 there’s no way to (1) position the label on the right and (2) add the faux checkbox <span/> for SLDS styling.
  46. 46. Using <fieldset/> in other frameworks <fieldset> <legend>My Legend</legend> <!-- Form fields and other grouped content go here --> </fieldset>
  47. 47. If an element behaves like a button, it’s a <button/> Generally speaking, if an element submits a form, executes some code without leaving the page, or otherwise has button-like behavior, it should be a <button/> Image-only buttons have other important considerations -- we’ll talk about this in Images.
  48. 48. Why semantic <button/> use is important ● Buttons have different interaction behaviors than links and are announced differently by assistive technologies ○ Pressing Space or Enter triggers onclick on button, but only Enter triggers onclick on links ○ <a/> elements with an empty href attributes won’t receive keyboard focus ● <div/> and <span/> elements don’t receive keyboard focus, so aren’t accessible from the keyboard* ● Some assistive technology uses shortcut keys to get a list of links or buttons on the page -- you want the right elements to be returned
  49. 49. Images Describe non-text content to assistive technologies
  50. 50. Informational vs decorative images
  51. 51. <img/> requires the presence of the alt attribute The alt attribute helps assistive technologies describe the purpose of an image to users who can’t see it ● Images that are purely decorative should have an empty alt attribute: <img src=”decorative.jpg” alt=”” /> ● Informational images should have a useful alt attribute value: <img src=”exclamation.png” alt=”Warning” /> ● “null”, “empty” and “undefined” are not appropriate alt values ● If the alt attribute is missing, the file name will be read instead!
  52. 52. alt attributes in Visualforce Use the alt attribute on <apex:image/> for accessible images in Visualforce: <h1 class="h4">Recent Items</h1> <ol class="list-unstyled recentItems"> <apex:repeat value="{!recentItems}" var="item"> <li> <apex:outputLink value="/{!item.Id}"> <apex:image value="/s.gif" styleClass="{!IF(item.type='Account', 'account24', 'contact24')}" alt="{!IF(item.type='Account', 'Account', 'Contact')}" /> {!item.Name} </apex:outputLink> </li> </apex:repeat> </ol>
  53. 53. alt attributes in Lightning <ui:image/> has an imageType attribute with two possible values: ● informational: the alt attribute is also required ● decorative: the alt attribute is not required However! <ui:image/> is not available in Lightning components as of Winter ‘16. Instead, use the HTML <img/> tag and set the alt attribute as for any other framework (remember to set alt=”” for descriptive images)
  54. 54. alt attributes in Lightning: SLDS Example If you want to leverage the SVGs in SLDS inside Lightning Components, you may need the Lightning SVG Icon Component Helper
  55. 55. alt attributes in Lightning: SLDS example recentItemsList.cmp <aura:component implements="force:appHostable" controller="RecentItemsControllerLX"> <ltng:require styles="/resource/slds0121/assets/styles/salesforce-lightning-design-system.min. css"/> <aura:attribute name="items" type="RecentlyViewed[]" /> <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> <ol> <aura:iteration var="item" items="{!v.items}"> <li> <c:sObjectHyperlink sObjectId="{!item.Id}" hyperlinkLabel="{!item.Name}" sObjectType="{!item.Type}" /> </li> </aura:iteration> </ol> </aura:component>
  56. 56. alt attributes in Lightning: SLDS example sObjectHyperlink.cmp <aura:component > <aura:attribute name="sObjectId" type="Id" /> <aura:attribute name="hyperlinkLabel" type="String" /> <aura:attribute name="sObjectType" type="String" /> <a href="javascript:void(0);" onclick="{!c.showObjectInfo}"> <aura:renderIf isTrue="{!v.sObjectType == 'Account'}"> <c:svgIcon svgPath="/resource/slds0121/assets/icons/standard-sprite/svg/symbols.svg#account" category="standard" size="small" name="account" containerClass="slds-icon__container slds-icon-standard-account" assistiveText="Account"/> </aura:renderIf> <aura:renderIf isTrue="{!v.sObjectType == 'Contact'}"> <c:svgIcon svgPath="/resource/slds0121/assets/icons/standard-sprite/svg/symbols.svg#contact" category="standard" size="small" name="contact" containerClass="slds-icon__container slds-icon-standard-contact" assistiveText="Contact"/> </aura:renderIf> {!v.hyperlinkLabel} </a> </aura:component>
  57. 57. Image links and buttons need text content With icon fonts, this is too common: <a href="http://www.facebook.com/"> <span class="icon-facebook"></span> </a> <a href="http://twitter.com/"> <span class="icon-twitter"></span> </a> <a href="http://youtube.com/"> <span class="icon-youtube"></span> </a> <a href="http://plus.google.com/"> <span class="icon-googleplus"></span> </a>
  58. 58. Image links and buttons need text content How a screen reader announces this: “Link” “Link” “Link” “Link”
  59. 59. Image links and buttons need text content How to fix it: <a href="http://www.facebook.com/"> <span class="icon-facebook"><span class=”assistive-text”>Facebook</span></span> </a> <a href="http://twitter.com/"> <span class="icon-twitter"><span class=”assistive-text”>Twitter</span></span> </a> <a href="http://youtube.com/"> <span class="icon-youtube"><span class=”assistive-text”>YouTube</span></span> </a> <a href="http://plus.google.com/"> <span class="icon-googleplus"><span class=”assistive-text”>Google+</span></span> </a>
  60. 60. Image links and buttons need text content Bootstrap image example: <button class="btn btn-link"> <span class="glyphicon glyphicon-remove delete-icon"> <span class="sr-only">Delete</span> </span> </button> See also: http://salesforce.stackexchange.com/questions/99411/make-an-apeximage-appear-conditionally-with-apex- code/99418#99418
  61. 61. Interactivity Make all interactive content accessible from the keyboard.
  62. 62. Ensure interactive elements are accessible using keyboard and assistive technology These components all follow the W3C spec for accessibility ● Menu <ui:menu/> ● Modal dialog <ui:modal/> ● Non-modal panel <ui:panel/> ● Autocomplete typeahead <ui:autocomplete/> ● Tabset <ui:tabset/> ● Tooltip <ui:tooltip/> Only <ui:menu> is supported in Lightning as of Winter ‘16 -- for a list of supported components, use https://yourdomain.lightning.force.com/auradocs/reference.app rather than the open source http: //documentation.auraframework.org/auradocs)
  63. 63. Use hyperlinks and buttons for click targets Only <a/>, <button/>, and <input/> types should be: ○ Click targets ○ Hover targets They natively receive and show focus, perform actions, and communicate with assistive technologies.
  64. 64. Use hyperlinks and buttons for click targets Don't make <div/>, <span/> and other non-focusable elements “clickable”.
  65. 65. Use hyperlinks and buttons for click targets Navigation options: ● add onclick to a card for a larger tap/click target, but include a hyperlink to the same destination ● wrap the card in an <a/> Interaction: ● add an explicit <button/> instead of onclick on a non-focusable element
  66. 66. Using hover ● Behaviors which occur on mouse hover must also occur with keyboard focus ● Triggers need to be focusable In this example, the blue circle with the “i” character should be an anchor. The tooltip shows when the anchor is in focus.
  67. 67. Using hover Don’t use hover to reveal actionable content, such as buttons or links. Just show them. In Lightning Experience, pencils aren’t hidden behind hover states. Instead, they get darker on hover.
  68. 68. Color Usage Color is a key part of visual design -- but not everyone using your page will see it the same way you do
  69. 69. Text color contrast ratio must meet the minimum requirement According to the WCAG, ● Contrast ratio between text and background should be at least 4.5 to 1. ● If font is at least 24 px or 19 px bold, the minimum drops to 3 to 1. For large text, the lightest gray you can use on white is #959595 For small text, the lightest gray you can use on white is #767676
  70. 70. Don’t use color as the only means of differentiation
  71. 71. Don’t use color as the only means of differentiation
  72. 72. Other Considerations These are other items that test automation can be used to find.
  73. 73. Other ● Have a descriptive page <title/> ○ This is good not only for assistive tech, but for those of us who like to have 20 tabs open in our browsers! ● Properly nest your page headings (<h1/><h2/><h3/>) ○ Use heading tags for headings! <div class=”my-heading-style”>...</div> does not communicate that the content is a heading to assistive technologies. ● Consider whether lists are ordered or unordered ● Data table cells must be associated with data table headers ● Have a descriptive title attribute for frame and iframe elements ● Avoid repetitive hyperlink text (Edit, View All, etc) ○ Provide disambiguation for assistive technologies by hiding the content visually
  74. 74. Testing and Debugging How can you tell if you’re doing the right thing?
  75. 75. Testing and Debugging ● Unplug your mouse ● Test with users with disabilities ● Chrome Accessibility Developer Tools ● Mac OS X ○ VoiceOver - free screen reader software (System Preferences > Accessibility > VoiceOver) ○ Full Keyboard Access: All Controls (System Preferences > Keyboard > Shortcuts) ○ Safari accessibility: tab to links (Preferences > Advanced >Press Tab to highlight each item on a webpage) ● Windows ○ NVDA - free screen reader software ○ Most screen reader users use JAWS on Windows
  76. 76. Questions?
  77. 77. Resources How to Meet WCAG 2.0 7 Things Every Designer Needs to Know about Accessibility Colorsafe.co Microsoft Inclusive Design Toolkit

×