Separating Behavior From Presentation | July 26, 2004

I’ve developed a renewed interest in Javascript the last couple of months, due to articles like these, and more recently, an excellent SkillSwap talk by Jeremy Keith and Richard Rutter.

Over the weekend I decided to make a few little enhancements to the comment form on this site. I tidied up the live preview and added a “Make It Bigger” button to resize the comment field.

I really like the idea of separating behaviour from presentation. On a very basic level the site should still work smoothly if you turn off Javascript, CSS or both of them. For instance, at the moment, If you turn off Javascript, the “Make It Bigger” button won’t display, neither will the live comment preview. However I feel this separation should happen in the code as well as for the benefit of the user.

While scripting this button I realised there were essentially two ways of doing it. I could either affect the style of the form element directly using the style property, or I could apply a class to the field. If I use Javascript to affect the styles directly, that would be mixing presentation into the behaviour layer. To return the form element to it’s initial size I’m setting it’s height to be 100px. If I choose to set the initial height to something different in the stylesheets I have to remember to also alter this in the Javascript.

To get round this I thought about setting a class instead of directly setting a style. That solves the problem of presentation being mixed in with the Javascript. However it presents another problem. Turn CSS off but keep Javascript on and, even though the “Make It Bigger” button gets displayed, It won’t actually do anything.

So it strikes me that, while it’s possible to create separation for the user, the act of setting styles using Javascript makes this separation impossible for the developer.

Posted at July 26, 2004 9:03 AM

Comments

Colly said on July 26, 2004 10:25 AM

Just had to try it out, Andy - the form looks smashing on Safari. I had a few complaints early on about the ‘live preview’ on my site - mostly due to my poor Javascript skills. However, with a few tweaks and a little explanation for the user, the problems have dried up.

Increasing text field size is a must. I don’t know if you’ve used Basecamp from 37 Signals, but it’s the kind of thing they do as standard, and our clients have found it to be a real bonus when copying large chunks of text into the field.

Anyway, on a day when Keith is discussing attention to detail in our designs, these subtle tweaks seem highly appropriate.

Colly said on July 26, 2004 10:29 AM

Ah, same problem I had. The preview shows the HTML (I know you state it will be stripped out) such as coded links (I’d linked Keith’s article http://www.7nights.com/asterisk ) but it’s been removed from my comment. I do think if HTML will be removed, the preview should reflect this. Sorry…

sil said on July 26, 2004 10:52 AM

Immediate thought: if the button doesn’t work without JS, then write it into the document with JS (or hide it by default and then unhide it with JS if you prefer).

James said on July 26, 2004 10:57 AM

Nice idea this. One suggestion:
How about an anchor to the message box? That way users don’t have to scroll all the way back down the page to see the newly resized text area.

Frank said on July 26, 2004 11:17 AM

I love this kind of scripts. But you may want to try using the function with return false; or call the function via void, so the anchor in your link is not executed. It is slightly irritating to jump to the start of your page when all you wanted to do was to make the textarea bigger. :)

Paul said on July 26, 2004 11:20 AM

No need for named anchors - if you return false from the onclick function the link won’t be followed, so the page won’t jump back to top.

Andy Budd said on July 26, 2004 11:36 AM

Colly: True. I’ll have a crack at knocking up a “Strip HTML tags” function next weekend.

Sil: I’ve already done that. The problem is that, If I set a class rather than a style in the javascript, it won’t work with CSS turned off.

James: You mean like the “Jump to the comment form” link below the comment headline?

Frank and Paul: Ah, I see what you mean now. This doesn’t happen on Safari. Missing out return false was definitely an omission on my part, and one I’ll rectify when I get home this evening. Cheers for the heads up.

David House said on July 26, 2004 11:52 AM

PHP, or another serverside language could make your job easier if you go for option 1: have it parse both your stylesheet and JS script, then instead of typing 100px, type <?php echo $textboxinitalsize . ‘px’; ?>. Then you have one config file where you set this value. One value to change.

Paul James said on July 26, 2004 12:38 PM

Correct me if I’m being overly pedantic, but shouldn’t the “Make textarea bigger” link not actually be an anchor tag since it doesn’t link to another resource only executes some behaviour.

If you made it a span, a div, or even a p, then you wouldn’t have the issue of having to return false from your script to wipe out the default action of the anchor tag.

Separating behaviour from presentation is truely a great thing.

Mike P. said on July 26, 2004 12:56 PM

Hey Andy, cool changes (though the ‘Your Contact Details’ is wacky in the always-and-undertsndably-neglected Opera).

One little suggestion/idea. Since the live preview gets tanked with Javascript off, how about coding the standard ‘Preview’ button and using Javascript to set it to ‘display:none’ onload. In that way, users without javascript wouldn’t lose out on the ability to preview, which is a feature that benefits everyone as it allows for ‘better quality’ comment posting.

Also, one thing that I have often wondered (while you’re messing with your forms): why not increase the width of the text inputs for name and web address etc. (example)? The full length of my e-mail address isn’t visible in the box as it is now.

Anyway, just ideas; love the new changes.

Thomas Tischler said on July 26, 2004 3:12 PM

I´ve been doing a lot of work lately that hovers around the same question: If a site won´t work without Javascript (for some reason) anyway, how to get at least decent (semanatic markup) and use JS & CSS to do the layouting.

The same problem: I´ve worked on a couple of system that are “closed”: the server process generating the markup locked to you (as a designer / coder / whatever), but you have to get those quick changes in (and the only option you have is adding a little content (footer - header)). Obviously, JS is not the pain that it used to be, if you are willing to sack NS4.

I´ve come to love the DOM + CSS option for doing quick, otherwise impossible changes.

Terry said on July 26, 2004 6:43 PM

Looks good, however, you forgot to add a return false; before exiting the toggleLink.onclick event. The default behavior of the link has to be disabled. When I click “Make textarea smaller” it takes me to the top of the page because the href property - the lone hash “#”, ion this case - fires right after the onclick.

Andy Cogbill said on July 26, 2004 9:10 PM

Hey Andy, I’ve a few questions concerning these new features. Enlighten me, I prithee.

Issues with jumping to the top of the page aside, I am wondering exactly how much of a feature to convenience ratio this truly is. To clarify, I often wonder about including things like dynamic options and resizers and open / close buttons on a site.

Though all of these features add to the “custom experience” for a user, why not err on the side of caution?

Given this example of the textbox: When was too much textbox a problem? If the person isn’t going to write much, he or she will leave that space blank and hit submit regardless. It’s only in the case of a long-winded person that an actual disconvenience is presented. So why make the loquacious type (me) suffer unnecessarily through an extra click and a scroll down?

It is, in all cases, a nice display of JavaScript.

Andy Budd said on July 26, 2004 10:16 PM

Colly: I’ve added in a regular expression to strip out any HTML tags so the preview should be more “foolproof” now.

Mike P: That would be a good idea Mike. As soon as I can be bothered knocking up a style for the MT template, I may just do that.

Andy: I know what you’re saying. I could post rationalise by saying something about having a large text area by default could stop people seeing the comment preview, but to be honest, I really just think it’s a neat idea. On lots of sites I’ve ended up wishing for a way to increase the size of their comment field (actually I’ve a bookmarklet that does this) so thought it would be fun to give users of this site the opportunity.

Andy said on July 27, 2004 12:35 AM

You wish you could increase text field size because normally the designer chose to make it small. Not because you wanted to change the size, per se, but more because it was too small in the first place.

I guess what I’m saying is that if you’re thinking about a usable text box, you should lean more toward a non-client-side-scripting solution that wouldn’t be an inconvenience to anyone, if given that option.

But hey, you’re the expert ;).

Cameron Adams said on July 27, 2004 2:12 AM

Given that JavaScript is running on 94% of browsers:

http://www.thecounter.com/stats/2004/July/javas.php

The benefits derived from using it to enhance user experience far outweight any inconveniences for users with abnormal browser settings (such as “make text bigger” not working with CSS turned off).

Of course, you should do as much as possible to accommodate those with other settings, hence why JavaScript should only affect users with JavaScript, and not (negatively) interfere with non-JavaScript browsing.

Case in point, I’d point you to my new portfolio site, which features a number of JavaScript enhancements (both of the usability and coolness-types), but you’d be none the wiser and have a full browsing experience without JavaScript.

(P-L-U-G)

Andy said on July 27, 2004 2:25 AM

Cameron:

I totally agree with you on the use of JavaScript. I use it. We (almost) all use it. My point is, if you are thinking about implementing a function, it’s best to think about what effect your new functionality will have if you permanently apply it.

This is not specifically applicable to the textbox example, but I feel that there is a certain niche of “features” I am talking about here.

I wholeheartedly agree that JS should be used to enhance and not to change; that said, I am wondering if, in this particular case, an extra click should be required to make a text box larger while User A doesn’t use it all, and doesn’t care, and User B needs to click to enlarge. If both users can be satisfied without an extra click — by enlarging permanently the text box — I think that choice is more ideal than making the second (User B) click and possibly scroll down.

I hope I’m explaining myself adequately; bottom line for me is people don’t like to click — they want to do their thing and kick out of there.

Cameron Adams said on July 27, 2004 2:49 AM

Well, irrespective of JS, it always comes down to trade offs — what default behaviour will cause the least amount of aggravation for your set of users.

It’s the sort of thing that can’t be answered in your head, it takes real user testing. Of course, you could just try one and see who complains :o]

pid said on July 27, 2004 3:35 AM

You don’t need to hard code/store the height info in the JS if you read the calculated value out, and temporarily store it.

pidster.com/test.html

Jeremy Keith said on July 27, 2004 12:34 PM

Andy, I don’t think you’re thinking things through to their conclusion in your last two paragraphs.

You use the following justification for setting the style directly (rather than just switching the class) in the JavaScript:

“I thought about setting a class instead of directly setting a style. That solves the problem of presentation being mixed in with the Javascript. However it presents another problem. Turn CSS off but keep Javascript on and, even though the “Make It Bigger” button gets displayed, It won’t actually do anything.”

But if CSS is turned off, then your function won’t work in any case regardless of whether you’re altering the style directly or switching classes.

Right now I’m using IE5 on the Mac with JavaScript enabled and CSS disabled: the link “Make textarea bigger” appears but it has no effect… exactly the behaviour you wanted to avoid (I couldn’t find a way to switch off CSS in Safari, Firefox or IE Win).

So you see, there really is no benefit in setting the style directly. You can use JavaScript to switch classes and have those classes defined in your stylesheet. Voila! Separation of behaviour and presentation, negating your pessimistic final paragraph:

“So it strikes me that, while it’s possible to create separation for the user, the act of setting styles using Javascript makes this separation impossible for the developer.”

Now what you really need is a little test to determine if CSS is enabled…

Andy Budd said on July 27, 2004 3:19 PM

Sorry Jeremy. My mistake. What I actually meant to say was that if you disable or override the site stylesheets (with a user stylesheet say), you could be left with a situation where CSS was turned on but chaning the class did nothing. However I guess that’s a highly unlikely scenario.

I guess you can probably test to see if CSS is enables by checking for the existence of the style property (object?)

pid said on July 27, 2004 3:29 PM

Jeremy: does object.style become unavailable when you disable CSS, or does it simply mean that style sheets are not rendered?
Even if CSS is not available elements have height and width (in visual browsers)

(testing for css should be simple, set a property using css that alters the default. e.g. a div = 100% wide by default, so set it to 40px and test it’s calculated width.)

a textarea is a special case because you have the ability to set rows and columns. the javascript function could manipulate those instead if CSS is not enabled.

~

Andy: I think you should redefine this problem, there really are too many questions.
I think this this whole discussion is mired in theory.

Is there a practical case whereby CSS is not available and Javascript is?

If so, define ‘CSS not available’, does this also mean the browser does not support the DOM?

If it doesn’t how do you expect to write Javascript?

sil said on July 27, 2004 7:32 PM

Checking to see if CSS is turned on can be done by styling some element somewhere in the CSS and then using IE’s runtimeStyle property or the DOM’s getComputedStyle function on the element to see if the style is there. This is fiddly and not all that cross-browserly effective, mind.
The other alternative might be to rethink the problem a little; rather than having an explicit “grow the textarea” button (well, a link), why not just automatically grow the textarea as someone types into it? This doesn’t solve the generic “CSS off, JS on” problem, but it might be an adequate solution for this specific problem.

Scott said on July 28, 2004 4:48 AM

This is pretty cool Andy. Would it be to much to ask if I could implement this on my site?