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) */

Responsive HTML Email Layouts

Things to be aware of

  • No retina images:

    The majority of email clients don’t support CSS for resizing background images.

    (Some email clients also ignore img tag width and height, which makes it unsafe to include retina size images in the html.)

    Reference: www.campaignmonitor.com/resources/will-it-work/guidelines/

  • No media query support / responsive styles in Gmail:

    Gmail does not support style tags. = Responsive styles using media query will not work.

    (Inline styles on each HTML element are also required for this reason.)

  • Media query / responsive support is spotty in general:

    Even for email clients that do support style tags, not all support media queries.

    BEWARE: The meta viewport tag causes emails to render as blank in Blackberry.


  • Make layouts flexible / fluid.
  • Design for lowest common denominator first.
  • Use media queries only as an enhancement; do not rely upon them.
  • Use “inline-block” layout to create a more fluid semi-responsive layout instead of media queries. (Inline block elements will line up if there is room, otherwise they will wrap.)


CSS support for email clients:

Media query support:

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

%d bloggers like this: