Web Accessibility 101

An actionable list of basic steps you can take to make your web site more accessible.

  1. Use proper semantic HTML markup:
  2. Include text for all meaningful visual elements.
    • All images should have “alt” tags:
        • Alt text should be meaningful and useful.
            • DO:
              <img src="acme-logo.png" alt="Acme">
            • DO NOT:
              <img src="acme-logo.png" alt="Company Logo">
        • If the image is redundant or primarily decorative, leave alt value empty:
          <img src="pretty.png" alt="">
    • Use image replacement techniques to include text inside tags for icons, etc. or else use an aria-label attribute to label the element.
  3. Ensure text and background colors are AA compliant. (includes meaningful visual elements such as icons)
    Test tool: http://accessible-colors.com/

    • text: minimum contrast: 4.5:1
    • “large” 18 point or 14 point bold text: 3.1
  4. Make forms accessible.
    • Use label tags properly.
    • Use either fieldset and legend tags for groups of inputs, such as radio inputs or use ARIA and role attributes.
  5. Use aria landmark roles for main areas of page content.
    If you use semantic markup, the need for some of these is lessened.
    See: https://www.w3.org/TR/html-aria/#allowed-aria-roles-states-and-properties
    See also: http://adrianroselli.com/2017/10/dont-use-aria-menu-roles-for-site-nav.html

    • Useful:
      • role=”banner” (Use on main page header of site. Only one per page.)
      • role=”contentinfo” (Use on main page footer. Only one per page.)
      • role=”search” (Use on search forms.)
    • Not needed with semantic markup:
      • role=”form” (Not needed if you use a “form” tag.)
      • role=”complementary” (Not needed if you use “aside” tag)
      • role=”main” (Not needed if you use “main” tag. Only one per page.)
      • role=”navigation” (Not needed if you use “nav” tag.)

Vue.js “Levels”

Summary of 4 main usage levels of Vue.js from basic to more advanced

Basic vs. Advanced

“Basic” = good for integrating Vue within existing apps using other frameworks such as Angular.js. (Great for gradually migrating legacy apps to Vue.)

“Advanced” = good for brand new web apps being built from scratch

Requirements for Usage:

  • Basic: link to vue.js library script
  • Advanced: Webpack or similar build tool is required in addition to vue.js library


Level 1: Directives (basic)

Very similar to a basic Angular 1 app. “Directives” are used as special attributes within HTML tags to render content, etc. (No need to use components.)

(Level 1 can be used just on its own for simple apps but would normally be combined with the other “levels”.)


<!-- In HTML: -->
<div id=”app”>
        <li v-for=”item in items”>{{item.text}}</li>

Level 2: String Components (basic)

Components are defined as a string within a JS file then used as a custom tag within HTML. (ES6 template literals can be used for nicer formatting.)


// in JS:
Vue.component('alert-component', {
    template: '<div class="alert"><p>This is an alert!</p></div>'

<!-- in HTML: -->

Level 3: Template Components (basic)

Components are defined using “template” tags within the HTML file where they are used. Data and methods are defined in a separate JS file. (Component templates can be referenced as an HTML partial for use within multiple page templates. Best Practice: Use dash in component tag names to follow web component practices.)

NOTE: Levels 2 & 3 are basically alternate ways of doing the same thing.


<!-- in HTML (at top outside of "#app"): -->
<template id="alert"></span>
    <div class="alert"><p>Hello!</p></div>

<div id="app">
    other content ...

// in JS:
Vue.component('alert-component', {
    template: '#alert'

Level 4: Single File Components (advanced)

HTML template, JS code, and any custom styles are included in “component.vue” files for each component.

NOTE: Level 4 is also an alternate way of doing components somewhat similar to levels 2 & 3 but has extra dependencies.


<!-- in “mycomponent.vue” -->
    <div class="alert"><p>This is an alert!</p></div>

    // define methods, etc. used by component
    export default {};

<style lang="scss" scoped>
    /* scoped component styles (optional) */

Scaling CSS for Large Web Sites

This is a PowerPoint presentation for a talk I gave to Fandor as an outside CSS expert at the invitation of their senior product manager. It summarizes recommendations for methodologies and tools useful in writing, organizing and maintaining CSS code. (Fandor afterwards ended up implementing several of my recommendations.)

Scaling CSS for Large Web Sites

Unobtrusive jQuery Popups

A technique for creating accessible popups using simple semantic HTML and unobtrusive jQuery code.


  • Popup content is still accessible when JavaScript is disabled.
  • Popup content is separate from main HTML document which makes adding new popups and linking from multiple pages simple.
  • Easy to use. Doesn’t rely on special classes, IDs or inline JavaScript events.
  • Popup content is loaded through a jQuery AJAX method so there is no page refresh.

HTML for Popup Links (add to your main HTML documents):

<a href="popups/help.html" target="_blank">View help popup</a>

To trigger display of popups you need only add an ordinary link such as above. This links to a separate html document for each popup. The file names for the popup documents can be whatever you like. The only thing to remember is to place all the popup documents into a separate “popups” directory.

Example HTML for Popup:

<!DOCTYPE html>
<meta charset="utf-8">
<title>Help Popup</title>

<div id="popup-wrapper">
	<p>This is some helpful information.</p>
</div><!-- /#popup-wrapper -->

Within your “popups” directory simply add simple html documents such as above for each popup you wish to display. The only important thing here is that all the content within the body must be wrapped by a div with the id “popup-wrapper”.

Example CSS:

#greyscreen {
	background: #000;
	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
	filter: alpha(opacity=50);
	-moz-opacity: .50;
	opacity: .50;
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;

#popup {
	background: #FFF;
	border: 3px solid blue;
	padding: 10px;
	width: 300px;
	height: 350px;
	margin-top: -185px;
	margin-left: -160px;
	overflow: auto;
	position: fixed;
	top: 50%;
	left: 50%;

#popup .close {
	cursor: pointer;
	display: inline-block;
	float: right;

These are just basic styles for your popups to get you started. You can modify these to suit your particular site design.

(NOTE: IE6 doesn’t support “position: fixed”.)

jQuery Code:

$(document).ready(function() {
	// Unobtrusive Popups
	var $popup = $('<div id="popup"></div>');
	var $greyscreen = $('<div id="greyscreen"></div>');
	$('a[href*=popups]').click(function() {
		 .load($(this).attr('href') + ' #popup-wrapper', function() {
		 	$('<span class="close">Close</span>').prependTo($popup);
		return false;
	$greyscreen.click(function() {
	$('#popup .close').live('click', function() {

Make sure to link to the jQuery library from within the head of your main HTML document so the above code will work.

How it works

Two separate divs for a greyscreen effect and for the popup are created dynamically. These get appended to your main HTML document then are hidden until needed. The script then looks for all links pointing to files within the “popups” directory and attaches special actions when the links are clicked. When users click these links the popup and greyscreen divs are displayed and the popup content is loaded into the popup div. A close button also gets appended to the popup. (The reason for adding the close button using jQuery is because if JavaScript were turned off it would have no purpose.) Finally, actions are added to both the greyscreen div and the close button so that once clicked upon they will again hide the popup.

See it in action:

http://www.bentomaster.com/ Scroll down to the bottom of the page and click the “credits” link.

%d bloggers like this: