Christian Heilmann

You are currently browsing the archives for the General category.

Archive for the ‘General’ Category

What does adding empty links to a document do in terms of accessiblity?

Thursday, January 24th, 2008

Over at the YUI blog, I managed to convince accessibility researcher and all-out good colleague Mike Davies to publish a research on how empty links in the document affect accessibility.

Why would you ever add empty links to a document? Well, it is part of a Microformat, in this case the include pattern. Over to Mike:

The Microformats group have created an include pattern which is a mechanism for including a portion of data from one area of a page into another area on the same page. Essentially, it’s a means of preventing the duplication of data.
A good example of this is a page that lists all the reviews done by one person. Instead of every review having to duplicate the reviewer details, we can use the include pattern to define the reviewer once, and include it into each review. No needless duplication.
The main technique being advocated as an include is the humble link, but in an effort to minimise duplication of content, the example is an empty link; a link with no link text:

So if you wondered about this microformat and accessibilty, go on over to the yuiblog and have a read.

[tags]accessibility,links,microformats[/tags]

Will not link for pocket money

Friday, January 18th, 2008

It seems that there is a rather annoying group of people sending random emails about text link advertising to bloggers. I’ve got some, and Ed Eliot sitting next to me got the same. This wouldn’t be an issue, after all I think I should get some reward for keeping this up for years and fending off spammers and hacking attempts while I’d really just want to concentrate on what to write here. The crux of the matter is the ridiculous terms and conditions these new kids on the advertising block ask for:

  • Can you add a link to the following articles … for the lifetime of the web site
  • I will pay you $10-15 dollars for each link as a one-off payment

My first confusion there is “lifetime of the web site”. Does this mean I can shut it down tomorrow and claim it caught a cold and died? Secondly a ONE-OFF payment of $10 for an infinite time of showing an ad a client probably pays you at least $100 a month for?

I appreciate that some people try to get a foothold in a very competitive market like online advertising (and I got an email answer like that when I pointed out the slight discrepancy of what other companies pay for a monthly view vis-a-vis the one-off I could spend in Starbucks on a coffee and a muffin) but please be reasonable and don’t think that people who have high-traffic sites didn’t do research what value a text link from their sites has. We do get punished by Google for adding them, too, and it should be worth our while.

An attempt for a more accessible edit-in-place solution

Friday, January 4th, 2008

Today I will try to find a more accessible way to provide an edit-in-place script. The solution described here is probably not ready for real life yet, please test it in different environments and provide fixes. It is licenced with creative commons share-alike, so go nuts!

I really like the idea of edit-in-place. Probably the most used example of edit-in-place is flickr which allows you to click any heading or description when you are logged in to directly edit it. The reason I like edit-in-place is that it makes it a lot easier for users to describe things, which hopefully results in more accessible and easier to find web sites (after all text is what gets indexed and what is available to everybody). The drawback of edit-in-place is that a lot of solutions are not very accessible. They add a click handler to elements that are not necessarily available to assistive technology and are not at all accessible with a keyboard.

A non-scripting solution attempt

Technically the easiest solution to create an accessible edit-in-place would be to use input fields with labels and use CSS to make them look like the other elements. The code could be the following:

<h1 class="editable">
  <label for="mainheading">Heading:</label>
  <input type="text" id="mainheading" 
         value="Otters in eastern Europe">
</h1>

And the CSS:

.editable label{
  position:absolute;
  top:0;
  left:-9999px;
}
.editable input{
  border:none;
  font-family:arial,sans-serif;
}

But alas! Is it more accessible? I am not sure, as the semantic goodness of a heading is disturbed. I am quite sure search engines will frown upon it and as screen readers work differently in forms mode than in reading mode it might even be more confusing. So let’s scratch that.

Making it work unobtrusively

The next step would be to use a normal heading and somehow connect it with a form field somewhere else in the document. The cool thing about this is that we have something like that in plain HTML: targeted links. For example:

<form id="editform" action="servermagic.php">
<h1 class="editable">
  <a href="#editheader">Edit me, wuss!</a>
</h1>
<p class="editable">
  <a href="#editdescription">Me as well, do it!</a>
</p>
<div id="editingsection">
  <p>
    <label for="editheader">Content of main heading:</label>
    <input type="text" id="editheader" name="editheader">
  </p>
  <p>
    <label for="editdescription">Content of description:</label>
    <input type="text" 
           id="editdescription" 
           name="editdescription">
  </p>
  <p><input type="submit" value="Save Changes"></p>
</div>
</form>

This works without JavaScript (but somehow my Firefox does not highlight the form field when you hit the link, does anyone know why? Please comment!). All it needs to turn it into a working version of edit-in-place is a JavaScript. What the script does is:

  • find the section with the ID “editsection” and hide it from view
  • find all elements with the class “editable” and add a click handler pointing to an edit function
  • override the submit event of the form to point to a store function

The edit function should do the following:

  • check if another element is already being edited and focus that if there is one
  • Get the ID of the form element from the href of the targeted link
  • set the value of the form element to the content of the element
  • set an “edited” style to the original element to hide it
  • show the form field where the original link was
  • focus the form field
  • tell the main script what element is currently being edited

The store function should:

  • check if there is an element edited (to avoid overriding normal form submission)
  • set the content of the targeted link to the value of the field
  • move the form field back to where it came from
  • set the focus back to the link
  • store the content asynchronously (not implemented here)
  • stop the normal form submission
  • reset the edit state of the script to none

