1 | 2 | 3 | 4 | 5 | 6 | 7

6 - 10   [31]

Accessibility Assessment Report

This post does not relate to any other topics

In light of the DRC Report back in April, further alarming reading comes from Comparative Assessment of Web Accessibility and Technical Standards Conformance in Four EU States:

It is not just that Web technology is not being applied positively to improve opportunities and capabilities for users with disabilities. On the contrary, as Web services become more pervasive and essential, it means that those with disabilities in our society will increasingly suffer further disadvantages in accessing information and online services. Carmen Marincu and Barry McMullin

A sample of 4877 websites from Ireland, United Kingdom, France and Germany, selected from the Open Directory, were tested with Bobby:

  • 94.0 percent of the Irish sites, 94.5 percent of the U.K. sites, 95.6 percent of the German sites and 98.6 percent of the French sites failed Bobby at the minimal accessibility level (WCAG-A)
  • 99 percent of U.K. sites and 100 percent of the Irish, French and German sites failed Bobby at the professional accessibility level (WCAG-AA)
  • All (100 percent) of the sites failed Bobby at the maximum accessibility level (WCAG-AAA)

Posted on Aug 03, 2004 at 20:17:35. [Comments for Accessibility Assessment Report- 0]

WCAG Working Draft Updates

Also relates to Web Standards and CSS Design

New Working Drafts of WCAG 2.0 and accompanying HTML and CSS techniques have recently been published:

Posted on Aug 03, 2004 at 20:16:59. [Comments for WCAG Working Draft Updates- 0]

Automating Placeholder Text In HTML Forms

Also relates to DOM Scripting

One of the stumbling blocks for achieving Triple A Conformance of the WCAG 1.0 is Checkpoint 10.4 regarding placeholder text for form controls:

Until user agents handle empty controls correctly, include default, place-holding characters in edit boxes and text areas.Checkpoint 10.4 Web Content Accessibility Guidelines 1.0

This is actually an interim solution to accomodate certain legacy assistive technologies that can not handle empty form controls. However, accessibility can be improved if, in meeting this checkpoint, the placeholder text is informative text that assists the user with the information they should enter. For example:


<input type="text" id="name" name="name"
       value="Please enter your name"/>
<input type="text" id="tel"  name="tel"  
       value="Your Phone Number - 01234 123123"/>

This information can be valuable to the user where a complex form is layed out with tables and the label may be detached from the field it relates to. To ease the form completion process a Javascript event may be attached to the form field to clear the placeholder text when focus is received.


<input type="text" id="name" name="name"
       value="Your name"/
       onfocus="if(this.value=='Your name')this.value=''"/>

With a multi-field form the inclusion of a large number of onfocus event handlers will bloat the HTML so this behaviour should be defined in a separate script file.


var helpers = ['Please enter your name', '…', … ];
function addFieldListeners() {
  var elems = document.forms[0].elements;
  for (var i = 0; i < elems.length; i++) {
    if (elems[i].type == "submit") {continue;}
    elems[i].onfocus = function(evt) {
      evt = (evt) ? evt : 
                    (window.event) ? window.event : null;
      if (evt) {
        var elem = (evt.target) ? evt.target : 
                    (evt.srcElement) ? evt.srcElement : null;  
        if (elem) {
          var value = elem.value;
          for (var i = 0, m = helpers.length; i < m; i++) {

            if (value == helpers[i]) {
              elem.value = "";
            }              
          }
        }
      }
    }    
  }  
}

Here an anonymous function is assigned to each form field and when focus is recieved the value is tested against an array of predefined placeholder text strings. This code could be cleaned up by assigning a new array search function to the Array object prototype property, and a global function for retreiving the element that received the event (since other behaviour in the document may require this). This solution will suffice, with new placeholders just added to the helpers array, but in larger projects this in itself can become quite a tiresome process - take a content management system as an obvious example.

Working on a CMS solution just the other day I thought about using the title attribute of the input field to store the placeholder text. My initial thinking was that this could still provide the helper information to the user after they had set focus on the field. If they were jumping around a large form, the user should not be expected to remember the helper text once it has been cleared. Plus the purpose of the title attribute is to provide additional information for the element - exactly what the helper/placeholder text is doing in this scenario. So, this time, using the closure technique discussed previously, the following:


<input type="text" id="name" name="name"
          accesskey="n"
          title="Please enter your name" 
          value="Please enter your name" />

could be handled with the following field listener:


function FieldListener(elem) {
  this.elem = elem;
  this.helper = "";
  
  var me = this;
  
  this.init = function() {
    this.helper = this.elem.getAttribute('title');    
    // Scott Andrew's addEvent method at 
    // www.scottandrew.com/weblog/articles/cbs-events
    addEvent(this.elem, "focus", this.clear);
    addEvent(this.elem, "blur",  this.redisplay);
  }
  
  this.clear = function(evt) {
    if (me.helper == me.elem.value) {
      me.elem.value = "";  
    }
  }
  
  this.redisplay = function(evt) {
    if (me.elem.value == "") {
      me.elem.value = me.helper;  
    }  
  }
}

The FieldListener object stores the title attribute value in a member variable when it is instantiated, then when the field receives focus, the field value is compared against this member variable. Functionality can be extended by redisplaying the placeholder text if the field is still empty when the user moves focus elsewhere - the FieldListener.redisplay() function achieves this. This event listener can be bound to each form field (along with other behaviours - eg pseudo CSS, validation) as follows:


function register(collection) {
  var i, elem, listener;
  for (i = 0; elem = collection.item(i++); ) {
    if (elem.nodeName == "INPUT" && 
        elem.getAttribute("type") != "text")
        {continue;}
    listener = new FieldListener(elem);
    listener.init();  
  }
}
function __init() {  
  if (document.getElementsByTagName) {
    var input_flds = document.getElementsByTagName('input');
    register(input_flds);
    var textarea_flds = document.getElementsByTagName('textarea');
    register(textarea_flds);
  }
  else {    
    nastyHackToHandleNonW3CDom();
  }
}

// see Simon Willison's addLoadEvent entry at 
// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
addLoadEvent(__init);  

An alternative function would need to be provided for legacy browsers that do not support DOM2 (Netscape 4.x, MSIE 4.x). Perhaps just selecting the placeholder text on field focus so the user can delete it if they wish to (DOMElement.select()) may suffice. To round off, this modular solution provides a simple automated approach to handling placeholder text that does not require the author to expicitly register the text within the Javascript code - the whole process is automated based on the value of the title attribute.

Posted on Jul 01, 2004 at 16:34:43. [Comments for Automating Placeholder Text In HTML Forms- 4]

CSS Negative Margins Algebra

Also relates to CSS Design

Defining CSS layouts with negative margins requires a high level of precision to ensure that all siblings are cleared effectively. Pie-fecta was the earliest example of this technique, demonstrating a complex set of dependant CSS rules. But, this should not make the technique so daunting that it is ignored. Ryan Brill's recent publication provides an insight into the simpler side of the technique. Only glimpsed at in his article, negative margins offer one huge benefit that should put table-based design to rest once and for all - flexible document structure.

As a scenario take the following document structure that defines the main content areas for a three column layout:


<div>
<div id="center">  </div>
<div id="left">    </div>
<div id="right">   </div>
</div>

Since the central column contains the main content, I have chosen to lead with it in the document structure for accessibility and SEO. The left column contains the navigation menu, and the right column a subsidiary menu/content (or perhaps advertising). Deeper into the site hierarchy, I decide to utilise the right column to bind additional information to the central column (eg links to related articles, or recent material). However, the document structure will now be detached since the main navigation (in the left column) separates the two bound columns. While this is of little relevance on a styled page where the columns are always in the same position, it is counter-intuitive for assitive devices or an intelligent search bot, where the style rules do not apply. The solution is to flip the left and right columns in the document tree. And the good news is with negative margins this can be achieved without changing a single rule in the underlying CSS!

So now it is time for the mathematics. I started this entry by emphasising the importance of precision, and there is no better way to ensure this than some CSS algebra.


α = column 1 width (#middle)
β = column 2 width (#left)
γ = column 3 width (#right)

Δ = predefined balancing unit

#middle {
  float:left;
  width:α;
  margin:0 [-(α+(β-Δ))] 0 β;
}

#left {
  float:left;
  width:β;
  margin:0 0 0 -Δ;
}

#right {
  float:right;
  width:γ;
}

The middle column is given a negative right margin to the value of its own width (α) plus the left margin (β) less a predefined unit (Δ). This provides the entire width of the parent container less one unit on the left for the middle column's siblings. The left column is floated with a negative left margin to the value of the predefined unit to place it flush left to the parent. The right column is simply floated right. The predefined unit is arbitrary, but obviously should be less than the width of the left column - I generally use a unit of 1 (eg 1em, 1px, 1%). The underlying premise behind this principle is explained in the CSS2 Specification.

A float can overlap other boxes in the normal flow (e.g. when a normal flow box next to a float has negative margins) Visual Formatting Model, CSS2 Specification

Now, the right and left column can be reversed in the document tree without any need for additional rules or any detrimental affect on the presentation. A clearing element will apply to all three columns - allowing any column to be longest (resolving the inherent problem with absolute positioning).

Here are a few examples:

These examples have been tested across all the major PC browsers, but I have not had an opportunity (or time) to test them on Mac and Linux. The only major bug arises in IE6 for a contained liquid width (ironically not IE5.x). There is also a gotcha involving preformatted text in the IE browsers for both liquid and fixed widths (explained in the above examples). The only hack required accounts for the IE Doubled Float-Margin Bug by declaring the containers' display inline.

Any layout containing floats has potential for browsers discrepancies (eg Peekaboo bug and IE Float Margin as above) and potential self-destruction. So far on quite complex test examples I have found this technique to work adequately cross browser. Plus, in theory the technique can also be applied to sub-containers - so long as the formula is balanced the columns can be cleared.

As for colouring the columns, the Faux Columnstechnique or a similar set of containing wrappers is required. IMHO, such non-semantic containers should be avoided in the document. This can be resolved by utilising presentational javascript. The presentation should first be made accessible to users with no javascript, then an onload event handler can be attached to the window object which performs the wrapping. Here is a little example, which I intend to write up soon - the Elastic Fantastic.

Posted on Jul 01, 2004 at 00:59:57. [Comments for CSS Negative Margins Algebra- 1]

Accessible Javascript Event Handling

Also relates to DOM Scripting

Thanks to Simon Willison's interesting post on closures in Javascript I recently rediscovered W3Future's article on applying closures to event handling methods. This article provides a very illuminating resolution to the common problem in separating the behaviour of a web page from the structure - the method assigned as the event handler to an object does not contain a reference to the object itself (at least not in IE). Traditionally this could be solved with a cross browser concoction of event.target, window.event.srcElement and bubble management.

The closure paradigm is a very adaptable and dynamic solution, that not only allows clean cross browser access to the source element, but is readily extensible in an object oriented environment:


function EventHandler(elem) {  
  this.elem  = elem;
  this.evt   = "";
  
  this.register = function(handler, fn) {
    addEvent(this.elem, handler, fn);  
  } 
  
  this.invoke = function(evt) {}
  
  this.cancel = function() {}
  
}

function FieldHandler(elem) {
  var me = this;
  this.base = EventHandler;
  this.base(elem);
  
  this.mouseon = function(evt) {
    me.invoke(evt);
  }
  this.mouseoff = function(evt) {
    me.invoke(evt);
  } 
}
FieldHandler.prototype = new EventHandler;      

handle = new FieldHandler(DOMElement);
handle.register('mouseover', handle.mouseon);
handle.register('mouseout', handle.mouseoff);

The me variable provides access each instance of the FieldHandler object, which would otherwise be unavailable. (Note EventHandler::register it uses Scott Andrew's Cross Browser Event Handling routine to assign the event listeners.) Another use might be to assign the callback function for the event at runtime based on the event type:


function EventHandler(elem, me) {  
  
  var me = this || null;
  
  // …
  
  this.invoke = function(evt) {
    me.evt = (evt) ? evt :
      ((window.event) ? window.event : null);
    me.assign();
  }
  
  this.assign() = function() {}
  
  // …  
}

function FieldHandler(elem) {
  
  this.base(elem, me);

  // …
  
  this.assign() = function() {
    switch(this.evt.type) {
      case 'mouseover':
        this.mouseon();
        break;
      case 'mouseout':
        this.mouseout();
        break;
    }
  }
  
  // …

}

// …   

handle.register('mouseover', handle.invoke);
handle.register('mouseout', handle.invoke);

The one stumbling block I fell over briefly was the cancelling of an event. A typical example being a stylesheet switcher where a link is supplied to switch the CSS on the server where Javascript is not available. In a Javascript environment the HTTP request should be cancelled. Sadly, using event attachment to assign handlers, return false will not cancel the operation. Information on this hurdle appears to be lacking on the web, but fortunately the solution was nestled in the DOM2 Events Specification:


this.cancel = function() {
  if (this.evt) {
    if (this.evt.preventDefault) {
      this.evt.preventDefault();
    }
    this.evt.returnValue = false;        
  }
}

In the W3C event model preventDefault called anywhere within an event processing tree will cancel the default event. For the Exploders falsify the returnValue property for the event.

These are very basic examples, but just in an afternoon I discovered immense power in this method without the need to hack cross browser scripts (I have tested the method successfully across all the major PC browsers - IE5.x, IE6, Moz, Opera). I have started work on integrating the EventHandler class into my form validation scripts and will hopefully present this as a more detailed and explanatory article when I find more time. The biggest benefit of the method is it allows for the behavioural scripts to be totally detached from the mark-up for a web document, thus only serving javascript content where it can be handled while achieving a more lightweight document.

Posted on Jun 20, 2004 at 03:39:51. [Comments for Accessible Javascript Event Handling- 6]

Breadcrumbs Trail

[ Home ] -> TW Blog -> Accessibility
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.018 seconds