JavaScript Triggers

Warning: Experimental/controversial content. Proceed with caution.

Article Continues Below

The front end of a website consists of three layers. XHTML forms the structural layer, which contains structural, semantic markup and the content of the site. To this layer you can add a presentation layer (CSS) and a behavior layer (JavaScript) to make your website more beautiful and user-friendly. These three layers should remain strictly separate. For instance, it should be possible to rewrite the entire presentation layer without touching either the structural or the behavior layer.

Despite this strict separation, the presentation and behavior layers need instructions from the structural layer. They must know where to add that touch of style, when to initiate that smooth bit of behavior. They need triggers.

CSS triggers are well known. The class and id attributes allow you to fully control the presentation of your websites. Although it is possible to work without these triggers, by putting the instructions in inline style attributes, this method of coding is deprecated. If you want to redefine your site’s presentation while using them you’re forced to change the XHTML structural layer, too; their presence violates the separation of presentation and structure.

JavaScript triggers#section2

The behavior layer should function in exactly the same way. We should separate behavior and structure by discarding inline event handlers like <code>. Instead, as with CSS, we should use triggers to tell the script where to deploy the behavior.

The simplest JavaScript trigger is the id attribute:

<div id="navigation">
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</div>

var x = document.getElementById('navigation');
if (!x) return;
var y = x.getElementsByTagName('a');
for (var i=0;i<y.length;i++)  y<i>.

Now the script is triggered by the presence or absence of the id=“navigation”. If it’s absent nothing happens (if (!x) return), but if it’s present all the link elements that descend from it get a mouseover behavior. This solution is simple and elegant, and it works in all browsers. If ids serve your needs, you don’t have to read the rest of this article.

Advanced triggers#section3

Unfortunately there are situations where you can’t use id as a trigger:

  1. An id can be used only once in a document, and sometimes you want to add the same behavior to several (groups of) elements.
  2. Occasionally a script needs more information than just “deploy behavior here.”

Let’s take form scripts as an example of both problems. It would be useful to add form validation triggers to the XHTML, for instance something that says “this field is required.” If we’d use such a trigger we’d get a simple script like the one below.

function validateForm()
{
 var x = document.forms[0].elements;
 for (var i=0;i[this field is required] && !x<i>.value)
    // notify user of error
 }
}

But how do we create an XHTML trigger that tells the script a certain field is required? Using an id isn’t an option: we need a solution that works on an unlimited amount of form fields. It would be possible to use the class attribute to trigger the behavior:

<input name="name" class="required" />if (<strong>x<i>.className == 'required' && !x[ i ].value)
  // notify user of error

However, the class attribute’s proper use is defining CSS triggers. Combining CSS and JavaScript triggers is not impossible, but it can quickly lead to a confused jumble of code:

<input name="name" class="largefield required" />if (
  <strong>x<i>.className.indexOf('required') != -1 &&
  !x<i>.value
)

In my opinion, the class attribute should only be used for CSS. Classes are XHTML’s primary triggers for the presentation layer, and making them carry behavior information, too, confuses the issue. Triggering both layers from the class attribute violates the separation of behavior and presentation, though in the end this remains an issue you have to take your own decision on.

Information-carrying triggers#section4

Besides, triggers can grow to be more complicated than just a “deploy behavior here” command. Sometimes you’ll want to add a value to the trigger. A trigger value would make the behavior layer much more versatile, since it can now respond to each XHTML element’s individual requirements instead of mindlessly executing a standard script.

Take a form in which some textareas have a maximum length for their value. The old MAXLENGTH attribute doesn’t work on textareas, so we have to write a script. In addition, not all textareas in the form have the same maximum length, making it necessary to store the maximum length of each individual textarea somewhere.

We want something like this:

var x = document.getElementsByTagName('textarea');
for (var i=0;i[this textarea has a maximum length])
  x<i>.onkeypress = checkLength;
}function checkLength()
{
 var max = <strong>[read out maximum length];
 if (this.value.length > max)
  // notify user of error
}

The script needs two bits of information:

  1. Does this textarea have a maximum length? This is the general trigger that alerts the script that some behavior is coming up.
  2. What is the maximum length? This is the value the script needs to properly check user input.

And it is here that the class-based solution doesn’t really serve any more. Technically it’s still possible, but the necessary code becomes too complicated. Take a textarea with a CSS class “large” that is required and has a maximum length of 300 characters:

<textarea
  class="large required maxlength=300"
>
</textarea>

Not only does this example mix presentation and two separate sets of behavior, it also becomes tricky to read out the actual maximum length of the textarea:

var max = <strong>this.className.substring(
  this.className.indexOf('maxlength')+10
);
if (this.value.length > max)
 // notify user of error

Note that this bit of code works only when we put the maxlength trigger last in the class value. If we want to allow a maxlength trigger anywhere in the class value (because we want to add another trigger with a value, for instance) the code becomes even more complicated.

