TV version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer


Weblog Entry

Positioning and the Cascade

March 04, 2004

Two quick CSS tricks that I’ve been relying on more and more lately:

  1. Applying positioning to a parent element, to allow absolute positioning of a child element within the parent.
  2. Context-sensitive elements. Chaining classes by applying two or three or more to the highest parent element possible allows cascading down to deep child elements.

Positioning

Something I’ve only recently wrapped my mind around is that if you position a parent element by using absolute or relative positioning, you can absolutely position any child elements from the edges of the parent.

Too abstract? Try this: apply position: relative to a <div>, without supplying a top or left value. Then apply position: absolute; to the <p>s inside it, with top and left values. Sort of like this:

#parent {
 position: relative;
 height: 200px;
}

#parent p.first {
 position: absolute;
 top: 20px;
 left: 200px;
}

#parent p.second {
 position: absolute;
 top: 40px;
 left: 150px;
}

Why’s that useful? Instead of the <p> elements starting from the top left of the browser window, they start from the top left of the containing #parent. You get the benefits of absolute positioning with none of the mess of fixed elements. Especially useful for fixed-width pages that are centered. Like this one. Here’s an example:

position: absolute; top: 45px; left: 250px; font: 8px silkscreen, verdana, sans-serif; line-height: 2;

position: absolute; top: 120px; left: 10px; font: normal italic 14px georgia, serif; text-transform: lowercase;

position: absolute; top: 0; left: -100px; font: bold 36px helvetica, arial, sans-serif; color: #7895BD; line-height: 0.8; width: 100em;

position: absolute; top: 20px; left: 30px; width: 120px; font: 9px verdana, sans-serif; line-height: 1.5; color: #324F70;

More on this trick tomorrow. §

Cascading

This one is a bit harder to explain, but the basic mechanism works like this. You can apply a bunch of classes to a single element. The higher up the element is in the document tree, the more each class can control. By applying them to a top-level element like <body>, you give yourself a bunch of different ways to get at the elements contained within. (Ryan Carver explains it in a bit more detail.)

<body class="weblog homePage blue">

Using this example code, you can reference deep elements with fairly simple selectors, and customize items based on which page they sit on. For example, let’s say you change the blue class in the above code to red. One simple class change in the body tag, and you can change the colour of your entire site by referencing each child element:

.red h1, .red h2 {color: red;}
.red #sidebar {color: red;}

Of course, if you don’t want red, you can go green:

.green h1, .green h2 {color: green;}
.green #sidebar {color: green;}

The power starts becoming apparent when you set up a style sheet with a bunch of variations like this, and changing between each is as easy as modifying a class.

Similarily, we could hook into the weblog class and style pages that are specifically weblog content differently from those pages with, say, static or permanent classes. And we can combine both colour switching and page-sensitivity on the same site.

There are really interesting implications from this, particularly from a code viewpoint. Instead of littering your source with inline scripts, a simple body class switch is all that’s needed. By passing a few variables on to the page (and you can almost view each of these classes as variables, incidentally) you have some incredibly flexible control over how the page is rendered.

Still exploring this one. More coming in the next few months as various projects launch. §


Reader Comments

Stephen says:
March 04, 01h

The cascading classes trick at first appears to be simple, however could this allow development of a new type of style-switcher? You could simply use the DOM to alter those classes. Just food for thought.

Dave S. says:
March 04, 01h

Jonathon – no. By applying three classes to the body element, I can usually remove a ton of classes elsewhere in my code. Because I’m cascading down I can build bigger selectors like “.blue #header ul a:hover” instead of, say, giving all links in the list their own class. This is a bad example, but until I write the followup article, it won’t be immediately clear unless you start using it.

Dave S. says:
March 04, 01h

Stephen, I think that might work. Changing the class manually works just fine, automating it should too. Nice idea.

Mike P. says:
March 04, 01h

Stephen,

I’ve tried that before, the DOM switcher idea, and ran into text-reflow problems with certain browsers, in certain situations. I believe the worst was I.E. (surprise!).

March 04, 01h

As an additional hint: Use *always* ‘body:position:relative’ if you use positioning at all on your site.

See: http://216.239.59.104/search?q=cache:HTnsWwY8qJwJ:www.mozilla.org to understand why. ;)

March 04, 01h