Following is the script that does exactly that. I am using the YUI in this example as I like to concentrate on writing scripts rather than worrying about browser problems. That said, notice that you need to wrap form field focus in a timeout in Firefox, what’s with that?

YAHOO.namespace('ch');
YAHOO.ch.editinplace = function(){
 
  /* Names and IDs used */
  var namesandids = {
    editsection:'editingsection',
    edited:'edited',
    hidden:'hidden',
    editable:'editable',
    form:'editform'
  };
 
  var YE = YAHOO.util.Event,YD = YAHOO.util.Dom;
 
  var edit = {};
  var editingsection = YD.get(namesandids.editsection);
  if(editingsection){
    YD.addClass(editingsection,namesandids.hidden);
 
    function doedit(e){
      if(!edit.target){
        var t = YE.getTarget(e);
        if(t.href){
          var fieldid = t.getAttribute('href').split('#')[1];
          var field = YD.get(fieldid);
          this.appendChild(field);
          field.value = t.innerHTML;
          YD.addClass(t,namesandids.edited);
          setTimeout(function(){field.focus();},10)
          edit = {target:t,field:field,id:fieldid};
        };
      } else {
        setTimeout(function(){edit.field.focus();},10)
      }
      YE.preventDefault(e);
    };
 
    function store(e){
      if(edit.target){
        edit.target.innerHTML = edit.field.value;
        YD.removeClass(edit.target,namesandids.edited);
        editingsection.appendChild(edit.field);
        edit.target.focus();
        // Ajax Magic here, you can used edit.id as the id 
        YE.preventDefault(e);
        edit = {};
      };
    };
 
    var edits = YD.getElementsByClassName(namesandids.editable);
    YE.on(edits,'click',doedit);
    YE.on(YD.get(namesandids.form),'submit',store);
 
  }
}();

Try out the solution and Download the example page with the script as a zip and tell me what you think!

Tested in Firefox, IE7 and Opera 9 on PC, please get me some more feedback on other systems and browsers.

[tags]unobtrusive,accessibility,editinplace,interface[/tags]

Let’s make 2008 the year of embracing the server side with Ajax

Sunday, December 30th, 2007

I am always fascinated by the amount of Ajax tutorials and examples out there that totally ignore the backend part of an Ajax app. A lot of times you’ll find page-long ravings about the 6-7 lines of JavaScript that allow the client to make an HTTP request but when it comes to talking about the proxy script needed to allow for cross-domain requests a lot is glossed over as “you don’t need to know this, just use this script”.

That would not really be an issue if the scripts offered weren’t that bad. Unsanitized URLs are the main attacking point for cross-server-scripting attacks. If you use a PHP_SELF as the action of your forms you shouldn’t be too confused about a lot of mail traffic from your server or text links on your site you didn’t sign off and get money for.

The other thing about Ajax information on the web that amazes me is that people keep complaining about the slowness and problems with converting data from one format to another on the client side. Let us not kid ourselves: even after all the articles, books and podcasts about Ajax we still have no clue whatsoever what a visitor uses to look at our products. We cannot tell for sure what browser is used, if there is assistive technology involved or anything about the specs of the computer the browser runs on. This to me makes the client side the least preferable place to do heavy calculation and conversion.

The server side, on the other hand, is in your control and you know what it can do. Complex regular expressions, XSLT conversion, all of this is much easier to do on the backend – and you know that the text encoding will work to boot. A lot of complexity of Ajax apps is based on bad architecture and design decisions and on relying on the client side to provide necessary functionality.

So if you ask me what the ratio of client-to-server code of a good Ajax app is I’d say 30% client and 70% server. The 70% on the server should be used to provide security, non-JavaScript fallback functionality (yay accessibility) and conversion of data to small, easy-to-digest chunks for the client (think HTML and JSON). The 30% client side code should mainly be used up to enhance the usability of the product and make it easier for your visitors to reach their goals.

So here’s my plan for 2008: whenever I talk Ajax I will try to cover as much backend as frontend. I’ll do this by partnering with other experts as I myself created some terrible PHP in the past. I hope that others will follow that example as Ajax is a wonderful opportunity to bridge the gap between frontend and backend engineering – and we have to talk to each other to create a good app.

[tags]ajax,development,php,security,xss,architecture,tutorials[/tags]

The seven rules of unobtrusive JavaScript

Monday, November 12th, 2007

I’ve written a lot about unobtrusive JavaScript before, but I never really held a workshop about it. Well, now as part of the Paris Web Conference later this week in Paris, France I am giving one which is already sold out and I am very much looking forward to it.

As part of the workshop I prepared my materials and wanted to have a nice outline to follow. I took this as an opportunity to build up on the older materials and the outcome of this exercise is that I managed to define the rules of unobtrusive JavaScript, which are:

  • Do not make any assumptions
  • Find your hooks and relationships
  • Leave traversing to the experts
  • Understand browsers and users
  • Understand Events
  • Play well with others
  • Work for the next developer

I’ve explained them all in some detail here: The seven rules of unobtrusive JavaScript

After the workshop I will also add the code demos with some more detail, but that’ll be most probably after @media Ajax.

I hope this is helpful to you, it is creative commons, so use it for good.

[tags]javascript,unobtrusive,unobtrusivejavascript,methodology,planning,webdevtrick,scripting,bestpractices[/tags]