Archive for the 'CSS' Category

JavaScript formatting library update

This is a quick update on the state of my JavaScript date formatting libraries and date chooser, and JavaScript number formatting library. It’s been a while since I wrote them, and as you can tell my interests have turned to many other things, but thet remain the best JavaScript formatting and parsing libraries I’ve seen.

I originally started this post in May of 2006, intending to use the libraries to demonstrate how HTML tables can contain multi-dimensional data, and use the seldom-used HTML elements like TFOOT to generate aggregate data about the table. This was going to be the follow-up to my tables and data with CSS post. I had a rough draft sketched out somewhere: a table full of numbers, dates, currencies and strings. A drop-down menu and a “format paintbrush” would let you reformat it all on the fly, and it would all be generated from semantic information attached to the table cells, not hard-coded into the page.

This was only practical because of the efficiency of my libraries; to reformat entire date regions in the table in real-time, for example, you’d need to parse the value as a date in one format, then reformat it for output in another. It was to be a showcase of how much efficiency matters for some things.

Tangent: I suppose it’s less important for people who aren’t still running 500MHz laptops these days, but efficiency really matters for me; a lot of these flashy sites these days simply take too much CPU for my little old computer to run well. I stubbornly resist getting a new computer because I cringe at the thought of the environmental cost, but I’m slowly breaking down; it’s gotten to the point my battery won’t charge, and Dell doesn’t even have a record of my service tag anymore. Spare parts for these things are long since unavailable.

Now I’m involved with quite different things, since I’m working more in programming and less in the Internet space. The good news is others keep reading and using all of my work — not just the recent work — which makes me happy. Just the other day Liran Tal wrote to tell me he’s using my Javascript libraries in the Daloradius project (check it out, it’s pretty cool). The date-parsing library found its way into some ExtJS tools that extend the YUI libraries, too.

And a few days ago someone sponsored an improvement to the number-formatting libraries.

Who knows — someday I may end up building some browser GUI systems again and use these. In the meantime it’s encouraging that they remain useful to people.

Note: This episode is pre-recorded. I’m taking a short hiatus from blogging and will respond to your comments when I return.

Technorati Tags:, , , , , , ,

You might also like:

  1. Javascript date parsing and formatting, Part 2
  2. JavaScript date formatting benchmarks
  3. JavaScript Number Formatting Library v1.3 released
  4. How to format numbers in JavaScript flexibly and efficiently
  5. JavaScript date chooser

How to create input masks in HTML

Download HTML Input Mask

Note that this is not compatible with all browsers, has known problems and limitations, and I am not maintaining it or replying to requests for help. Thanks! (But also note that you are free to change and redistribute under the license terms, which you should read after downloading)

Have you ever wanted to apply an input mask to an HTML form field? Input masks are common in traditional GUI applications, but HTML has no such feature. This article introduces a library that adds input masks to form fields with unobtrusive JavaScript.

What’s an input mask?

View the Demo

Input masks are guides to help users enter data in the correct format. They typically do not actually validate data; they just ensure the right types of characters are entered in the right places. Typical uses are for dates, times, social security numbers, phone numbers, and credit card numbers. The user enters un-formatted input, and the mask takes care of adding dashes and other separators in appropriate places.

For example, in the United States most people use MM/DD/YY format to write dates. A well-written GUI application honors the user’s locale and creates an appropriate input mask, such as ##/##/##, for date entry. The user types the numbers, and the program inserts the slashes. If the user types something other than a number, that character is discarded, not entered into the field.

How to do this with JavaScript

There are several problems you need to solve to simulate this in a web browser. First things first: let’s state the requirements.

  1. Help the user avoid entering invalid characters.
  2. Automatically insert separators as the user types.
  3. Constrain the length of the input.

Second, let’s create a spec for the masking syntax. In Windows Forms programming, controls have a Mask property, and other GUI libraries have similar functionality. The full behavior of these masks is complex. For an example, see the MSDN documentation for masked edit controls. You can get a lot of that functionality with a simpler specification, though. The following will suffice for many uses:

  1. The mask only allows one type of character for the entire mask. For example, the mask can allow either all digits or all alphanumerics, but you can’t constrain one character to be a digit while letting other characters accept alphanumerics.
  2. The mask specifies the placeholders for input with spaces, and separators as non-spaces.

An example mask, then, has two parts: the format, which says which places can accept user input, and the type, which says what type of character can go in those places. We’ll see how to actually do this later.

The third problem is to unobtrusively attach the masking functionality to input fields, with gracefully degrading behavior if the browser doesn’t support it, and without adding a lot of markup to your forms to specify the mask format and type. This is easy, using the principles I laid out in an earlier article on using classes to specify data types. This technique is 100% appropriate because classes aren’t just hooks for CSS, they’re general-purpose processing information. This lets you easily specify a) which inputs get masks, and b) which type of mask they get.

How it works

To add masks to form fields, reference my library, then make the page’s load event fire the Xaprb.InputMask.setupElementMasks() function in my library. This will find all elements with the class input_mask, which specifies that the element should get a mask. Each element should also have a mask_??? class, where the ??? specifies which mask to attach. The library takes care of the rest.

By the way, this library depends on the Prototype library, so you will also need to reference that in your page. If you don’t, you won’t get an error, but nothing will happen.

The setup function iterates over the elements and connects a callback to the onkeypress event. The callback is created by another function. To decide which mask to apply, it does a regular expression match against the element’s className. If the element’s class is “input_mask mask_date_us“, the regular expression captures “date_us,” and looks up the date_us mask. Here’s how that is defined:

      date_us: {
         format: '  /  /    ',
         regex:  /\d/,
      }

The format property is a string with spaces where input should go, and other characters get inserted automatically. The regex property is a regular expression that matches a valid character, in this case a digit.

Here’s how the callback function works: when it fires, it checks each character in the form field’s value. If there’s a space in that place in the mask’s format string, it looks to see if the character matches the mask’s regular expression. If so, the character is valid for that place in the input; if not, the character is rejected. If there isn’t a space in that place in the format string, the character from the format string is copied into the form field (this is how separators are automatically inserted).

Demonstration

Enough talk, let’s see it in action. This demonstration of Javascript form input masks shows a few of the masks I discussed above: US date, time, and phone number.

If you like the way the form input fields look, you can thank the fine folks at Particletree. I borrowed the styling from their article on how to make forms suck less (it makes the borders of the input areas easier to see).

Limitations

Since this is really just a hack on top of existing HTML form inputs, there are some things that will never work quite as well as a natively designed widget (the same is true for my JavaScript Combo Box widget). Here are some of the limitations:

  • No unicode or international characters (this might be easy to fix).
  • No spaces as placeholders. Sometimes you might want spaces between user input, rather than non-space separators.
  • Only one type of character for the entire input; you can’t constrain the first character to be a digit, and the second a letter.
  • It doesn’t show the mask ahead of time and let the user ‘fill in’ the missing characters; instead, it reveals the mask as the user types.
  • You can’t have two adjacent separators.
  • You can’t type into the middle of the text; all input you type is appended to the end.
  • It hijacks things like Ctrl+A to select all.

Despite the length of that list, these are such minor things (except for maybe international characters) that it’s practically a complete implementation. And as far as I know, everything here could be solved easily. I just haven’t done it, because you haven’t yet told me which things are problems for you (hint, hint: leave a comment, and patches are very welcome). I deliberately kept things really simple in this first version. Future versions can get fancier, or not.

Conclusion

So that’s it! Simple, lightweight, intuitive input masks. With a proper form validation library on the back-end, you should be able to use this to help your users enter data in the format you desire. Again, let me know what you think, and by all means improve this, and send me the results!

Technorati Tags:No Tags

You might also like:

  1. JavaScript date chooser
  2. Javascript date parsing and formatting, Part 2
  3. JavaScript number-formatting library updated
  4. JavaScript date parsing and formatting, Part 1
  5. How to find and fix invalid character data in MySQL

Automatic image captions with unobtrusive JavaScript

View the Demo

You’ve probably heard of unobtrusive JavaScript. It’s a simple technique that lets you create richer documents without cluttered markup or accessibility problems. I often see link decoration and drop-shadow effects done with unobtrusive JavaScript. How about unobtrusive image captions? Instead of writing a caption into the page, let JavaScript do it. In this article I’ll show you how simple this can be.

The idea

How often have you seen websites that use a table or a div to enclose an image and some text to create a “captioned” image? Far too often, I’d guess. Semantically speaking, though, nothing in the markup actually associates the image and the “caption” — this isn’t a good way to give an image a caption. Until HTML itself actually has a true mechanism for a captioned image, or until someone makes a microformat for it, you may be better off taking the path of compromise between richness and semantic content.

That compromise, in my view, is using unobtrusive JavaScript to add richness to the site after it is loaded. The document is delivered to the browser in plain-Jane fashion, then altered after the browser loads it. The end result is no more semantic than hard-coding all the extra markup, but it’s a good trade-off in my opinion.

Plus, it makes authoring content much easier. Let’s see how.

The old way

Here’s typical code you might see to create a “captioned” image:

<div style="width:100px">
   <img src="treefrog.png" alt="A tree frog"
      width="100" height="100" />
   <p>A tree frog</p>
</div>

You may also see inline styles, a table instead of a div, and other ugliness.

The new way

The better way to do this is simply eliminate all that redundant typing. What’s redundant, you say? Well, the width of the wrapper element and the text of the “caption,” to mention two things. The image already has a width — why repeat it in the wrapper element? The image already has a place for associated text in its title attribute — why write it out again?

Let’s strip things down to the bare minimum:

<img src="treefrog.png" alt="A tree frog"
      title="A tree frog" class="figure"
      width="100" height="100" />

Does that look minimal to you? If you’re thinking the alt attribute and the title attribute are redundant, I disagree. The alt attribute is never to be presented to the user when the image can be presented. It is an alternate representation of the content when the image isn’t available. It is not a title for the image. That’s why there is a title attribute for images! If it were redundant to the alt attribute, it wouldn’t be there.

I propose this as the bare minimum for an image, except for one thing: CSS styling. You may want to use CSS to float your image to the left or right. Nobody wants an ugly break in the text flow for an image. But that’s where I’ll start with this article.

CSS styling

Time for a demonstration of the starting point. I’ll insert two images from stock.xchng, a great free stock photography site. I’ll float one of them left and the other right with the following CSS:

.left {
   float: left;
   margin-right: 5px;
}
.right {
   float: right;
   margin-left: 5px;
}

You can see a demonstration here. It’s pretty plain, isn’t it? But it works. Nothing fancy, but then again you can do a lot with this basic markup. Now let’s add some captions to those images.

The magic

It’s actually really easy to lift the images out of the page, insert a wrapper element, and put the image back into the wrapper. There are some subtleties, and I’ve done a thing or two to make the technique easily extensible. Here’s the code:

function addCaptionsToImages() {
   wrapImagesInDiv( 'figure', [], [ 'float' ] );
}

if(typeof window.addEventListener != 'undefined') {
   window.addEventListener('load', addCaptionsToImages, false);
}
else if(typeof document.addEventListener != 'undefined') {
   document.addEventListener('load', addCaptionsToImages, false);
}
else if(typeof window.attachEvent != 'undefined') {
   window.attachEvent('onload', addCaptionsToImages);
}

function wrapImagesInDiv( className, attributes, styles ) {
   var images = document.getElementsByClassName(className);
   for ( var i = 0; i < images.length; ++i ) {
      var img = images[i];
      // Lift the image out of the page and insert a div under it.
      var parent = img.parentNode;
      var frame = document.createElement('div');
      var txt = document.createTextNode(img.getAttribute('title'));
      parent.insertBefore(frame, img);
      parent.removeChild(img);
      frame.appendChild(img);
      frame.appendChild(txt);
      // These are special cases.  We always copy these from the image to the
      // div.
      frame.style.width = img.getAttribute('width') + 'px';
      frame.className = img.className;
      // Copy specified attributes and style properties from the image to the
      // div.
      for ( var j = 0; j < attributes.length; ++j ) {
         frame.setAttribute(attributes[j], img.getAttribute(attributes[j]));
      }
      for ( var j = 0; j < styles.length; ++j ) {
         frame.style[styles[j]] = img.style[styles[j]];
      }
   }
}

I’ll break that down a bit at a time. The first few lines define a function to be called on page load. I use Scott Andrew’s cross-browser onload functionality to add an event that’ll call the wrapImagesInDiv function with the desired arguments. I do this because I want the flexibility of passing desired arguments.

Next I define the wrapImagesInDiv function itself. This function accepts a class name, an array of attribute names, and an array of style property names. The class name defines the target elements: everything with a class of “figure.” The array of attribute names specifies which attribute values should be copied from the image to its wrapper, and likewise with style properties. You’ll see where I use those in a bit.