That positioning trick is quite useful, and I tend to use it in the situations described (centered column or unknown coordinates). Absolute positioning seems to be a wee bit forgotten these days, though it’s one of the more powerful features of CSS.

The second trick is somewhat new to me, though I have used single classes on the body to style, say, headings and navigation differently in different sections. The example you give is interesting, and I’m sure the follow-up will shed a little more light on its use.

March 04, 01h

While both these techniques are quite helpful, one thing I’d like to see is the ability to group classes together under other classes (or IDs/elements for that matter). Something like this:

with(body.webLog) {
p { … }
a { … }
h2 { … }
}

with(body.misc) {

}

with(.foo) {
p { … }
}

Not sure how that’d be best executed, but I’d like to see it happen.

March 04, 01h

I had no idea you could apply multple classes like that. I can see how the cascade is usefull.

I have used this kind of class on the body, to make the active tab (or whatever nav) appear different than it’s brothers. It’s easier to do this with systems like MT, than to put a ‘class=”active” ’ on the or of the element.

Even better have multiple flags, so to speak, applied the body.

Also, multiple classes are usefull when you want to apply two different styles to an element. Say you have a style for .indent and .purple and want to apply them both to a single . In the past, I would have made a new .purpleindent class, but no more.

Thanks.

Eric says:
March 04, 02h

Multiple classes are useful ways to get around IE’s lack of good selectors. You can use things like “first” “last” etc without interfering with the rest of your styles.

10
Jonathan Dobres says:
March 04, 03h

My mistake. I was misreading things. I actually use this selection method as much as possible. I just don’t find much use for it on the body tag.

dusoft says:
March 04, 03h

The cascade method seems pretty useful to me and although I know about it for some time I haven’t been using it much. It should simplify CSS files since some redundant classes could be removed.

March 04, 05h

While I’ve known about the absolute positioning trick for a while now, the notion of applying multiple classes to a single element is completely new to me. I just didn’t know that this was legal syntax. Sure, I’ve always wanted to be able to do something like this, but I’d never read anywhere that it could be done.

Thanks for clearing this up, Dave! Multiple classes on a single element should certainly make our CSS files much more concise when applied properly.

March 04, 05h

I came up with something conceptually similar to style different themed sections of a website, though I didn’t take it as far as you have. It worked quite well to have the class on the body tag, so I could, then, affect huge changes in the pages by simply doing something like body.sectionname #content {attrs}. It was one of my better moments. ;)

I await part 2 of the article to see what the great mind of Dave reveals. I’m sure it will be useful! :)

Nice work!

March 04, 06h

I’ve been familiar with both of these concepts for a bit, and while I’ve not used the multiple classes, I have found the positioning quite useful. Also, if one did not know how this worked, I’m sure it would be rather frustrating. Very nice.

15
Jonathan Dobres says:
March 04, 12h

Interesting positioning trick, but I question the usefulness of the cascading technique. Doesn’t sticking so many class identifiers in your tags harken back to the days when content and presentation were one and the same? Granted, linking everything to a stylesheet does make things more flexible, but it’s still an awful lot of extra classes (and CSS).

Daryl says:
March 04, 12h

I’ve used the first happy discovery for some time in building (horror of horrors) Windows-like applications – complex forms with subsections corralled into their own little labelled boxes within the main application grid. By nesting two divs within a parent div for each such subsection, you can build (for example) a gray 3D box with a little blue offset label. Whether or not following the Microsoft look is a good thing is debatable – that my users are comfortable with that look is an argument in favor of it, and I’ve found that using CSS tricks like this one has been invaluable in putting my Web apps together. I was first turned on to using CSS in this way by CSS Zen Garden, btw.

Mike P. says:
March 04, 12h

In the little ‘css’ challenge I did in my blog a couple of people applied the positioning trick to acheive the layout in question.

Check here for an example…
http://www.fiftyfoureleven.com/sandbox/weblog/2004/mar/css-semantic-challenge-results/

AkaXakA says:
March 05, 03h

Jeff - That’s odd…
I never really seem to have problems concerning negative margins…
Just take a look at my website…the top right logo is fully negatively positioned (sounds odd, but you know what I mean).

I haven’t tried to use ‘em’ as a size in those cases…but what you could do is try to make the margin-top of the div em too, as you have tried to put
div {
position: relative;
}
in…right? (or absolute…as long as IE has something to work with.)