The problem#section5

So this is our problem for today. How do we add good JavaScript triggers that allow us to pass both a general alert (“deploy behavior here”) and an element-specific value to the script?

Technically, adding this information to the class attribute is possible, but is it allowed to use this attribute for carrying information it was not designed to carry? Does this violate the separation of behavior and presentation? Even if you feel there is no theoretical obstacle, it remains a complicated solution that requires complicated JavaScript code.

It is also possible to add the trigger to other existing attributes like lang or dir, but here, again, you’d use these attributes to carry information they aren’t designed for.

Custom attributes#section6

I opt for another solution. Let’s take a second look at the textarea maxlength example. We need two bits of information:

  1. Does this textarea have a maximum length?
  2. What is the maximum length?

The natural, semantic way to express this information is to add an attribute to the textarea:

<textarea
  class="large" maxlength="300"
>
</textarea>

The presence of the maxlength attribute alerts the script to check user input in this textarea, and it can find the maximum length of this specific textarea in the value of the attribute. As long as we’re at it we can port the “required” trigger to a custom attribute, too. required=“true”, for instance, though any value will do because this trigger just gives a general alert and doesn’t carry extra information.

<textarea
  class="large" maxlength="300" required="true"
>
</textarea>

Technically there’s no problem. The W3C DOM getAttribute() method allows us to read out any attribute from any tag. Only Opera up to version 7.54 doesn’t allow us to read out existing attributes (like src) on the wrong tag (like <h2>). Fortunately later versions of this browser support getAttribute() fully.

So this is my solution:

function validateForm()
{
 var x = document.forms[0].elements;
 for (var i=0;ix<i>.getAttribute('required') && !x<i>.value)
    // notify user of error
 }
}var x = document.getElementsByTagName('textarea');
for (var i=0;ix<i>.getAttribute('maxlength'))
  x<i>.onkeypress = checkLength;
}function checkLength()
{
 var max = <strong>this.getAttribute('maxlength');
 if (this.value.length > max)
  // notify user of error
}

In my opinion this solution is easy to implement and consistent with the form JavaScript triggers may take: a name/value pair where the presence of the name triggers the behavior and the value gives the script extra information, allowing you to customize the behavior for each individual element. Finally, adding these triggers to the XHTML would be extremely simple even for novice webmasters.

Custom DTDs#section7

Anyone implementing this solution and running the resulting page through the validator will immediately note a problem. The validator protests against the presence of the required and maxlength attributes. It is of course completely correct: the first attribute is not a part of XHTML, while the second one is only valid on <input> elements.

The solution is to make these attributes valid; to create a custom Document Type Definition (DTD) that extends XHTML a bit to include our trigger attributes. This custom DTD defines our special attributes and their proper place in the document, and the validator obeys by checking the document structure against our special flavor of XHTML. If the DTD says the attributes are valid, they’re valid.

If you don’t know how to create a custom DTD, read J. David Eisenberg’s aptly named Creating Custom DTDs in this issue, in which he explains everything you need to know.

In my opinion, using custom attributes to trigger the behavior layer — and writing custom DTDs to define these custom attributes correctly — will help to separate behavior and structure and to write simple, efficient scripts. In addition, once the attributes have been defined and the scripts have been written even the newbiest of webmasters will be able to add these triggers to the XHTML document.