The first line inside the function uses the document.getElementsByClassName method supplied by the Prototype library to find all the images labelled with class="figure". There are other ways to do this, but I think Prototype is ubiquitous enough that this is a fine choice.

After that, the script simply loops through the array of resulting objects. For each object, it gets a reference to the parent element, creates a div element, moves the image inside that, and appends the image’s title attribute as text afterward.

Then it does a couple of tricky things. First, it sizes the wrapper horizontally to match the image. This is necessary so the wrapper doesn’t take over the entire width of the page. Next it copies the image’s class to the wrapper. This is necessary to preserve any CSS styling that was used to place the image relative to the text. In my case, this preserves the left-floating and right-floating I created in the first example.

Finally, it loops through every other attribute and style property I specified, and copies those from the image to its wrapper. This is an easy way to get the same script to do lots of different things — you just give it different arguments. Do you want the wrapper to have the same title attribute as the image? Fine, just add ‘title’ to the argument array — I’m all about choice.

I’ll add a couple extra lines of CSS to make things prettier, too. Here’s the result: automatic image captions without ugly markup.

Further tweaks

This is a really simple technique, and you can go much further with it. Here are some more ideas:

  1. Use Roger Johansson’s technique to add custom corners, borders, and drop shadows. Why not?
  2. In keeping with thinking of the images as “figures,” auto-number them, and create references to them on the fly by adding in other hooks for JavaScript.
  3. Tables could be figures, too, and you could auto-number and auto-reference them. But don’t auto-caption tables, because they already have a caption element of their own.
  4. Generate a table of figures for your document.

If you haven’t done much reading on unobtrusive JavaScript, you really should. You can do so much with it. And the best part is, it lets you keep your HTML sooooo much cleaner and saves you so much work.

Conclusion

I hope this article has helped you break out of a common web design rut and snazzy up your documents without adding un-semantic markup bloat. If you thought this was good, let me know! If you want to suggest some improvement, let me know that too! And if you want to subscribe to my articles, go right ahead. It’s free and easy.

Technorati Tags:No Tags

You might also like:

  1. How to display an HTML table as a folder tree
  2. Advanced HTML table features, Part 1
  3. JavaScript date chooser
  4. Stock images are too popular
  5. How to style HTML lists consistently in all browsers

How to display an HTML table as a folder tree

XHTML tables provide several elements to group and structure data, including row groups (thead, tbody, and tfoot). Styling row groups with CSS can make data relationships visually obvious. One familiar way to group data visually is with Explorer-style folder icons.

Data grouped as a folder view

The basic idea is to use tbody as many times as needed to group each set of rows together. The image above shows a single tbody element. I think using multiple tbody elements may not occur to developers because it sounds like there ought to be only one — but that’s not true. Tables can have as many tbody elements as you want. You can optionally have one (and only one) thead and tfoot too. Read the Tables in HTML documents part of the HTML spec for more, if you want (there’s no need to for this article).

The next thing to do is add some CSS. The image will go at the far left of the leftmost (first) td as a background image, and I’ll add some left-padding to keep the text from overlapping the image. I identify the leftmost column with the first-child class.

Next, the first and last rows in the group need special treatment. The middle rows get a little dotted “tree-view” extender line, but the first row needs a folder icon and the last needs the extender line not to continue downward (because there’s nothing below it to connect to). To accomplish this, the first row in the group gets the first-child class, and the last gets class="last-child". Now I can use these to set different background images for the first and last rows in the group.

If I knew that my browser was a Good Browser such as Opera, Firefox or Konqueror, I could use the CSS selector :first-child instead of adding classes, but since IE is still popular, I’m adding the classes to the HTML instead.

This part is optional, but I like to do it because it keeps the number of images down: use exactly the same image for every row (first, middle and last), and set the background-position property so a different part of the image will show up (top, middle, and bottom of the image).

That’s it! Here’s a demo.

Another option is to re-code the first row of each group with th elements instead of td. The scope attribute can then be set to rowgroup, which conveys additional semantic meaning about the row and eliminates the need to add the first-child class to the tr. Whether I do that depends on the data. I don’t think it makes sense for my demo, but I can imagine data applications where it does. I can also imagine making the leftmost column th instead of td in my sample data; that strikes me as appropriate. Regardless of how I do it, if I mark the data up semantically, I can use CSS to reflect that meaning visually.

Technorati Tags:No Tags

You might also like:

  1. How to find duplicate rows with SQL
  2. Simple and complex types in XML Schema
  3. Advanced HTML table features, Part 1
  4. How to find data distributions with SQL
  5. JavaScript regular expression toolkit

Tables and data part 1: CSS and data types

I don’t know how spreadsheets do it internally, but at least from a user’s perspective, they derive the default cell format from the type of data in the cell. For example, if I enter a number into a cell, the spreadsheet will right-align it. It will format dates and times according to cultural conventions, and will recognize other data types as well. This is the right way to do it, because the formatting conveys information about the data. Right-aligned numbers are numeric, not textual.

Now switch from spreadsheets to HTML. I have a table with sales data rolled up by day for a week. How do I format it? Do I right-align the numbers, format them with dollar signs and two decimal places, and display negative numbers in red? Do I left-align the days? Or do I just specify the first column as date and the second as currency?

I could do either, but I think it’s better to go the second route, and let CSS control the formatting. It’s possible to control simple presentation with just CSS and the HTML class attribute, the general-purpose method for adding processing data to HTML elements. I might want more advanced formatting (rearranging the data itself), and in that case I’d need some help from JavaScript. I’ll demonstrate all that and more in this series of articles. Let’s dive in:

The foundation

To set the stage, here’s some sample data, which I’ll use throughout this series of articles:

Weekly Sales Stats
DateNet Sales
2005-01-01581
2005-01-02557.23
2005-01-03532.1
2005-01-0420.
2005-01-05-82.58

Aside from an alarming trend in the numbers (quick! Get me the VP of Marketing!), this table is pretty uninteresting and hard to read, especially since the numbers aren’t formatted consistently (they represent the values accurately, but not legibly). A sample row looks like this:

<tr><td>2005-01-05</td><td>-82.58</td></tr>

I used standard formats for the data. The dates are in ISO8601 standard format, and the numbers are just plain… numbers. No fanciness here. That’s intentional, because I want it to be easy for a program to use in a future article (you’ll see, it will get pretty complex).

First steps: formatting, type vs. value

The most immediate benefit comes from specifying visual formatting for the values, to convey information about what they are. I can’t think of anything special to do with the dates (visually at least — adding a date class will still convey semantic information), but the numbers can be right-aligned and negative numbers can be red. How can I make negative numbers red? I could add a few classes to the TD, for example class="number currency negative".

Does that negative belong there? I don’t think it does. I’m a data guy, and I don’t do hand-coding if I can get a program to do it for me, so I naturally assume the table is generated dynamically and the CSS classes are specified in a template. The CSS will vary by data type, and perhaps specify a desired formatting based on the data type, but will not vary by the data’s actual value. I think it’s crucial to distinguish between types, presentational styles, and values.

  • number is a data type.
  • currency is both a presentational instruction and a sub-type of the number data type.
  • negative is neither type nor presentational — it’s dependent on the data value, not the type or the author’s formatting preference. It doesn’t belong there.

To keep the type/presentation/value separation clear, I won’t mark negative numbers up differently. I’ll just add some classes to the TD elements to indicate my data type and formatting preferences.

CSS class name conventions

I used class="currency" above as an example, but I’m going to use certain class name conventions to help organize the CSS classes. I’ll use the prefix dt- to indicate “data type,” and dst- to mean “data subtype.” Here are the values I’ll use:

Data TypeClass NameMisc
Datedt-datetimeAll date and time data.
Date and Timedst-dateDate only; no time information.
Numericdt-numberAll numeric data, including currency.
Currencydst-currencyA subset of number.
Currency Typedst-???Use ISO 4217 currency codes.

I can think of many other variations, but I’ll invent them when I need them. The sample row now looks like this:

<tr>
    <td class="dt-datetime dst-date">2005-01-05</td>
    <td class="dt-number dst-currency dst-USD">-82.58</td>
</tr>

That’s as far as I’ll take it with plain CSS at this point — I’m happy with the markup. It is structural and semantic, but not presentational; the CSS will handle that later.

Future possibilities

