[Javascript] separating structure, style, and behavior

Paul Novitski paul at novitskisoftware.com
Thu May 6 10:13:55 CDT 2004


Mike,

ye scribed:
>   I like the idea of controlling display with css, but taking everything 
> "out" to the style sheet makes the inline code a bit less readable.  (ok, 
> so i'm lazy too)

What I've found is that ever since I've been consciously separating html 
structure from javascript behavior from css style, my own code has become 
MORE readable and manageable, and more often I know exactly where to go to 
solve a particular problem because there's so little overlap between the 
three domains.  Previously, if a page element didn't look or behave 
properly, I'd have to look in two or three files to track it down.

Here are some vivid examples of the sucessful separation of structure from 
style, in which the same html skeleton is fleshed out dramatically 
differently using CSS:

         Listamatic http://css.maxdesign.com.au/
         The CSS Zen Garden http://www.csszengarden.com/

In practice, I'm finding that I can't separate the three completely.  In 
order to get some CSS structures to work, I find that I must tweak box 
dimensions at onload() or during interaction.  Until CSS4 and HTML7 and 
Browser10 come along and solve all of our problems forever (you bet!), 
we'll be shambling along as best we can with incompletely formed 
limbs...  But even with today's imperfect technology one can get quite 
close to the ideal.


>   How do you deal with multiple properties using that strategy?  If i 
> want to change both the background color (for enable/disable) and 
> font-weight (for select/deselect) - is there a way to use CSS class, 
> without having to define 4 classes for this one object?

Well, there are various approaches.  First of all, I actually don't find it 
onerous to define four classes if that's what the design calls for:

         cssEnabled{background-color: lightblue;}
         cssDisabled{background-color: ghostwhite;}
         cssSelected{font-weight: bold;}
         cssDeselected{font-weight: normal;}

That way I can assign these classes to my elements singly or in pairs:

         oThang.className = "cssEnabled"
         oThang.className += " cssDeselected"

The point is that I'm using html & javascript to apply metaphorical class 
names rather than explicit style attributes.  Given a single html 
structure, I can tweak its appearance merely by changing its stylesheet.  I 
can more easily allow a generic widget to be adapted to many cosmetic 
contexts.  I can more easily use the same page for different purposes by 
creating alternative stylesheets -- whether for different browsers or for 
different media (display/print).  Another benefit of separation is that 
it's easier to build pages that degrade gracefully -- they may not look 
terrific if the browser doesn't support CSS or Javascript, but at least 
they won't break as easily as they would if the scripting languages were 
thouroughly intermixed.


One of the cool things about CSS is that you can have more than one class 
name per object -- just separate them with spaces:

         <select class="cssEnabled cssDeselected cssFrankie cssJohnny ...">

This allows a page element to belong to more than one cosmetic group, which 
can often come in handy.


In a page where certain items can have more than one class name, I often 
use RegExp replace logic.  Instead of:
         oThang.className = "cssActive"
I write:
         oThang.className = oThang.className.replace(/cssIdle/, "cssActive")

so that I can toggle one set of class names without disturbing others.


Since CSS requires that multiple class names be delimited by spaces, it's 
easy to capture them in a Javascript or VBscript array:

         var aClassNameArray = oThang.className.split(" ")

Of course, most often you don't need to declare a special class name for 
default states like "disabled" or "deselected", because without a class 
name an element will render using the default properties of its type, e.g.:

         /* default properties for drop-down lists */
         select
         {
                 background-color: ghostwhite;
                 font-weight: normal;
         }

         /* special states */
         select.cssEnabled
         {
                 background-color: lightblue;
         }

         select.cssSelected
         {
                 font-weight: bold;
         }

That way you're really only juggling two class names, not four, but with 
the same effect as four.


Another cool thing about CSS is that you can use the a:hover selector in 
place of many Javascript onmouseover behaviors.  (IE is limited to applying 
:hover to anchor tags, while some other browsers will apply it to any tag.)

HTML:
         <ul id="Amphibians">
                 <li><a href="#">Frog</a></li>
                 <li><a href="#">Salamander</a></li>
         </ul>
CSS:
         #Amphibians a:hover
         {
                 background-color: lightgreen;
         }

You can even use this to drive dynamic menus, causing sub-menu items to 
appear & disappear with hover:

HTML:
         <ul id="PlantList">
                 <li><a href="#">Trees
                         <ul>
                                 <li>Larch</li>
                                 <li>Spruce</li>
                         </ul>
                 </a></li>
                 <li><a href="#">Shrubs</a>
                         ...
                 </li>
         </ul>
CSS:
         /* hide submenus by default */
         #PlantList a ul
         {
                 display: none;
         }
         /* show submenus on mouse over */
         #PlantList a:hover ul
         {
                 display: block;
         }

More later...

Paul


At 06:12 AM 5/6/2004, Mike Dougherty wrote:
>>Rather than explictly changing an element's backgroundColor in 
>>Javascript, I recommend that you change its className instead, and set 
>>the color specifics in your stylesheet.  If you can confine as many of 
>>your stylistic effects as possible to css, you'll always know where to go 
>>to tweak the cosmetic and you won't have to worry about css/javascript 
>>conflicts.
>
>   How do you deal with multiple properties using that strategy?  If i 
> want to change both the background color (for enable/disable) and 
> font-weight (for select/deselect) - is there a way to use CSS class, 
> without having to define 4 classes for this one object?
>
>   I like the idea of controlling display with css, but taking everything 
> "out" to the style sheet makes the inline code a bit less readable.  (ok, 
> so i'm lazy too)






More information about the Javascript mailing list