Keeping the hot side hot and the cold side cold

Written byAaron Gustafson. 34 comments

Aaron Gustafson

Aaron Gustafson runs a web consultancy, Easy! Designs, and is a member of the Web Standards Project (WaSP) and the Guild of Accessible Web Designers (GAWDS). He serves as Technical Editor for A List Apart, and has spoken at numerous conferences including An Event Apart and Web Directions.

Applying 1980s’ fast-food logic to JavaScript and CSS separation: techniques for keeping your presentation out of your scripts.

If, like me, you lived through the 1980s in the United States and watched any tele­vi­sion at all, you prob­a­bly recall a pre-​​Seinfeld Jason Alexan­der pranc­ing about, singing the won­ders of a new ham­burger from the golden arches: the McD.L.T.

The McD.L.T. (which stood for McDonald’s Let­tuce & Tomato) was a bril­liant con­cept: it quar­an­tined the hot ham­burger patty in one com­part­ment and the cold, crisp let­tuce and tomato in the other, leav­ing the con­sumer to com­bine the two halves for the full McD.L.T. ‘experience’.

Through this sep­a­ra­tion, McDonald’s was able to cre­ate a much more enjoy­able prod­uct and we, as web design­ers and devel­op­ers, can learn a lit­tle some­thing from this concept.

Sep­a­ra­tion is at the heart of the web stan­dards movement.

Sep­a­ra­tion of con­tent from pre­sen­ta­tion came first, and we began swap­ping FONT ele­ments for style sheets. The next major move­ment was the sep­a­ra­tion of con­tent from behav­iour, which urged us to write unob­tru­sive JavaScript. Unfor­tu­nately, the final mem­ber of the web stan­dards sep­a­ra­tion tri­umvi­rate – the sep­a­ra­tion of behav­iour from pre­sen­ta­tion – has yet to take hold, but the tide is start­ing to turn.

Where’s the beef?

JavaScript (and CSS, for that mat­ter) first became pop­u­lar as com­po­nents of DHTML. It was in the con­text of DHTML that styles and scripts first become entan­gled and, regret­tably, the knot they formed has proven par­tic­u­larly dif­fi­cult to untie.

As you know, DHTML was not a lan­guage unto itself, but rather an appli­ca­tion of JavaScript for manip­u­lat­ing the DOM, to gen­er­ate and alter both markup and styles on the fly. Here’s a ridicu­lously sim­ple exam­ple of early DHTML:

  1. <a href=“foo.html”;
  2.     style=“color:blue;”
  3.     onmouseover=“‘red’”
  4.     onmouse­out=“‘blue’”>Foo</​a>

Main­te­nance of code like this was a night­mare because any change in the behav­iour required you to muck about in the markup.

If tasked with cre­at­ing this same inter­face today, the obvi­ous choice would be to add

  1. a, a:link, a:vis­ited {
  2.   color: blue;
  3. }
  4. a:hover {
  5.   color: red;
  6. }

to an exter­nal stylesheet and avoid using JavaScript alto­gether; so, why didn’t DHTML coders do the same? Well, the likely answer is that CSS was so poorly under­stood at the time that the folks writ­ing DHTML weren’t aware of the other options avail­able to them. But we know bet­ter … don’t we?

It’s bet­ter here

Mod­ern JavaScript, even the unob­tru­sive sort, still employs the same basic means of style manip­u­la­tion. The only dif­fer­ence is that in today’s JavaScript, the STYLE attribute manip­u­la­tion is likely to exist in an exter­nal file, where you’ll find some­thing akin to this:

  1. for( i=0; i<objects .length; i++){
  2.   objects[i].style.dis­play = ‘none’;
  3. }

This exam­ple was taken from the JavaScript library used on the cur­rent Microsoft home­page, but you see this sort of code in prac­ti­cally every JavaScript library and tonnes of one-​​off scripts. I chose this par­tic­u­lar lit­tle code snip­pet because it intro­duces a known acces­si­bil­ity issue: most screen read­ers will not read con­tent that is hid­den using dis­play: none or vis­i­bil­ity: hid­den, whether it is writ­ten in your stylesheet or set via JavaScript.

Cur­rently, the best prac­tice for hid­ing con­tent in an acces­si­ble way is to absolutely posi­tion said con­tent way off the left-​​hand side of the page

  1. for( i=0; i<objects .length; i++){
  2.   objects[i].style.posi­tion = ‘absolute’;
  3.   objects[i].style.left     = ‘-999em’;
  4. }

But what if the best prac­tice was to change? It would be far eas­ier (and much more eco­nom­i­cal) to main­tain this sort of style infor­ma­tion in dec­la­ra­tions like this:

  1. .hid­den {
  2.   posi­tion: absolute;
  3.   left: -999em;
  4. }

We could then update our code to activate/​deactivate them as needed:

  1. for( i=0; i<objects .length; i++){
  2.   objects[i].add­Class­Name( ‘hid­den’ );
  3. }

Addi­tion­ally, if best prac­tices changed, we’d only need to update our CSS and not the JavaScript.
But how do we main­tain style rules asso­ci­ated with our scripts? That’s the $10 mil­lion question.

Do what tastes right

There are cur­rently only a hand­ful of options avail­able for sep­a­rat­ing pre­sen­ta­tion from behav­iour, but they fall into two broad cat­e­gories: exter­nal­is­ing and embedding.


Exter­nal stylesheets are prob­a­bly the most widely used form of stylesheet, and with good rea­son: they have the ben­e­fit of being cached, allow­ing them to be used across an entire site with­out incur­ring a down­load penalty as a user moves from page to page. (Many folks com­ing into JavaScript pro­gram­ming with a CSS back­ground also pre­fer this method because it’s more famil­iar to them.

When work­ing with exter­nal stylesheets in JavaScript, you have a few options. First, you can pack­age all of the styles your script requires into a sin­gle stylesheet. Any­one imple­ment­ing your script would then be required to include the CSS file when­ever they include your script:

  1. <script type=“text/​javascript” src=“WickedCool.js”></​script>
  2. <link rel=“stylesheet” type=“text/​css” media=“screen” href=“WickedCool.css” /​>

This approach gives you all of the ben­e­fits of exter­nal­is­ing your styles, but the main draw­back is that some­one needs to remem­ber to include that CSS file when­ever they include the script.

A sec­ond, closely related method, requires that any­one imple­ment­ing your script add your script’s styles to their own stylesheet(s). When mak­ing a rec­om­men­da­tion like this, it is best to advise the imple­menter to clearly label the group of styles you’ve sup­plied to avoid con­fu­sion when she, or some­one else on her team, edits the file later on:

  1. /​* =START Wicked­Cool Script CSS (do not remove) */
  2. .wicked {
  3.   color: red;
  4.   font: bold 4em/​2 “Comic Sans”;
  5. }
  6. .cool {
  7.   color: blue;
  8.   font: bold 4em/​2 “Comic Sans”;
  9. }
  10. /​* =END Wicked­Cool Script CSS */

This approach is less likely to cause imple­men­ta­tion issues unless some­one acci­den­tally removes the styles from the stylesheet. (It happens).

A third approach is to take the exter­nal stylesheet from the first method (above) and add it to the doc­u­ment when your script runs. To accom­plish this, you sim­ply deter­mine the direc­tory hous­ing your script, using a func­tion like FindPath()

  1. func­tion Find­Path( file­name ){
  2.   var path = false;
  3.   var scripts = doc­u­ment.getEle­ments­By­Tag­Name( ‘script’ );
  4.   for( var i=0; i<scripts .length; i++ ){
  5.     if( scripts[i].getAt­tribute( ‘src’ ) &&
  6.         scripts[i].getAt­tribute( ‘src’ ).indexOf( file­name ) != –1 ){
  7.       path = scripts[i].getAt­tribute( ‘src’ ).replace( new Reg­Exp( file­name ), );
  8.       break;
  9.     }
  10.   }
  11.   return path;
  12. }

and then add a dynamic LINK, ref­er­enc­ing the CSS file, to the HEAD of the doc­u­ment. Here’s an exam­ple of one such imple­men­ta­tion within an object literal:

  1. var Wicked­Cool = {
  2.   _​jsFile:    ‘WickedCool.js’,
  3.   _​cssFile:   ‘WickedCool.css’,
  4.   _​basePath:  false,
  5.   ini­tial­ize: func­tion(){
  6.     /​/​ deter­mine the path
  7.     this._​basePath = Find­Path( this._​jsFile );
  8.     /​/​ add the CSS file
  9.     var css = doc­u­ment.cre­ateEle­ment( ‘link’ );
  10.         css.setAt­tribute( ‘rel’, ‘stylesheet’ );
  11.         css.setAt­tribute( ‘type’, ‘text/​css’ );
  12.         css.setAt­tribute( ‘media’, ‘screen’ );
  13.         css.setAt­tribute( ‘href’, this._​basePath + this._​cssFile );
  14.     doc­u­ment.getEle­ments­By­Tag­Name( ‘head’ )[0].append­Child( css );
  15.     /​/​ do the rest of the wicked cool stuff
  16.   }
  17. };

With this in place, WickedCool.initialize() will not only trig­ger the script to work all of its wicked cool magic, but it will also dynam­i­cally add the CSS file to the page. The real ben­e­fit with this approach is that users with­out JavaScript enabled will never down­load that extra stylesheet, sav­ing them both band­width and time. It’s also easy on the imple­menter because they sim­ply need to ensure that the CSS and JavaScript files for the script reside in the same directory.


The other cat­e­gory of approach utilises embed­ded stylesheets and involves plac­ing style blocks into a dynam­i­cally cre­ated STYLE ele­ment, which is, in turn, added to the HEAD of the doc­u­ment. You can do this using a script such as:

  1. func­tion add­CSS( styles ){
  2.   var el = doc­u­ment.cre­ateEle­ment( ‘style’ );
  3.       el.setAt­tribute( ‘type’, ‘text/​css’ );
  4.   if( el.styleSheet ){
  5.     el.styleSheet.css­Text = styles;
  6.   } else {
  7.     el.append­Child( doc­u­ment.cre­ate­TextN­ode( styles ) );
  8.   }
  9.   doc­u­ment.getEle­ments­By­Tag­Name( ‘head’ )[0].append­Child( el );
  10. }

This func­tion, a slight mod­i­fi­ca­tion of one devel­oped by Nicholas Zakas, allows you to sup­ply a text string of style rules for inser­tion into the head of the doc­u­ment. Imple­ment­ing this method is pretty straightforward:

  1. var Wicked­Cool = {
  2.   _​css:       ‘.wicked { color: red; font: bold 4em/2“Comic Sans”; } ’ +
  3.               ‘.cool { color: blue; font: bold 4em/​2 “Comic Sans”; }’,
  4.   ini­tial­ize: func­tion(){
  5.     /​/​ add the CSS
  6.     add­CSS( this._​css );
  7.     /​/​ do the rest of the wicked cool stuff
  8.   }
  9. };

While, tech­ni­cally, the styles are not sep­a­rated from the script itself, I don’t think any­one could argue that this approach is worse than directly manip­u­lat­ing STYLE attrib­utes on ele­ments. The ben­e­fit here is that you only need to main­tain a sin­gle file when mak­ing updates to your script; but the down­side is that the styles will not be cached, as they would if you were using an exter­nal stylesheet.

Note: this approach is far more man­age­able when work­ing with a lim­ited num­ber of styles.

Think out­side the bun

But it’s not all about tech­nique; there are other things we need to keep in mind when striv­ing to exter­nalise our styles from our scripts:

  1. #1 What you want is what you get

    When you are adding CLASS or ID attrib­utes to ele­ments, you want to avoid apply­ing unwanted styles to those ele­ments, so strive to keep their names unique. For instance, con­sider pre-​​pending the name of your func­tion or object to the CLASS or ID: “but­ton” becomes “WickedCool-​​button”. Fol­low­ing a rule like this will vir­tu­ally ensure you never expe­ri­ence a style conflict.

  2. #2 We don’t make it until you order it

    If an ele­ment already exists on a page and you want to apply some styles to it when the script runs, con­sider adding a new CLASS to the ele­ment to indi­cate it is “on” (or oth­er­wise ready to receive the script-​​related styles). This is espe­cially impor­tant if your script styles are in a sta­t­i­cally linked stylesheet, as you don’t want styles intended for the JavaScript-​​enhanced page to be applied if JavaScript is not avail­able. Here are some examples:

    At RestActi­vated
  3. #3 Have it your way

    Most dynamic inter­faces require some set of core style rules to func­tion, but there are other aspects of the inter­face that should remain flex­i­ble. Sep­a­rat­ing your script-​​related styles into “core” and “skin” groups can make it really easy for you, or oth­ers, to redesign your inter­face. Obvi­ously, you’ll want to offer some sort of default skin, but you shouldn’t lock your­self or other imple­menters into that design for­ever. Pro­vid­ing doc­u­men­ta­tion of what prop­er­ties are safe to manip­u­late is also a good idea, both for your own knowl­edge and to assist oth­ers who may work with your script.

We love to see you smile

It’s not always easy to main­tain per­fect sep­a­ra­tion between your scripts and styles, but it should be your ulti­mate goal. The ben­e­fits are obvi­ous – reduced main­te­nance headaches, reduced band­width, and reduced con­flict – so we have lit­tle rea­son not to give each their own space. And, when main­tain­ing your scripts starts get­ting eas­ier, you’ll be happy. And, when you’re happy, who knows, you may burst into song…

“Keep the C-​​S-​​S on the STYLE STYLE side, and the SCRIPT [clap, clap] stays clean!”

1 back to overview

Comments on this article

  1. Written byTimid on the 6th of November

    I am inter­ested in read­ing this arti­cle, “Keep­ing the hot side hot and the cold side cold”, but only see the title? am i going mad? blind per­haps? … help?

  2. Written byGuy Leech on the 7th of November

    Timid, you’re nei­ther going blind nor mad — the arti­cles are not put online until three months after they’ve been printed. To have a read of an arti­cle before then, you have to pur­chase one of the printed ver­sions (or a PDF version).

    This issue will be avail­able online in Decem­ber, so you can either stick around for that, or grab a copy of the printed ver­sion (the PDF starts at just $3.99).

  3. Written byTimid on the 10th of November

    Thx for your response.

    I think i’ll be patient then… cheers again!

  4. Written byconrad on the 29th of December

    Check­ing this all the time… you were talk­ing about decem­ber 2008 weren’t you?

  5. Written byGuy Leech on the 29th of December

    Con­rad: Yes, that was orig­i­nally the plan. How­ever, we’ve delayed the release till the 9th of Jan­u­ary to give us a bit of time after the hol­i­days in case of unex­pected issues. So hope­fully it’ll be here in 10 days.

  6. Written byconrad on the 30th of December

    thanks for the quick response. happy hol­i­days then! best wishes, conrad

  7. Written bylazyet on the 26th of July

    Thank you very much for this arti­cle!
    How­ever, one draw­back (“but the down­side is that the styles will not be cached, as they would if you were using an exter­nal stylesheet.”) IMHO is wrong, as the javascript is in a file on his own, so cached as well. Still harder than some other solu­tions to spot where a dis­play bug is intro­duced though.

  8. Written byKathrin on the 29th of May

    Scroll Mag­a­zine | Keep­ing the hot side hot and the cold side cold by Aaron Gustafson” ended up being a remark­able blog, can not wait to read through alot more of ur blog posts.
    Time to squan­der a bit of time online haha. Many thanks ,

  9. Written byLodge Discounted (Hotels_Discount) upon Twitting on the 5th of July

    I’m not that much of a inter­net reader to be hon­est but
    your sites really nice, keep it up! I’ll go ahead and book­mark your site to come back later. Cheers

  10. Written byLow cost New Orleans Hotels on the 23rd of July

    Thanks on your mar­velous post­ing! I def­i­nitely enjoyed
    read­ing it, you hap­pen to be a great author.I will ensure that I book­mark your blog and def­i­nitely
    will come back later on. I want to encour­age you
    to con­tinue your great job, have a nice afternoon!

  11. Written byLower price New Orleans Motels on the 1st of August

    Whats up very nice blog!! Guy .. Excel­lent .. Amaz­ing .
    . I’ll book­mark your site and take the feeds addi­tion­ally? I’m
    glad to find so many use­ful infor­ma­tion here within the post, we want work
    out extra tech­niques on this regard, thanks for shar­ing.
    .… .

  12. Written byTaylor on the 3rd of August

    Scroll Mag­a­zine | Keep­ing the hot side hot
    and the cold side cold by Aaron Gustafson” def­i­nitely makes me imag­ine a tiny bit extra.
    I appre­ci­ated every sin­gle part of it. Thank you ‚Rhonda

  13. Written byKristine on the 17th of August

    I actu­ally wanted to dis­cuss this par­tic­u­lar blog, “Scroll Mag­a­zine |
    Keep­ing the hot side hot and the cold side cold by Aaron Gustafson” with my best close friends
    on face­book itself. I actu­al­lyjust sim­ply wanted to dis­trib­uted ur out­stand­ing post­ing!
    With thanks, Maynard

  14. Written byliposuction is the key to looking thin on the 6th of August

    Please let me know iif you’re look­ing for a author for your blog.

    You have some really great posts and I think I would bee a
    good asset. If you eveer want to take some of the load off,
    I’d really like to write some arti­cles for your blog in exchange for
    a link back to mine. Please send me an e-​​mail if inter­ested.

  15. Written byBreast Augmentation Boise on the 14th of August

    Great arti­cle about cod­ing! Love to see more like it very soon! Thanks :)

  16. Written by on the 4th of September

    I read this arti­cle fully on thee topic of tthe resem­blance of most recent and pre­ced­ing tech­nolo­gies, it’s awe­some

  17. Written byGreen Deal Cashback on the 5th of September

    What’s up every­one, it’s my first pay a visit at
    this web­site, and piece of writ­ing is truly fruit­ful designed for me,
    keep up post­ing such articles.

  18. Written byOnline Publishing on the 6th of September

    I like what you guys are up too. This kind of clever work
    and report­ing! Keep up the excel­lent works guys I’ve incor­po­rated you guys to blogroll.

  19. Written byWindow Cleaning Insurance on the 7th of September

    Hi, I check your bllog reg­u­larly. Your writ­ing style is witty,
    keep doing what you’re doing!

  20. Written byMicrosoft Office on the 7th of September

    you are in point of fact a excel­lent web­mas­ter.
    The web site load­ing speed is incred­i­ble.
    It kind of feels that you are doing any unique trick. More­over, The
    con­tents are mas­ter­work. you’ve per­formed a won­der­ful activ­ity in this topic!

  21. Written on the 17th of September

    Every­one for­got that the boys were sup­posed to get
    the wind chime in the con­ser­va­tory; they only remem­bered that the friends had gone where only some had spied the man­sion through the gates.
    He’s got to refrain from scream­ing like a lit­tle girl when a hit ball comes right at his face.
    It’s very hard for Drew and I to go any­where in pub­lic together because, instantly, peo­ple rec­og­nize us.

  22. Written bysurgery side effects, on the 5th of October

    What’s Hap­pen­ing i am new to this, I stum­bled upon this I’ve dis­cov­ered It absoutely use­ful and
    it has helped me out loads. I am hop­ing to give a con­tri­bu­tion & assist dif­fer­ent cus­tomers like its aiderd me.

    Great job.

  23. Written byfree internet access providers on the 12th of October

    Hello there I am so glad I found your web site, I really found you by mis­take,
    while I was search­ing on Google for some­thing else, Nonethe­less I
    am here now and would just like to say thanks for a remark­able post and a all round
    excit­ing blog (I also love the theme/​design), I don’t have
    time to read through it all at the minute but I have saved it and also added in your RSS feeds,
    so when I have time I will be back to read a lot more, Please do keep
    up the superb jo.

  24. Written byApp Nana Unlimited Nanas Hack on the 14th of January

    We started off lit­er­ally with, ‘one of each please. Like­wise, up to 3 out
    of every 10 direct mar­ket­ing life insur­ance leads you get
    may not respond affir­ma­tively to you, if at all. Ulti­mately, there is no spe­cific, fool-​​proof way to get a major label record

  25. Written bytolvajbanda on the 21st of January

    I have read so many arti­cles on the topic of
    the blog­ger lovers but this post is really a pleas­ant arti­cle, keep
    it up.

  26. Written on the 21st of February

    Wow, superb weblog lay­out! How long have you ever been run­ning a blog for?
    you made run­ning a blog glaqnce easy. The over­all
    look of your web site is mag­nif­i­cent, as smartly as the con­tent material!

  27. Written bywww.Koreanfestivalhouston.Com on the 1st of March

    Strona świad­czy o intere­su­ją­cych zagad­nieni­ach, zapraszam do roz­mowy test obciążeń orga­nizmu cena łódź,
    test obciążeń orga­nizmu katowice

  28. Written byTim cox fort worth texas on the 8th of March

    Oh my good­ness! Amaz­ing arti­cle dude! Thank you, How­ever I am encoun­ter­ing issues with your RSS.
    I don’t under­stand the rea­son why I am unable to sub­scribe to it.
    Is there any­body else get­ting the same RSS prob­lems?
    Any­one who knows the answer can you kindly respond? Thanks!!

  29. Written on the 22nd of March

    Hi my fam­ily mem­ber! I want to say that this post
    is awe­some, nice writ­ten and come with almost all sig­nif­i­cant
    infos. I would like to see more posts like this .

  30. Written byBeauty school academy on the 3rd of June

    Hello There. I found your weblog using msn. This is an extremely well writ­ten arti­cle.
    I’ll be sure to book­mark it and return to read extra of your help­ful infor­ma­tion. Thanks for the post.

    I’ll def­i­nitely return.

  31. Written byLara on the 21st of July

    Neural Lin­guis­tic Pro­gram­ming is one form of Hyp­no­tism becom­ing more promi­nent as
    one of the best ways to stop smok­ing. Jump­ing to the con­clu­sion that the elec­tronic cig­a­rette was the
    cause of the fire before it is con­firmed by the fire depart­ment inves­ti­ga­tor could present a risk for patients of the hospital.

    While there are lots of meth­ods that aim to help peo­ple quit smok­ing
    like nico­tine lozenges, chew­ing gum, coun­selling, patches and other ces­sa­tion meth­ods,
    one sig­nif­i­cant alter­na­tive is hyp­no­sis or hypnotherapy.

  32. Written on the 7th of August

    If you would like to increase your famil­iar­ity just keep vis­it­ing
    this web page and be updated with the hottest news posted here.

  33. Written byDerick on the 17th of August

    I blog often and I gen­uinely appre­ci­ate your content.

    This arti­cle has really peaked my inter­est. I will book­mark your blog and keep check­ing for new details about once a week.
    I opted in for your Feed too.

  34. Written on the 1st of September

    Hi there, I wish for to sub­scribe for this blog to get most recent updates, so where can i do it please assist.

Leave a comment

Don't forget to keep track of further comments too!