I could push the limits a bit, but the techniques I’d have to use are either not widely supported or not part of current standards. However, some will very likely be widely implemented in the future, so they are interesting enough that I want to discuss and demonstrate the possibilities:

  • Align cells along a string. No browser, as far as I know, currently supports this — and that’s understandable because it would be really hard and the spec has some problems — but the CSS 2.1 spec says you could theoretically line numbers up along the decimal point. In my opinion, this won’t happen in the forseeable future, so I’ll just mention it in passing and forget about it.
  • Use the :before pseudo-element to add the currency sign before currency values, according to the currency type. This won’t work in IE.
  • Change the formatting based on the value itself. With some limitations, this works well. For example, add parentheses around negative numbers. This requires matching some part of the data in the stylesheet, which isn’t currently possible. There is a workaround though, which will be very useful for other purposes too: use the abbr attribute to hold a copy of the value. Then the CSS can match the attribute value. CSS 2.1 allows only very limited matching (see section 5.8.1), but CSS3 will probably allow more options (see section 6.3), most importantly the substring matching selectors. For example, it would be possible to style numeric data beginning with “-” differently — perhaps making it red, perhaps using before: and after to add parentheses. Currency values that don’t end in a decimal place and exactly two zeros could be fixed up. Even though the attribute matching is still pretty limited, it would allow a lot of flexibility — and you know how web programmers are. Some bright kid is sure to figure out ways to combine all sorts of technologies and make it sing and dance.
  • If the application is not HTML, but is some other variant, such as XHTML or just XML, other technologies such as XSLT and XPath can do far more complex processing.

These techniques could change the actual value the user sees, which brings up a related issue: am I lying about the data if I change the displayed value? In my opinion, no, I’m just showing the user one particular view of the data. The document contains the same data no matter what the browser displays. There are many views on a single bit of data, and making the view independent of the data is a good thing. There’s precedent for this practice even in HTML and CSS — text-transform is an obvious example. In other technologies, it’s taken for granted that the user never sees raw data, only views of it. Heck, even a browser is just one view of an HTML document!

Even though many of these techniques aren’t well supported, some of them are. Here is a demo so you can see all of the above — both supported and unsupported — in action. Let me know what you think!

Upcoming work

That’s all for now. In upcoming articles, several threads (JavaScript, date and number formatting, CSS, tables) are going to start converging, and I’ll introduce a lot more material. You’ll see how to add load-time processing to your tables, apply predefined and user-defined format strings by naming them in the CSS, get around the row/column multiple-hierarchy problem so you don’t have to specify the classes on every single row or cell separately, allow users to really choose their preferred view of the data, and maybe even more. Stay tuned!

Technorati Tags:No Tags

You might also like:

  1. Javascript date parsing and formatting, Part 2
  2. How to format numbers in JavaScript flexibly and efficiently
  3. JavaScript number-formatting library updated
  4. JavaScript formatting library update
  5. JavaScript date parsing and formatting, Part 1

How to use CSS to go beyond separation of content and presentation

One of CSS’s loftiest goals was to help separate content and presentation on the Web1. It has succeeded to some degree, bringing great benefits in terms of maintainability, usability, and accessibility.

Think at a higher level

There is much noise about content and presentation, but it’s not the only beneficial separation. In fact, pick any dimensions you wish, and I think you can benefit by distinguishing among them at least to some degree: content, presentation, structure, behavior, and so forth.

One reason separation is good that it actually lets me factor out repetition and shared aspects, and deal with them just once. In this sense, I’m not just separating things in one place, I’m bringing them together in another. Aspect-Oriented Programming is a great example from the programming world. However, it is technique, rather than technology, that is important. CSS doesn’t guarantee the separation — it’s how I use it that matters.

With this in mind, I am currently ruminating the following: I think it’s a Good Thing to separate layout and presentation within CSS. Again, these are just dimensions within one technology; I think making the proper distinction between the two is just a good practice.

Definitions

First let me define the terms as I use them in this article:

Layout Styles
dictate how the elements of the page are arranged: where is the navigation, is the content a fixed-width column that’s centered on the page, and so forth. Layout markup is usually about setting some properties of elements that hold the “real content” of the page.
Presentational Styles
specify how the “real content” appears: font size, colors, borders, link hover effects and so forth.

What this means on a real website

In terms of a typical website that uses CSS for both purposes (layout and presentation), many elements on the page will have both types of styles. Global navigation, for example, will almost certainly have some positioning styles attached to a container, and often will have hover effects on links too. What if I want to change how the page is laid out, but not be distracted by all the font sizes on headers, margins on the lists, and so forth? I’ve done this myself and found it difficult to sort through an entire stylesheet, ignoring the presentation haystack to find the layout needle. Since then I’ve tried to keep the two separate, either by just using comments to mark separate sections within the one file, or by using two files. @include is great for this — the presentation stylesheet can include the layout stylesheet at the beginning. It helps a lot.

I don’t consider myself an expert on this. Not much attention has been paid to good practices when writing stylesheets. Everyone’s writing about standards, browsers, and so forth. For some reason, good writing practices don’t seem to be sexy (yet), and maybe that’s why everyone is eager to write about other things. I think this may have a lot to do with who’s writing CSS. In many cases, it’s not programmers, so as a programmer, I often find people’s stylesheets to be big freakin’ messes. In traditional programming, much effort has gone into studying what makes code maintainable, easily verifiable, and so forth. Similar work doesn’t seem to exist for CSS (though I personally feel the same principles apply). There’s not much, if any, guidance about style when writing CSS. How to indent, naming guidelines, and order of properties come to my mind when I think of this. Again, I don’t think I have anything more to offer than other people, but I’m thinking about it. Maybe at some point I’ll put some time into it and produce my own code standards for CSS. I’m sure others will start doing so as well, especially as CSS becomes more widely used and some people start getting stuck with bad code. When people get fed up with it, they’ll do something about it :-)

Perfection is an illusion

As a side note, I would like to say complete separation of content and presentation (or anything else) is not possible in many cases, despite some people’s insistence to the contrary. It’s a myth. A lot of this is because any given feature often belongs in several domains, so imposing a strict hierarchy rarely works (the realization that hierarchical taxonomies are flawed is exactly where all the “tagging” in Web 2.0 is coming from). I wrote my thesis on visual and informational representations of music and I’ve found it’s rarely clear-cut, be it music or text. My experience with music made me take a fresh look at HTML, and I was amazed at how my perspective changed. There’s much to be gained from an 80% solution, though, so fire away!


[1] People say this many different ways, such as “structure and presentation” and so forth. My memory says “content and presentation” was the first such phrase to be bandied about, and the terminology has changed over the last 6-8 years.

Technorati Tags:No Tags

You might also like:

  1. Why not to use CSS for columnar layouts
  2. Simple and complex types in XML Schema

Why not to use CSS for columnar layouts

Using DIV tags and CSS to format a single text into multiple columns is just as bad as using tables for layout. This article explains why.

Everyone agrees tables are not for layout, because tables are supposed to contain tabular data. Similarly, DIV elements aren’t the right tool for columns, because they are supposed to group content into a generic container — either to group related elements simply for grouping’s sake, or to identify actual content and apply meta-data such as language or class. From the spec:

The DIV and SPAN elements, in conjunction with the id and class attributes, offer a generic mechanism for adding structure to documents.

The keyword is structure. Using DIV elements to lay out text into columns isn’t structural, it’s presentational. Consider how columnar text is typically accomplished: DIV elements, floated left so they’ll stack next to each other. This is not semantically meaningful! In particular, the text must be split into multiple DIVs to get it into columns. Now the text, which is one piece of content and should not be divided, has been divided as though it’s many pieces of content.

Many people don’t like to admit it, taking a sort of “end justifies the means” attitude and forcing the content into columns with hacks, but HTML and CSS currently provide no mechanism for presenting a single text in multiple columns (CSS 3, which is not finalized, will provide a mechanism, and beta versions of Firefox currently support it). What bothers me the most about the hacks is those who approve of and admire them. Violating standards is nothing to be happy about or advocate. Those who do so are certainly not on the cutting edge. The cutting edge is about semantics and standards, not about ignoring semantics and violating standards.

If you must put your text into columns, there’s a good AListApart article about laying out columns with JavaScript. The advantage of this (as opposed to actually coding separate DIVs) is that the content is in a single DIV until the JavaScript works on it. In other words, the document your Web server delivers to the user agent has all the content in a single DIV. Only JavaScript-enabled user agents will see multiple columns. For practical purposes, that really means only visual browsers at this point. This is acceptable to me, because it doesn’t mess with the structure of the document, unless it’s in a user agent that doesn’t actually present structure to the user anyway.