Trent says:
March 05, 05h

This example illustrates a Firefox bug I’ve been dealing with for a long time (since Firebird as well).

In Firefox, go to the paragraph that begins “Why’s that useful?” Select text, and continue to drag the selection over the div that’s right below it. Suddenly, the entire selection skips down a page.

It also occurs if you select the text below the div and drag up…but it still skips downward!

Yeah, it’s a browser problem. But browser problems are often *our* problems, too.

20
Scott Plumlee says:
March 05, 05h

If you look at Ryan Carvers weblog at www.fivesevensix.com, you’ll see how he used the multiple classes trick to style www.onetruefit.com for Lee jeans. I’s starting to use it on my companies site to apply a style to a sub-division of the site, and then allow common style elements to be used without having to write redundant styles.

Pat W says:
March 05, 06h

It seems to me that the only reason to use multiple classes in the body is to allow for the co existence of various styles within one style sheet. Otherwise why not just use #body #header ul a:hover instead of .blue #header ul a:hover?

Using the multiple classes does allow for more separation of the style elements so you could change .blue whch could hande color but not change .weblog which could handle typography elements.

Using the cascade is a great way to style the actual elements without having to add classes I use it almost exclusively using classes only for instances that IE doesn’t support like adjacent sibling selectors, and :first pseudo classes for example.

In fact a good way of shoe horning a good CSS positioned section into an olf Table and Font tag ridden page (I have to do this way to much for work) is to enclose it all in a ided DIV or ided TD and cascade everything div#styles ul#header li a:hover. This way ULs outside the #styles div won’t be touched by your new styles.

AkaXakA says:
March 05, 07h

The class trick has been used by Douglas Bowman (of stopdesign.com) for a long time now….

Also, the dynamic changing of classes is very easy in php for example.. just put an echo in to print a certain variable…nothing to it.

Another trick extending the absolute in relative, is to use minus margins…they’re a great way to have a footer or header that scales along with the content.

March 05, 07h

AkaXakA - Except that browsers interperet magrins, especially negative margins, differently. I’ve had times when trying to extend this code with that technique that came out amazingly broken…

<div>
    <h1> some text </h1>
    <p> some text </p>
<div>

Make a border on the div, then negative margin the h1 to -1em and set it’s size to 1em. Should place the text right on top of the border of that div, right? Pft. Sometimes in other browsers (IE I hate you) it simply wouldn’t show up - like I had set overflow: none. Even changing overflow around didn’t help either. Be wary wtih negative margins.

24
Michael R. Havard says:
March 05, 07h

We’ve been doing something similar for awhile where I work. We have different types of “containers” and change the styling of content within those containers using the cascade. I.E. class=”container” or “container panelgroup” or “container menu”, etc. It’s been quite helpful in keeping the majority of the code pretty generic and semantic but still getting a great degree of flexibility in styling.

Joseph says:
March 05, 10h

I think the “cascading” technique might also be another way to provide the “defining of color constants” that many designers would like to see in CSS.

ie, define a color once in your css, then have it apply to various different elements. If you later need to all instances of the color to another color, you can do so by modifying just one line of CSS.

One advantage to this approach is that you avoid the confusion of multiple definitions of a single class (eg, one grouped with others for shared properties, and another by itself for idiosyncratic properties), which is the present method of doing this.

Sure you have to assign the extra classes in the html at first, but by that, what you are actually doing is defining design relationships between elements, which seems to be a good thing.

Of course, it only allows single-purpose constants (you would have to define different constant-classes for background-colors and foreground-colors), but still, that also strengthens your element relationships.

Most people talk about CSS “constants” (or “variables”–they use the word interchangably) with reference to colors, but it has obvious applications for other properties too.

Er, did I make sense, or should I provide an example? I haven’t really tried it yet, so for complex sites it might be more inefficient than the prevailing approach.

Dave S. says:
March 06, 02h

Hasan - that’s valid shorthand, actually. ‘normal’ applies to font-weight in this case. http://www.w3.org/TR/CSS2/fonts.html#propdef-font

Dave S. says:
March 06, 09h