140 Reader Comments

  1. Patrick:
    >… all websites I made so far are valid XHTML >1.1 (no, thanks to IE I’m not sending the right >content-type – lukily it is still only a >”should be”- and not a “must be”-thing…).

    Yes, that goes for XHTML 1.0 (but even than it is considered ‘harmfull’), but NOT for XHTML 1.1. You MUST sent XHTML 1.1 as application/xhtml+xml.
    But maybe you should consider why using XHTML at all instead of HTML.

  2. I’ve been doing development on an internal web application for about 6 years. As the app has grown and we’ve added more forms and a wider variety of controls some of the inconsistencies in the standards have caused issues. For instance something that matches the article: Text inputs have a maxlength while text areas do not. Until recently each page with a text area had a custom script to handle validation of the length. The initial scripts validated length after pressing submit and later scripts tied to the keypress event for a more user friendly cutoff notice. However that’s all wasteful coding and would all be solved by just having a maxlength attribute on the textarea element.

    Add the ability to created your own custom attributes and a DTD to tell other agents about that attribute, mix in a little script, and you have a nice easily reusable component. No longer do the designers have to script a special validation for some textarea by ID or CLASS. Simply loop through the textareas on the page, attach the generic keypress handler and use the maxlength to decide the cutoff point for entry.

    This is all part of how the standards are supposed to work. Custom elements/attributes are the goal of XML and XHTML. It allows for the developer to create a page that might be used one way internally and yet still be readable/usable by someone on the outside.

    We have a redundancy approach to validation. Part of the reason why we do this is to provide the client with friendly interfaces and quicker response times when a validation error occurs. The other reason we do this is because we work within a web service model. Our server side code services more than just our one web client and so we cannot count on those other agents having built in client side validation. We must do validation on both sides.

    One additional factor that people may run into is an inconsistency in the way that “valid” data should display on the client vs. the way that it needs to be sent to a back end. (i.e. on the client it validates and displays as (405) 555-5881, the backend legacy system only allows 4055555881). Or as with dates, users might expect to see and enter 2/5/2005 or 2005/05/02 whereas the back end only allows 2005-02-05 12:00:00Z.

    It’s not always in the best interest of the user to do a round trip for relatively simple validations. The majority of validations can be done on the client side quite easily. Using this article as ONE example can make it even easier.

    Assume that you have all of your validation routines separated out. You create a generic function that loops through the elements on a form when the submit button is pressed. The function checks each elements class for cues on how to validate the field and runs the validation displaying error messages at the end of the validation. The cues would be simple i.e. class=”required date”, class=”optional string”, or class=”required currency”. The notation allows for the script to easily identify between fields that must have data over those where an entry can be validated but can also be empty. It also allows for visual cues to be set via CSS so that the user can easily identify what’s required or not or allow the designer to align fields based on data type.

    You can use the concept with Cocoon, STRUTS, XML/XSLT creating XHTML or PHP or JSP or whatever. It’s not only a this way or that solution.

    It’s all very simple loops and switch/case statements, very simple class identifiers, relatively no learning curve when used within a team setting. Plus you can create very robust functionality that’s extremely easy to maintain and extend.

    E_X_tensibility is the key in all this. We want to keep the content accessible, beautiful, functional, AND be able to add on “perks” like validation, custom controls, or other nice-to-haves, AND be ready for whatever the future holds.

    Stuffing all these properties into some javascript object or reading them out of an XML file via script could end up being very complicated. Lets say that I have a notes section that is reusable and dynamically inserted on many different pages. I would need to assign scripted properties either to the notes body (thus cluttering the structure with JS content) or add it to each parent page via include, js file, or just duplicating code. When you have one such page it may not be much of an issue. Imagine though if most of your site is made up of small reusable components and content that is dynamically included based on user, referrer, or some other criteria. It becomes very messy.

    This is one of the things that many frameworks are available for and attempt to eliminate. Unfortunately it’s usually either at the cost of functionality or at the cost of a high learning curve to use the framework.

  3. You can encode any number of parameters in an attribute and get them out again without having to write tricky parsing code.

    In the example below, “someattrib” could be “class” or some custom attribute you made up using a custom DTD.

    JavaScript can get all the values out using the dangerously powerful ‘eval()’ method:

    There are many other ways to use/abuse eval(). For security reasons, never eval() user-entered data.

  4. > Yes, that goes for XHTML 1.0 (but even than it is considered ‘harmfull’), but NOT for XHTML 1.1. You MUST sent XHTML 1.1 as application/xhtml+xml.

    So it’s my fault while translating “should not”?
    http://www.w3.org/TR/xhtml-media-types/#summary

    English is not my native language, but “should” shouldn’t be the same as “must”, or am I mistaken? “Should” should be a suggestion on how something is supposed to be, but it’s still optional – it must not be that way. As far as I understand it.
    A nice article about this: http://www.xml.com/pub/a/2003/03/19/dive-into-xml.html

    > But maybe you should consider why using XHTML at all instead of HTML.

    Because of better (more specific) rules and because I will went pretty soon to XHTML 2.0 when it’s wildy adopted by clients.
    Another point: I’ve never used HTML, why should I start with it now? That would be the same as if I would start programming in assembly instead of Java.

    However, I don’t think this should be part of this discussion, hm?

  5. I’ve written down a quik sample of what I meant, as I’m still not sure that I’ve been understood…

    http://www.pagosoft.com/preview/formvalidation/

    It should be enhanced, but it should also be enaugh for a small demo.
    It’s fully standard compatible (the XHTML – I didn’t care much about the javascript) and includes the desired functionality (or at least it covers a part of it, it could do more if I had spended more time on creating it).
    And all of that without the need of creating my own DTD.

    (Note: I’ve tested it only with Firefox, so I don’t know if it works in other browsers as well…)

  6. Hello all!
    First of all congrats to everyone involved in alistapart.com, excellent site!
    Second kudos to ppk for his magnificent article! It really got me thinking on a lovely Sunday afternoon.

    Id like to say that although Im a proficient Java developer, I got carried away by your conversation here.
    Ive only fiddled around with .css and .js but Im really jealous of all web designers and the awesome work they produce and that is why I was so excited to get my hands dirty with what you have here.

    However, I have to admit that although I had my solution ready straight after I read all 11 pages’ posts, I struggled to put it in practise since my experience in .js is limited! (took me over half an hour to get my head around .js’ OO implementation!)

    Into the problem!
    *”How do we add good JavaScript triggers that allow us to pass both a general alert (“deploy behavior here”) and an element-specific value to the script?”

    Well to answer to this I would say that we dont! Any attempt will result in an non-standard implementation. Not that it terribly wrong!, just not an orthodox one Im afraid.

    I agree that class and id should only act as “hooks” (well put!) to presentation and behaviour, and not provide a whole lot!
    Namespaces on the other hand sound like a great idea (natively supported by xhtml) only that again (as mentioned) it leads to lots of namespaces around being developed by different developers, hence not standardized.

    So why play with fire? Afterall Javascript is suppose to handle all our behavioural needs why not use it that way? My idea is based around “components” that you define and match the desired behaviour. Simply add an “id” to an element and “hook” it to the component providing that behaviour. Here is my take on the problem.

    http://briefcase.pathfinder.gr/file/cue/32015/380791

    I appologise that I havent got a web server to upload the example for a live demo.

  7. Just noticed that the page displays only in greek.

    In any case just click the button on the left to save the file!

    Sorry about that.

  8. I very strongly agree with the poster “None of your Business”:

    Under the hood of supporting web-standards, this technique undermines them completely. You even carmouflage this act by rewriting the validator itself. Essentially tis is like saying: I want to use “li” as child of “body” but XHTML doesn’t validate me, so I rewrite the Specs for me.

    What to do if future TR’s of XHTML/XFORMS introduce a “validate” attribute and your client complains about two alert windows, one by you, one by the compliant browser?
    No future release is going to “fix” this for your personal by chance XHTML _looking_ markup once standards are broadly accepted.

    Fine, you want to republish all your Markup once future Browsers rely on DTD’s for their rendering. They will _hopefully_ want to know if it is XHTML, XML+XSLT+CSS or RDF they are receiving – and in which version.

    The class and id attributes are perfect places for this Kind of information:

    With “ID”, the element says: You can refer to me by this particular identifier, apply styles and behaviors to me, look up my creation date in a database or do anything you can imagine to me alone.
    With “CLASS”, it says: I am one of these; one of this class of elements which may share styling information or anything. It might even occur that I am one of those strange “maxlength=30” elements which have a maximum length of 30.

    This kind of classification is not wrong, but probably going to outdate faster than, say, “mediumsized”. Various readers suggested to use a custom XML or JS configuration file for this. I agree, it even can be simple:

    validationConstraints = {
    name: { maxlength: 30 },
    anyRequired: { required: true }
    anyMediumsized: {
    maxlength: 400,
    mayContainTheWordFuck: false
    }
    }

    Here I use the any-prefix to specify rules for classes. Of course an XML-Description of these constraints would be even more robust and also usable on the server. But it also would require more work to be done.
    How we apply these rules during client interaction is not of interest here (and also not necessarily complicated).

  9. You missed the point again. Defining a custom DTD is allowed and encouraged by the w3 recommendations (standards). You are not going outside of the standards by adding your own custom attributes as long as you define the DTD. It isn’t rewriting the validator either. It’s letting the validator know how to validate your custom elements/attributes so that they are handled properly. That’s a feature of the validator.

    Again this is the whole premise behind the X in XML and XHTML. Extensible. You can, are capable, may, have permission to, extend the structure when and where necessary to fit your particular use as long as you provide a definition of your extensions.

    Can it be abused? Sure. People could go in and add back in all of the “bad” attributes like align, bgcolor, margin, and the things we hate. That’s why we want to encourage best practices as well as standards. Standards can and will be abused (ALWAYS) (i.e. using tables for layout is still available in standards but generally against best practice).

    Could newer standards create a conflict? Possibly. But it’s simple enough to add in an object sniffer that says if the agent supports validate don’t use custom scripting. Or you could write something on the server to handle these issues (via PHP, JSP, etc.) It’s not a mountain of a problem.

  10. To me it seems that you follow standards by their letters, not by their intention. The future-compatibility is one of the things that drive XHTML forward.
    Why should I bother about adding a sniffer later when I can avoid the problems now? Perhaps I have something else to do when my customers of the old days come and complain?
    Of course XML is extensible, that is no problem, but the mechanism for extension is XML-NS not a copy-paste-dtd.
    Browsers are made to understand and interpret (X)HTML and not any XML that you throw at them (though some do so).
    A custom DTD or XSD might be appropriate in an intranet environment, of course. But in the web, I try to _keep_ things simple and not to do simple tricks now that lead to problems later.

    Let me be a bit extreme now.
    In fact, the method we talk about is a hack: Todays Browsers do not require/check for XHTML, so we give them what we like.

  11. Doesn’t the BitfluxCMS (http://wiki.bitflux.org/) do something like this (correct me if I’m wrong). It uses XML and XSLT as a template engine. This means you could theoretically do something like and then let the server-side XSLT parse it.

  12. It’s not likely that you’re going to spend any significant time building a sniffer mostly because anyone using JS already has one built in or has pulled one from another site and secondly because they are so extremely simple to do. That’s not going to take any time away from more important aspects of a project. And if you were worried about one of your element/attributes being a problem in the future you’d probably already get a plan in place prior to customers complaining.

    An intranet IS the best place for custom solutions like this, but it’s not the only place. It’s up to the developer to determine what the needs of the consumer are and whether the benefits outway any potential risks.

    As far as I know all the major browsers today have support for XML. The current use of XHTML allows for backward compatability and forward extensibility. This means that we can send it as XML/XHTML to apps that understand it and HTML to apps that don’t. Either way it would still be valid per the recommendations. One might say that that is a hack but the way I read it it’s by design.

    It’s the difference betwee “should” and “must”. “Must” is an absolute – you CANNOT do it any other way. While “should” is not absolute – you CAN do it another way but here’s the way we recommend. Too many people read “should” as “must”.

    Yes there are multiple methods for defining document elements, families of elements, and extension modules. DTD, Namespaces, Schema or XSD. In many cases they can be complimentary (i.e. see XHTML modularization). I’m unsure what you mean about a “cut and paste” DTD. DTD’s are just a very simple way to define the document to the user agent. It came out before namespaces and XSD so it’s likely to be understood by a wider variety of industry tools and it’s easily discarded when no longer in use.

    Everyone acts as though this is high maintenance work. If I have 120 XHTML documents sitting on a server and decide to no longer use the DTD or use some attribute does anyone really think I’m going to go into 120 documents and manually strip out each and every occurance. No I’m going to at the very least allow my IDE’s find/replace or regex engine do it for me, create an XSLT file for transforming the docs, or strip a couple of lines out of my JSP/PHP code. We’re talking a few minutes worth of effort if you’ve coded thing right from the beginning. Better yet I’m going to have it already coded so that it can be turned on or off from a property file or from a flag from the user agent.

    I think all the arguments so far against the technique are trying to make it sound much more complex and much more fragile than it really is. The truth is that the approach while being “experimental” is already in use by plenty of people and doesn’t in any way go against the existing standards or even run affoul of any best practices tips I’ve seen to date.

  13. “What is the point of writing to standards if you are just inventing your own?”

    XML : eXtensible Markup Language
    XHTML : eXtensible Hypertext Markup Language

    Extensibility is part of the standard, Jacob.

  14. The XHTML 1.0 Recommendation (the standard) says under “A.1.” (a normative appendix):
    “The W3C recommends that you use the authoritative versions of these DTDs at their defined SYSTEM identifiers when validating content.”
    (http://www.w3.org/TR/2002/REC-xhtml1-20020801/#dtds)

    True: XML is about extensibility. Yet the intended mechanism for this is “XML Namespaces” which plays unfortunately not well with DTDs (that in turn root in SGML and thus do not yet adhere to our nice extensibility philosophy). One would have to use the XSD
    schemes for validation and use namespaces for custom attributes.
    If you just replace the doctype you do not extend XHTML but instead replace it with your own vocabulary. No fancy “valid XHTML button” then, and rightfully so. This is Jacobs point, I guess.

    To Michael Havard: Of course, in most of the cases anyone uses the custom DTD-technique everything will probably go fine.
    But if you have all the changes already prepared that are necessary in case your approach should break in future – why not just apply them now and save the double work?
    And honestly – do you already know what exactly these workarounds will be? I am not talking about just some object sniffer, but about the case where future standards introduce your syntax with a different meaning or using different attribute values (which is more probable). Turning off your behaviors to new agents will not suffice, because the behavior of your page is going to differ among user agents.

    I see my opinions might be a bit standards-zealous, but hey: This site is a member of “The Web Standards Project” after all.
    Of course, on the bottom line I also agree that this method has been marked as being “experimental and controversial”. So anyone who reads the article has been warned, hopefully will consider such dangers, and make the best out of this creative approach.

  15. You can use this code to make sure the user doesn’t paste info to get them over the maxlength of the textarea:

    First add the following to the textarea wher the onkeypress event is added:
    x[i].onpaste = checkLength;

    Then add this to the checkLength function:
    this.value = this.value.substring(0, max);

    You may also want to check the conditional logic to read as it makes sure the max is the true max sent and not one less:
    if(this.value.length >= max){

    Just thought I would share what I changed when using the script, thanks for the article!

  16. I have been using custom DTDs the way described in the article for quite some time – even going as far as putting rollover states for images in the HTML like this (not everybody’s cup of tea):



    For completeness, I would add that many people (mostly backend programmers) consider custom DTDs unacceptable, because they make a website too “top-heavy”, as it adds another 30/50k to the first page a user visits.

    A solution I used in that case is to add a “preparatory” script at the beginning of each page, roughly in this form:

    window.onload = function()
    {
    document.getElementById( ‘x’ ).addAttribute( ‘aname’, ‘avalue’ );
    document.getElementById( ‘y’ ).addAttribute( ‘bname’, ‘bvalue’ );
    //… etc
    }

    Again, this approach may or may not be to people’s taste.

  17. Discussion seems incomplete without including mention of microsoft’s css behaviors extension and .htc files. Far simpler interface, and a truer form of “trigger”, but admittedly probably not useful for the form validation example in this article.

    Lots of good comments though, to which i would add that if your XHMTL is being passed through an XSLT layer, you can output the validator scripts dynamically, before it ever reaches the client.

  18. Peter Paul Koch is not writing here something interesting that has news value.

    In fact he keeps rewriting his more than one and half year old writing

    Forms, usability, and the W3C DOM : Comments
    By Peter-Paul Koch
    Published on May 30, 2003
    http://digital-web.com/articles/forms_usability_and_the_w3c_dom/comments/

    and sells this for newbees as a new article and as seen here very many praise him.
    He just has added doubtful paragraph about custom DTDs and thats pretty much it.

  19. Matching a class name in JavaScript can be tricky, especially if you want to be able to apply more than one class to an element and still not match trick classes (like on the last list item).
    In this example we’re looking for an expression that matches the first four items in the list.
    Note that the last method is the correct approach, the first two are wrong.

    • Crocodile
    • Beaver
    • Pig
    • Monkey
    • Horse

    Following two methods will not work.

    if (element.className == “two”) {
    // Matches first list item only
    }

    if (element.className.indexOf(“two”) != -1) {
    // Matches all list items
    }

    This one however will.

    if (element.className.match(/( |^)(two)( |$)/)) {
    // Matches first four list items
    }

  20. Marek Mänd is not writing here something interesting that has news value.

    In fact he has written absolutely nothing that has any value whatsoever.

    And sells this for newbees as a viable critique of an article he couldn’t have written himself.

    He just has established beyond doubt that he’s jealous and thats pretty much it.

  21. Oops. I fell for the Capital letter meme.

    PPK’s method is just one method. We can rule out behaviours because:
    1. They don’t validate
    2. They are browser proprietary

    Admitted, PPK’s method fails #1 too but it does pass #2. Like it or not I still say that a custom attribute is the most semantically correct way.

  22. As Adrian and Dave pointed out, the ability to use the class attribute for things other than CSS classes is allowed. I’m not sure I follow the idea that this doesn’t allow us to keep the seperation between structure, presentation and behaviour, as the class attribute is already used to “bind” presentation to a structural element, why is this very same technique frowned upon for behaviour?

    Would Peter-Paul feel that having an attribute labelled “behaviour” with the ability to specificy function/object names better suited? Because this is essentially what the classnames are doing, only for presentation.

    The argument that mixing behaviour in with class names doesn’t allow for a clean seperation between structure and behaviour doesn’t really hold water with me, as this is exactly the same technique that is used to associate presentation with structure.

    However, I DO see a need to maybe seperate behaviour assignments from presentation assignments: this will lead to confusion (although were quite fortunate that this wont lead to a problem similar to what namespaces hope to clear up, as a classname could contain a behaviour called “button” and a CSS class called “button”)

    Anyways, fantastic article: some real food for thought there. Keep it up! I look forward to more articles from this author!

    Ben

  23. First off, great set of articles 🙂

    In the entire class vs attribute discussion I personally think that it’s more logical to use the class. It’s just a matter of “abstracting” the behaviour in the same way as we now abstract the presetation through the CSS. To me, writing maxlength=”300″ is about the same as writing a .red, .blew, .green, etcetera CSS class and applying them at random.

    I think that you need to separate the behaviour based on “what it _is_”, not on “what it should do”, exactly like we define CSS based on “what it is” (i.e. header) and not “what it should look like” (i.e. red, center). The most appropriate solution to me would be to simply have a

  24. I’ve marvelled at many of the articles at ALA, and I agree it’s up to any individual designer to press the limits. My only annnoyance here is that ALA has been a champion of ‘standards’ yet when I follow the link to the quirksmode site, it doesn’t recognise firefox, and so I have to view a java-free version of the site. Not standards friendly – from the start. Then, on the browser page, no mention of firefox? What of these 25 million new users? I have no doubt that quirks’ owner is a brilliant programmer/designer etc etc, but this is not doing std comp any favours. Love tips/tricks etc, but in the scheme of things, this article is not much better than an article on some MS proprietory easter eggery – until “standards” catch up. Is ALA now hoping to do what MS did and champion buggy and restrictive, limited access techniques for delivering ‘cool’ content to those who are dumb enough (in a bug infested world) to enable java everything – for the sake of viewing ‘cool’ sites. Btw, I not only had to view an ugly “quirks.. site doesn’t support your browser” 404 style page, but it didn’t even auto-redirect. Not a good look. In ALA’s best defence, this is the first article where I feel ALA may have ‘jumped the shark’. (jump the shark: episode of Happy Days where Fonzy goes to Florida and daredevil style, ski-jumps over a killer shark – 2 part episode.. ratings fell immediately. Keep it real. This article can only add fuel to the fire that is the argument that: code-freaks will always find a way to break things and in doing so, make arguments for MS to fix us up.

  25. A Soul asked:

    >Is ALA now hoping to do what MS did and champion buggy and restrictive, limited access techniques for delivering ‘cool’ content to those who are dumb enough (in a bug infested world) to enable java everything – for the sake of viewing ‘cool’ sites.

    No.

  26. For certain behaviors, I’ve used this technique. I also like it for validation triggered as you go (via onchange) rather than onsubmit.

    But for validation triggered from onsubmit, it doesn’t scale and I don’t like how I’m forced to maintain it. After a form gets sufficiently complex, putting the validation parameters within each element becomes difficult to manage and support. It is much easier, in my experience, to clump all of your validation code together within a single function, even if it means that removing a field now means to have to do it twice (once in the HTML, once in the validation script). This becomes even more important when you have interconditional validation such as “If Status is not draft and Time_Sensitive is checked then make sure the estimated date is populated, valid, and, if marked as high priority, also within the next two weeks.”

    I’ve finally settled on a standard validation script library ( http://www.openntf.org/Projects/codebin/codebin.nsf/CodeBySubContributor/6B4512863D22FC9288256BF900521391 ) and love it (except that I’ve yet to get around to integrating overlib instead of an ugly alert box).

    By the way, a related link you might find interesting mixing presentation with validation by changing the css class name from “RequiredField” to “ValidField” in the onchange: http://codestore.net/store.nsf/unid/DOMM-4RZH6P?OpenDocument Mixing that idea with this article would have some potential.

  27. >yet when I follow the link to the quirksmode
    >site, it doesn’t recognise firefox,

    Why should it have to recognize Firefox? Any site should work in any browser (and mine does).

    >and so I have to view a java-free version of >the site.

    My site is guaranteed 100% Java free because I don’t have the faintest idea how to write Java. Therefore every visitor sees the Java-free version.

    JavaScript is another matter, of course. If your browser doesn’t support the W3C DOM it doesn’t get the JavaScript interface.

    >Then, on the browser page, no mention of >firefox? What of these 25 million new users?

    It mentions Firefox’s parent browser rather a lot, and with lots of details. You do need to know just the tiniest bit about browsers, though.

    >I not only had to view an ugly “quirks..site
    >doesn’t support your browser” 404 style page,

    That’s not what the page says. Please read again.

    >but it didn’t even auto-redirect.

    Where should it redirect to? Isn’t it better to give the visitor a choice of destinations?

  28. >but it didn’t even auto-redirect.

    Good response PPK. Excuse my overuse of metaphors, but redirecting someone in a situation like that would be the equivalent of you driving someone out to the middle of nowhere when they asked you for directions.

    I had a thought about getting around the whole validation problem thing. The only solution to use custom attribues WITHOUT any sort of DTD and to have the page validate is, well, there is none. It’s called a “tradeoff”. We have a lot of them (fixed vs fluid-width, text/html vs application/xhtml+xml, etc). I’m suprised so many developers aren’t used to them by now.

  29. For what it’s worth, to you probably not a lot, but to my clients a good chunk of change :), I thought I’d add my thoughts.

    To start with let me thank PPK and all of you who have taken the time to contribute to this discussion. Not only has this article and comments been informative, but genuinely entertaining to think about. It’s these kinds of issues that make web design and development so interesting to me.

    Let me also say that, like many developers, I strive for standards compliant design and development, but occasionally make non-compliant choices (or I should say compliance with older standards) brought on by the reality of today’s browsers. Even the great Eric Meyers, CSS guru, uses a table for the basic layout of his examples in his books. *gasp* However he strives for CSS usage in all other ways.

    So I’ve decided on the following path for myself:

    1. I’m going to add one additional attribute to my HTML elements, behavior. I think this will add the least and get me the most.

    2. I’m going to keep my values for this attribute as simple as possible. This is how I make my values for the class attribute.

    3. I think I need different “groupings” for presentational and behavioral. For example, I want to display form elements in a single form in a consistent manner, but I want to validate email addresses in forms in a consistent way across pages in an application. I think the combination of IDs, classes, and “behaviors” will give me all the hooks I need to handle the situations I’ve seen presented here and reduce redundancy in my code.

    4. I think this will keep my JavaScript as simple, clean and atomic as possible.

    5. I don’t have a problem with a custom DTD.

    6. I want to keep the details of my behaviors external to my structure. For me I’ve decided to keep these details in my JavaScript file. The reason I went with this as opposed to external XML files, etc, is again to keep my JavaScript and other code as simple as possible.

    So there it is. My “centrist?” view of the ideas presented here.

    Thanks again for providing a space for and participating in this discussion. It’s been very useful for me.

    JD

  30. Very often I find myself using a class I’ve written in PHP to generate forms dynamically, by which I mean, you can generate the forms from any database table without prior knowledge of what the table structure is. It is aware of the field lengths in the database and so for input elements it can dynamically include the maxlength attribute.

    For me this answers the question of whether maxlength information should be considered structural or behavioural: it just doesn’t matter. There just is no other good place to put the information except in the XHTML file when it is generated, either using element attributes or (as someone else suggested) inside a comment near the element.

    I have no problem thinking that the requirements of form fields are structural. What you end up doing when a user breaks the constraints is behavioural. In fact I’d go so far as to say that the choice bewteen textarea and input is more presentational than structural, whereas the validation requirements of the field are more structural than behavioural. The lack of maxlength attribute for textareas is an oversight. But that’s just my take.

  31. I love the idea of using custom attributes. I’ve used classes to achieve this sort of thing in the past, and like the idea of using attributes for this purpose.

    The only thing I might add is the use of namespaces to use attributes within my own namespace. For example js:required as opposed to just required. This would clearly call out that the attribute isn’t defined by XHTML, rather some names space called js. Namespaces in XML is a w3c standard: http://www.w3.org/TR/REC-xml-names/

  32. secured to the referenced articles of exploring those greetings off records,why break point?Systematically my motives toward
    further highlights to my 1st read indicates it
    is coming a-long.Now a natural formatt direct-
    ed already impedes as interluctory attributes
    however what does this mean?Structured analysis impliments my hope to those compiled
    referenced directions.My 1st DTD.reciped add
    xhtml,fol.by an ia},nobones;ah you already have my formula,I’ll consolidate when noid +
    sign is.RF>

  33. Why not just perform a match on the Name of the text field? For instance, I use an onload=init() for the body that searches through all of the input tags that are type=text and adds onblur=validateDate(this) if the name of the text field contains ‘Date’. I do something similar for ‘Phone’ and pretty much anything else I need to validate.

    I can also use the same code to add any number of classes to any or all of the text fields. That way all the structure has to have is “” and onload javascript attaches both presentation AND behavior so changing either requires absolutely NO changes to the structure.

  34. I’ve been following this debate (and the larger debate on alistapart.com) over structure vs. presentation.

    I have to say that part of me that wants things to be logical and efficient leans toward defining my web pages semantically, and then using CSS to control layout and design.

    However, the realist in me knows that this is a practical impossibility. Anyone that has designed a slightly complex website – especially one that involves variable formatting between pages – knows that writing perfectly semantically driven code is impossible. We always end up making little compromises to get our layout to work right. stuff like

    is not semantic – but sometimes its the only way to deal with floated columns. Look at the code for this website – try and argue that its semantic not presentational! If alistapart.com, a magazine which is dealing with very spefic and predicable data chunks and consistent presentation, can’t write semanic code who can?

    The funniest thing is that we can kill ourselves designing these perfectly defined documents, but don’t all websites designed this way tend to end up looking very similar? Why? because if we design our documents semantically we lose a lot of layout flexibility. We can use CSS to achieve complex designs that look even better than table based designs – but websites designed this way are never defined semantically – and never will be, because at the end of the day, web pages are presentational documents. We don’t see similar arguments in the print layout community for semantically designed documents – so why in the web design community?

    I think the larger debate is an interesting one, but that in truth it applies to only a small subset of website applications, such as content management systems; and that even within this small subset of applications there is a lot or room for flexibility in how one strikes a balance between semantic logic and presentational necessitates.

    For MOST websites, none of this should be a concern. We can argue all we want if maxlength=200 is presentational or structural, and those people that design websites with the maxlength=200 hidden somewhere deep in the JavaScript because they have a firmly rooted ideological belief that it is structural not presentational – bring me a website that has no

    ’s I’ll be very impressed – but more surprised.
  35. Justin, your point is well made and quite on target, however, it is possible to make completely semantic sites and then, via JavaScript, add not only the behaviours, but also any “presentational” elements such as the divs you mentioned.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

I am a creative.

A List Apart founder and web design OG Zeldman ponders the moments of inspiration, the hours of plodding, and the ultimate mystery at the heart of a creative career.
Career