For purists though, there’s no getting around it until CSS 3: anything you do to format a single text into multiple columns is a hack, also known as an abuse. How quick we are to criticize people who used tables for layout, but how soon we forget our high-minded principles when we can’t have what we want.

Technorati Tags:No Tags

You might also like:

  1. How to use CSS to go beyond separation of content and presentation
  2. Simple and complex types in XML Schema
  3. How to display an HTML table as a folder tree
  4. Automatic image captions with unobtrusive JavaScript
  5. How to install beautiful X11 cursors

How to style HTML lists consistently in all browsers

IE’s and Mozilla’s ordered and unordered lists are rendered similarly by default, but the way the list is indented is opposite in the two browsers. Understanding how to style lists correctly is key to avoiding unexpected ugliness. In this article, I explain how UL and OL are styled by default, how to re-style them so they behave consistently, and uncover an incompatibility that cannot be fixed.

The example list is the same as the example list used in the CSS list-style-position property definition. Each sample image shows Mozilla’s rendering on the left and IE’s on the right. To show visually what is happening, I styled the left border of the content area, the list, and the list items red, black and blue respectively.

With default styling, the colored borders made it clear that the left borders of the list were in different places in the two browsers, even though the content was in the same position. In Mozilla, the list’s box extended all the way left to the content area. There was about 40px of space between the list’s left edge and the list item’s left edge. It was not obvious whether this was created by the UL’s padding or the LI’s margin. In IE, the left edges of the UL and LI were next to each other, so I guessed the indentation was created by the UL’s left margin. In both cases, it was clear the LI had no padding, but there was no way to know if it had a margin in Mozilla.

default styling

To understand whether Mozilla adds padding to the UL or margin to the LI, I removed the padding and margin from the elements and watched the results. First, I removed the margin from the UL:

margin-left: 0

There was no change in Mozilla, so that wasn’t it. Based on that, I decided there was probably padding on the UL. IE collapsed the list all the way to the left edge, so as expected, IE must use the margin on the UL to indent the bullets. Next, I removed the padding from the UL and reset the margin to the default:

padding-left: 0

This time IE was unchanged from the default, and Mozilla collapsed to the left edge, so I guessed right.

At this point, I understood enough to know how to make the browsers render the lists identically, but I didn’t know whether one way was better. I think either will do equally well for general purposes, but for some purposes, it is better to use Mozilla’s method. For example, when placing lists on the right side of a float, there are issues with margins. CSS defines special rules for margins on and around floating elements. In general, I think it is best to style every UL with padding-left, and remove the margins. This expands the left edge of the content box so there are no margins to behave strangely around floats.

So far so good, but I also have also noticed strange behavior with text-indent applied to LI elements. I was trying to style certain LI elements as “new,” with an icon to the left of the text. My first idea was to add a background image and indent the text so it didn’t overlay the image. I saw strange behavior again, though. That led me to experiment further with list items, namely with marker-position and text-indent.

To figure out how the text-indent was implemented, I first set the marker-position to outside. I saw no change in the rendering at all, so I set it to inside, and the results looked very much like the CSS spec’s example:

marker-position: inside

The CSS spec says when marker-position is inside, the marker should become the first inline box in the LI. Given that, I expect the marker to be indented with the text when it is inside the LI, and to remain independent when it is outside the LI. I experimented with this, adding text-indent with marker-position outside:

text-indent: 40px

Mozilla did as expected, indenting the content but not the marker. IE indented the marker too though, indicating the marker is not rendered independently from the content. Next I added text-indent with the marker inside:

marker-position: inside; text-indent: 40px

This time both browsers rendered the text the same, as per the spec. In this regard it seems IE doesn’t follow the spec. To be fair though, the spec is deliberately vague on markers to be backwards-compatible with the ambiguity in CSS1 on markers.

There seems to be no way to indent the text in a LI without also moving the marker, at least in some browsers. I recommend not relying on marker-position because different browsers treat it differently and the spec doesn’t indicate what is absolutely correct. As a side note, Opera treats markers exactly as IE in this regard.

PS: Guess what? It turns out I’m not the first to notice this.

Technorati Tags:No Tags

You might also like:

  1. Why not to use CSS for columnar layouts
  2. How to use CSS to go beyond separation of content and presentation
  3. How to display an HTML table as a folder tree
  4. Simple and complex types in XML Schema
  5. How to use meta-data to sort itself