Styles Objects in MR-lib

© 2012, Martin Rinehart

We use styles objects to specify the CSS styles for DOM elements. This makes styling an element in JavaScript almost identical to styling an element in CSS. For example, these styles will help create a red, white and blue element:

var rwb_element_styles = {
    background:    'white',
    border:        '5px solid red',
    fontColor:     'blue'
};

This example adds position and size:

var rwb_element_styles = {
    background:    'white',
    border:        '5px solid red',
    fontColor:     'blue'
    height:        '200px',
    left:          '100px',
    position:      'absolute',
    top:           '150px',
    width:         '300px'
};

Comparison to CSS Declarations

A styles object is very similar to the styles in a stylesheet:

/* CSS styles */
...{
      background: #f0f0ff;
      border:     1px solid #a0a0ff;
      ...
   }

/* JavaScript styles object */
...{
      background: '#f0f0ff',
      border:     '1px solid #a0a0ff',
        ...
   }

The differences are minor and language-specific. In CSS, you don't put quotes around value strings. In JavaScript, you need the quotes. CSS declarations are terminated by semicolons; JavaScript's properties are separated by commas.

Style Universality

Our styles objects accept all CSS property names, including CSS3 properties. As with CSS, invalid names are quietly ignored. Similarly, all valid values are permitted. We have a handful of our own (complete list below) property names. For example, opacity: 0.5 and opacity: 50% will both expand to the standards-compliant opacity (Chrome, Firefox, Opera and Safari) and to the equivalent MSIE filter specification.

As with CSS, unfortunately, specifying a border radius will get you the corners you like in most browsers. It will have no effect in MSIE7 or MSIE8.

Using Styles Objects

We began with a create_element() function. You used it this way:

var styles = {
    background:  'white',
    border:      '1px solid black',
    ...
};

var my_div = create_element(
        'div', 'my_id', styles );

It was often true that the very next line of code would appendChild(), attaching the just-created element to a DOM parent element. That happened so often that we created, and now use, this form, almost exclusively:

var my_div = create_attached_element(
    parent, 'div', 'my_id', styles );

Lately we have been adding many rectangular elements and specifying styles for left, top, width and height was becoming a nuisance, so we created the Rect: an absolutely-positioned div.

var my_rect = new Rect(
    left, top, width, height, styles );
    rect.draw( parent );

Where Else Can Styles Be Used?

We almost never write to a specific style these days. For example, in building our Meter object, it became apparent that the labels (often numbers) would sometimes look a lot better in a smaller font. Instead of adding a "font size" parameter to the label constructor, we added a "styles" object. (Why not let you choose font family, font weight, and whatever? We were glad we did almost immediately as we discovered that we didn't like the spacing between label and tic mark. Add a 'left' or 'top' style, not another parameter!) That said, we still have tons of old library code that doesn't support styles objects. Check the docs.

Special Styles

We use the styles object to do some dirty work when it comes to assigning CSS property names. For instance, for many years you couldn't just assign to 'borderRadius'. Initially you had to assign to 'OBorderRadius', 'MozBorderRadius' and 'WebkitBorderRadius'. Our styles object is happy to take care of that situation.

The styles from the styles object are assigned by the library routine style_elements(). That, in turn, uses the library routine style_an_element(). The latter is the place to go to add cross-browser styling. See the three lines that handle "cssFloat" for the pattern to follow.

cssFloat

At the moment we are down to two non-cross browser styles. That doesn't mean the browsers only have two issues. It means that the styles we are currently using only have two issues. You'll find many more if you explore the newer features of CSS3. The first is cssFloat which Microsoft supports as styleFloat (both avoid the use of simple float, which is an unused but reserved JavaScript keyword).

Opacity

In standards-compliant browsers, opacity is specified as a value from 0.0 (total transparency) through 1.0 (total opacity). MSIE has a very odd, absurdly complex way of specifying a filter for opacity from 0 through 100. Our styles object require just a simple standards declaration: opacity: 0.5, for instance. While we were at it, we realized that adding a "%"sign suffix was really no trouble, so now we allow opacity: 50%, too. Either way, you get correct opacity in all browsers.

Check the style_an_element() function for the latest word on currently suppoorted cross-browser CSS tricks.

Styling Your Styles

For years we have included all our style properties, in JavaScript and in CSS, in alphabetical order. It makes it so simple to find a property (if it's there) and change it. Hunting through unordered style property lists drives us crazy!

We also like single-property lines, and neat columns:

var rwb_element_styles = {
    border:        '5px solid red',
    background:    'white',
    fontColor:     'blue'
    height:        '200px',
    left:          '100px',
    position:      'absolute',
    top:           '150px',
    width:         '300px'
};

If your editor doesn't make this easy, check for a 'block mode' feature.


Feedback: MartinRinehart at gmail dot com

# # #