Building Accessible Building Accessible User Interfaces User Interfaces with JavaScript and jQuery with JavaScript and jQuery Antranig Basman, Core Framework Architect, The Fluid Project Clayton Lewis, Professor of Computer Science, University of Colorado at Boulder
198
Embed
Building Accessible User Interfaces with JavaScript and jQuery Antranig Basman, Core Framework Architect, The Fluid Project Clayton Lewis, Professor of.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Building Accessible User Building Accessible User InterfacesInterfaces
with JavaScript and jQuerywith JavaScript and jQuery
Antranig Basman, Core Framework Architect, The Fluid ProjectClayton Lewis, Professor of Computer Science,University of Colorado at Boulder
Our Goals•Guide to the ropes and pitfalls of
– JavaScript
– jQuery
•A special emphasis on techniques appropriate for
– Portals, Mashups and CMSs
– Designing accessible, flexible apps
• Finish by leading into the basics of Fluid Infusion
Portals, Mashups, and CMSs
•These days, diverse code and markup coexists
•Most JavaScript is written as if it owns the whole browser
•As you combine stuff, things can break
•Namespacing and privacy is essential
Schedule
– Javascript 101
• 8:55 Break
– jQuery
– AJAX
– Accessibility Basics
• 9:55 Break
– Accessibility Nuts and Bolts
• 10:55 Break
– Web 2.0 Accessibility and ARIA
– Fluid Infusion
• 11:55 Closing
Modus Operandi
•Brief introductions, so get to know one another a little
•We’ll ask you to discuss with your neighbors from time to time
•Questions, comments, and especially arguments are urged at any time!
Javascript 101
• Everything is an “object”
• Extremely loose type system
- Only 6 types for values
- No types for references
• No classes
• Functions are first class
• Some annoying quirks
JavaScript is Different
• Netscape rushed JS to market, bugs and all, and with a shabbily motivated name
• Microsoft reverse-engineered it.
• Standards committee enforced the bugs.
• In recent years JS has become a crucial technology
• Big efforts on improved implementations have delivered huge performance gains
Super-Quick History
• Variables
• null vs. undefined
• Type coercion
• Objects and Arrays
Part 1: The Basics
•Define variables with var
•Types are not specified
var mango = "yum";
mango = 12345;
mango = false;
Defining Variables
•If you omit var, it will be defined as a global variable.
•This is accident prone; JavaScript won't warn you!
rottenTomato = "gross!"; // This is global
Defining Variables
• Numbers
– lots of precision
– no distinction between floats and ints
– NaN !== NaN
• Strings
– Unicode (mostly)
– Immutable
– No character type
Numbers and Strings
• null is the "nothing" value
• undefined is extremely nothing
– Default value for uninitialized variables
– Also the value of missing members of objects and arguments
•exception thrown when the language encounters names which are not found in any scope
– “typeof” expressions are safe and need to be used for detection here
Null vs. Undefined
Truthy and Falsey
• JavaScript does a lot of automatic type coercion
– A common case is in conditions
•Shades of true and false
•Use with care
if (x)x? thing1: thing2
Falsey Values• false
• null
• undefined
• ""
• 0 (zero)
• NaN
• Everything else is truthy. Careful...
• -1, "false", "0" are all true
Equal vs. Equivalent
•Comparisons are coercive:
1 == "1" // true
0 == false // true
Non-coercive comparison:
• 0 === false // false
• 1 !== "1" // true
• 1 === Number("1") // true
Don’t use this operator!
Use this operator!
Objects
Objects Are Containers
Don’t use this!• At their core, objects are just maps or “dictionaries”
• new Object() or {} returns an empty container of key/value pairs
Coping With Bugs• this can be confusing and unstable
• Constructor functions can accidentally clobber the global namespace
• Prototypal inheritance can easily cause existing code to break
• Can we simplify things?
Plain Old Functions & Objects
// Just use plain old functions and objects.function orange () { // Stable pointer to the current instance. var that = {}; // Anything private stays inside here.
// For public methods, just add properties. that.squeeze = function () {...}
return that;}
Writing Collision-Free JavaScript
•Put code in a unique namespace
•Use closures for privacy
•Support more than one on the page
– Scope all variables to an instance
– Avoid hard-baking ID selectors
•Constrain selectors within a specific element
These are policies followed by Fluid Infusion
Keeping it to Ourselves
•You should take namespacing seriously
•Don’t steal global names
– JavaScript globals
– jQuery plugin names
– HTML id values
– others
•Components are carefully scoped
•Don’t expect control of the page
Start With a Unique
Namespace// Add on to the fluid object if it exists,// otherwise initialize it as an empty object.
var fluid = fluid || {};
Use Closures for Privacy
var fluid = fluid || {};(function() {
// Private stuff. function myPrivateFunction () {
}
// Add public stuff to your namespace.fluid.tabs = function () {
// Public creator function.};
})();
Keep Common Aliases Private
Pass important dependencies in as an argument to the closure:
jQuery.noConflict(); // Tell jQuery to surrender $
(function ($) { // $ is now only visible in our private space.//$ === jQuery;
}) (jQuery);
//$ === undefined;
JSON syntax
•Use of {} and [],
•Equivalence of assignment and JSON forms
•A curly bracket doesn’t just mean a block
JavaScript pitfalls
•Corrupting Object.prototype and Array.prototype (or any prototypes for that matter)
•Writing for (var x in v) for an array
•Asynchrony in AJAX (Talk about promises) and jQuery.when() – single-threaded!
•jQuery UI: Library of plugins and widgets for jQuery
– Datepicker, Accordion, Slider, Tabs
– version 1.8.3
finding something without a framework
function stripeListElements(listID) {// get the items from the listvar myItems = getElementsByTagName("li");// skip line 0 as it's the header row for(var i = 0; i < myItems.length; i++) {
if ((count % 2) === 0) {myItems[count].className = "odd";
}}
}
var myItems = jQuery('li');
finding something with jQueryfinding something with jQuery
jQuery("<selector>")
selectors :tags: jQuery("tr")
ids: jQuery("#myId")
classes: jQuery(".myClass")
pseudo tags: jQuery("div:first")
jQuery("<selector>")
selectors :tags: jQuery("tr")
ids: jQuery("#myId")
classes: jQuery(".myClass")
pseudo tags: jQuery("div:first")
finding something with jQueryfinding something with jQuery
} These forms as supported in CSS
jQuery("<selector>")
more selectors = combining selectorselement by class: jQuery("li.selected");
relationships: jQuery("tbody tr:even");
children: jQuery("div > p");
siblings: jQuery("div ~ p");
etc, etc, etc...
jQuery("<selector>")
more selectors = combining selectorselement by class: jQuery("li.selected");
relationships: jQuery("tbody tr:even");
children: jQuery("div > p");
siblings: jQuery("div ~ p");
etc, etc, etc...
finding something with jQueryfinding something with jQuery
jQuery("li");
doing something with jQuerydoing something with jQuery
jQuery("li:even");
doing something with jQuerydoing something with jQuery
jQuery("li:even").addClass("odd");
doing something with jQuerydoing something with jQuery
function stripeListElements(listId) {jQuery('#' + listId + "
li:even").addClass("odd");}
$(“li:even”, fluid.byId(listId)).addClass(“odd”)
doing something with jQuery
jQuery === $
$(".some-hidden-thing").show();
$(".some-hidden-thing").fadeIn("slow");
$("<li>A new list item</li>").appendTo("#myList");
$("#myList li:last").replaceWith("<li>A new list item</li>");
$("div.container").clone().appendTo("body");
$(".some-hidden-thing").show();
$(".some-hidden-thing").fadeIn("slow");
$("<li>A new list item</li>").appendTo("#myList");
$("#myList li:last").replaceWith("<li>A new list item</li>");
•Disability is the mismatch between the user and the interface provided
•We all experience disability
•Accessible software = better software
Motivations for Accessibility
•Legislative (ADA and Section 508)
•Business and outreach (reach everyone)
•Accessible is better (for everyone)
It’s just better•“curb cut effect” -- everyone benefits
•accessible technology tends to be
– more interoperable
– easier to re-purpose
– more future-proof
– more robust
– easier to use on a variety of devices
Models for Web Accessibility
•Text-only site
•One site, accessible for all
•Adaptable and Personalizable
Discuss
Models for Web Accessibility
•Text-only site-- really?
•One site, accessible for all --better
•Adaptable and Personalizable --best
W3C: Web Content Accessibility Guidelines (WCAG) 2.0
• Principle 1: Perceivable - Information and user interface components must be presentable to users in ways they can perceive.
• Principle 2: Operable - User interface components and navigation must be operable.
• Principle 3: Understandable - Information and the operation of user interface must be understandable.
• Principle 4: Robust - Content must be robust enough that it can be interpreted reliably by a wide variety of user agents, including assistive technologies.
WCAG is Good Design
Perceivable•Text alternatives for:
– Images
– Time-based media
– CAPTCHAs
•Adaptable presentation
•Use colour and contrast effectively
•Organize content in a meaningful sequence
Searchable, readable, faster
Operable
•Content needs to work with the keyboard
•Provide enough time to read and use
•Help users to navigate, find content, and locate themselves in your siteEasier to use and interact
with
Understandable
•Use plain language
•Define jargon and abbreviations
•Consistent and predictable user interfaces
•Help users avoid mistakesSpeaks to users on their terms; less frustrating UX
Robust
•Use valid markup and standards
•Describe the names, roles, and values of all user interface controls
Sites last longer, and are easier to repurpose
Better UsabilityDesigning for everyone
•Look at what an interaction is like for various users and contexts and then (re)envision how it could be
what is “alt” text?• It is read by screen readers in place of images
allowing the content and function of the image to be accessible to those with visual or certain cognitive disabilities.
• It is displayed in place of the image in user agents (browsers) that don't support the display of images or when the user has chosen not to view images.
• It provides a semantic meaning and description to images which can be read by search engines or be used to later determine the content of the image from page context alone.
•Flash has accessibility problems, but HTML 5 is coming
Video (Cont.)HTML 5
Avoiding Repetition
Avoiding Repetition
Navigation Bar
Avoiding Repetition
Navigation Bar
Main Content
Avoid Repetition
<div id="jumplinks"> <a href="#content" title="Jump to content"></a> <a href="#nav" title="Jump to navigation menu"></a></div>
<a id="nav" title="navigation menu"></a><!-- Navigation bar goes here --><a title="content area" name="content"></a><!-- Main page content goes here -->
Skip Links
Navigation Bar
Main Content
Designing Navigation
•Keep in mind that keyboard navigation is:
•not just for screen reader users
•is linear and one-dimensional
•can be slow and tedious
•Skip links should be available and visible to all
•Place them as high in the page as possible
Navigable Headings
Navigable Headings
Level One
Navigable Headings
Level One
Level Two
Navigable Headings
Level One
Level Two
Level Three Level Three
Level Three
Level Three
Level One
Level Two
Level Three Level Three
Level Three
Level Three
Navigable Headings
Level Four
Navigable Headings
<H1>
<H2>
<H3>
<H4>
<H3>
<H3>
<H3>
Navigating Headings
Navigable Headings
<body> <h1>Fluid: Designing Software that works - For everyone.</h1> <h2>Fluid Daily Build Resources</h2> <div> <div class="fl-col"> <h3>Fluid Integration Examples</h3> <h4>uPortal Instance</h4> <-- Content goes here --> <h4>Sakai Mock-up</h4> </div> <div class="fl-col"> <h3>Infrastructure</h3> ...
// Identify the container as a list of tabs.tabContainer.attr("role", "tablist"); // Give each tab the "tab" role.tabs.attr("role", "tab"); // Give each panel the appropriate role, panels.attr("role", "tabpanel");panels.each(function (idx, panel) { var tabForPanel = that.tabs.eq(idx); // Relate the panel to the tab that labels it. $(panel).attr("aria-labelledby", tabForPanel[0].id);});
Keyboard Accessibility
Keyboard Navigation
•Everything that works with the mouse should work with the keyboard
// Make the tablist accessible with the Tab key.tabContainer.attr("tabindex", "0");// And take the anchors out of the Tab order.$(“a”, tabs).attr("tabindex", "-1");
•Tabindex varies subtly across browsers
•jWuery.attr() normalizes it as of 1.3
• Should be jQuery.prop() as of 1.6
•For all the gory details:http://fluidproject.org/blog/2008/01/09/g
// Make each tab accessible with the left and right arrow keys.tabContainer.fluid("selectable", { selectableSelector: that.options.selectors.tabs, direction: fluid.a11y.orientation.HORIZONTAL, onSelect: function (tab) { $(tab).addClass(that.options.styles.highlighted); }, onUnselect: function (tab) { $(tab).removeClass(that.options.styles.highlighted); }});
Making Them Activatable
// Make each tab activatable with Spacebar and Enter.
tabs.fluid("activatable", function (evt) { // Your handler code here. Maybe the same as
Infusion is Different•Accessibility baked right in
•Carefully designed interactions
•Markup is in your control
•Not the same old MVC
•Supports portals, mashups and CMS’s
CSS Frameworks“If you’re going to use a framework, it should be yours; one that you’ve created. You can look at existing frameworks for ideas and hack at it. But the professionals in this room are not well served by picking up a framework and using it as-is.”