Joseph - bingo! That’s exactly what I used it for on one recent job. The colour sheme is controlled by one style sheet that dumps all fore- and background colour information into a quick series of rules. (You need a few more than you’d think actually, due to varying colour combinations) Adding a new colour scheme is all of 5 minutes work, most of it in coming up with a pleasing scheme in the first place.

I didn’t actually end up making full use of the cascading trick described above, though I could have. For an example, let’s say you have an ‘information’ section and a ‘working’ section. The first is just static content, the second actually expects interaction from the user. You want to style each a bit different, so the information section is blue, the working section is orange.

.information #navigation, .information h1 {
color: #fff; background-color: red;
}

.working #navigation, .working h1 {
color: #fff; background-color: red;
}

If you set up the style sheet this way, the only thing needed to trigger the color change is a body class:

<body class=”information”>
<body class=”working”>

Simplified, but when you extend it to a whole whack of rules at once, it’s incredible how easy it is to shift the whole look through one selector. Doubly so if you’re controlling the layout the same way.

28
Hasan says:
March 06, 10h

Dave, I was looking at your parent-child element positioning example and something didn’t look right. It took a minute, then I saw it…font: normal italic 14px Georgia? Thought you would want to know.

29
Hasan says:
March 07, 05h

I use a PC, and the example renders fine (it turns out) in IE6 and Opera7.23, but is showing as normal 9px in FireFox0.8 and Netscape7.1. Is this a known bug? What’s the dilly, yo…er, what gives?

30
Andrew says:
March 07, 11h

Just in case anyone hasn’t read it, Doug Bowman wrote extensively about the absolute within relative positioning idea a while ago:
http://www.stopdesign.com/also/articles/absolute/

J. Mulder says:
March 09, 01h

I’ve been using the positioning ‘trick’ for a while as well and it fits my way of thinking completely. I am sure I am not the only one who highly dislikes any constraints you’re putting yourself up with when designing a layout. Relative positioning is, for me, the most comfortable way of doing so.

I wouldn’t want to call this a trick though, I recall reading this in the specifications. Or maybe not :)

32
Hasan says:
March 10, 03h

Dave- figured it out. The spec you cited gives an incorrect example! The syntax is font-style, font-weight. http://www.w3.org/TR/CSS2/fonts.html#propdef-font The css doesn’t validate. http://jigsaw.w3.org/css-validator/validator?profile=css2&warning=2&uri=http%3A//www.mezzoblue.com/archives/2004/03/04/positioning_/
I know it’s nitpicky, but it was bugging me. Thanks.

Dave S. says:
March 10, 04h

Ah, you’re right too. I confused my order, whoops.

What’s interesting is that the example on the spec you mention *does* actually validate [validate through textarea], but that’s because the validator reverses the order of the bold and italic keywords!

34
Hasan says:
March 10, 04h

Even more confusion! You’re code should be valid because “A double bar (||) separates two or more options: one or more of them must occur, in any order.”! http://www.w3.org/TR/CSS2/about.html#property-defs And more!.. the style you actually wrote was 20px, not 14! lol Anyway, many thanks for your kind replies, I’m sure you’ll agree I’ve bugged you enough.

March 11, 11h

Forgive me if this has been suggested – I don’t have time at the moment to read every comment.

That being said, I’ve used the multiple class trick with Movable Type to create a different style for each blog category. FOr exampl, say I want a different background image per category. Maybe I want a guitar image when I’m talking about music, and some cards when i’m talking about poker. You can set up your MT templates to apply the category name as a class, so that you get something like:

div class=”blogEntryBody music”

and

div class=”blogEntryBody poker”

That way, you can assign styles that apply to ALL categories (fonts, colors, width, height, etc.) to DIV.blogEntryBody and those special styles (such as background image) to DIV.poker and DIV.music.

Very handy (even though i’m not currently using it myself). :)

March 29, 01h

Thank you so much. The first tip was like a lightbulb coming on. I just went back through a css file I was working on and stripped away tons of bad hacks.

Why didn’t I ever see it like that? Again, thanks.

Eversite says:
April 23, 07h

Wow, the positioning thing actually works :-).

I made a box model, with rounded corners using several div’s to apply the images to each corner. When i wanted to make a footer, the images went to the top of the body, killing my boxmodel.

I have a question though: if you don’t apply any positioning to a div, then what is it set to?

Thx for your solution…