Cascading Style Sheets - Finishing with Style
In the first two CSS articles I discussed basic syntax & using CSS to
position and space elements on web pages. I'm going to conclude the series
discussing using CSS rather than tables to build a web page with columns
and discuss is CSS worth the effort?
CSS - A page with columns
When I've needed a page with columns, I've resorted to using html table
elements. Html really doesn't have a built in way to do layout columns.
Not surprising since html was intended as a "content" rather than a layout
language. Tables are not of course, intended to control a page's layout -
they are for displaying tabular data. Using them for this purpose does
work, but tends to produce code that is messy and hard to maintain. When
you toss in IE and Netscape's differences in displaying tables, the
technique is pretty limiting. CSS offers a cleaner method of building a
page with columns.
There are several methods in CSS to layout a page with columns. The method
described below works correctly in both IE & Netscape and has the
advantage of producing a page that isn't a total mess in pre-CSS browsers.
It's unfortunate, but both IE & Netscape still have a lot of bugs (or lack
of implementation) with respect to CSS so many of the methods to layout
columns work in one or the other - but not both.
In order to use CSS for our columns layout, we need to define 'something'
we can put our column content in and then position it. As pointed out in
last month's column, block level elements are the best choices when using
CSS positioning features. We'll use two named DIV elements for this. To be
able to position these two content elements, we need a third named DIV
that provides a reference to position them from. Our layout schema looks
like:
<DIV> ( selector ID = body )
<DIV> ( selector ID = left_col )
content left column
</DIV>
<DIV> ( selector ID = right_col )
content right column
</DIV>
</DIV>
Our "container" DIV (body) - the one that holds both our column content -
gets positioned as relative. As you recall, elements with relative
positioning are placed with respect to where they would normally be in an
html document flow. We'll leave it in its default position.
Next we add our right column. It will fill the entire width of the body
container. Somehow, we have to make room to place the left column. We
accomplish that by creating a large white space area on the left side of
the right column. One would think the way to create the white space would
be to give the right column a large left margin. However, thanks to our
buggy browsers, that doesn't work correctly. Instead, we'll use the body
DIV's padding to create the white space. A simplified box diagram gives a
visual representation of what we are doing.
We'll position our right column as static, i.e., its
default positioning. We'll position our left column with absolute
positioning. Remember, elements with absolute positioning are placed with
respect to the nearest parent element. In this case, the DIV right_col,
since we want to control where within the right column's white space the
left column will be displayed.
The last piece of setting up this style sheet is specifying how big our
columns will display. Intuitively, we'd like to use a percentage width so
that the layout scales depending on the width of the user's viewport.
Unfortunately, we can't do that, because of a bug in Navigator. Instead,
we'll use the font scale, em, since that does work correctly in both
browsers.
Putting all this together, we end up with a CSS like the following:
<style type="text/css" >
#body {
position: relative;
}
#right_col {
padding-left: 11.5em;
}
#left_col {
position: absolute;
top: 0;
left: 0;
width: 10em;
}
</style>
In this example, I've made the left column fairly narrow with the bulk of
the page taken up by the right column. You can of course, increase it's
width making sure you keep right_col's padding-left larger than left_col's
width. Also keep in mind that you are making some assumptions about the
width of the browser's viewport. In this example, I've used the right
column as the container for the left. You could just as easily reverse
that and have the left column contain the right.
Here's a sample html page using the style sheet:
<body>
<DIV ID="body">
<DIV ID="right_col">
this text is in the right column. yada-yada ...... It takes up bulk of the
viewing space.
</DIV>
<DIV ID="left_col">
this text is in the left column. It occupies a relatively small portion of
the viewing space.
</DIV>
</DIV>
</body>
Adding page content above the columns
Adding content above the columns is straight forward. Since the DIV
containing our columns (body) is positioned relatively, any content placed
above will simply push our columns down on the page.
<body>
<p> adding content here just pushes our columns down on the page </p>
<DIV ID="body">
Adding content below the columns.
This is a little less straight forward. We've complicated it by using a
block element with absolute positioning i.e., our left column. Remember
that a block element positioned absolutely is totally removed from the
html document flow. It will be ignored when the browser positions other
page elements. Our right column uses it's default positioning, so it's
height is considered in the document flow. Any content added to the page
will be positioned following the right column. This means that if the left
column content occupies more vertical space than the right column, any
content added after our columns will overwrite the left column.
The work around here is to make sure the vertical space used by the
absolute positioned column is always shorter than the other column. How
much shorter? That all depends. Since we do not define a width for the
right column, it will vary with the width of the browser's viewport and
thus, affect the height of the right column.
We can also limit the effects of this by specifying a width for the right
column. This gives us more control over the relative heights of the two
columns. The disadvantage of doing this - if the browser viewport is more
narrow than the combined widths of the columns, the right column will
simple be cut off. A sample CSS that does this is:
<style type="text/css" >
#body {
position: relative;
}
#right_col {
padding-left: 11.5em;
width: 21.5em;
}
#left_col {
position: absolute;
top: 0;
left: 0;
width: 10em;
}
</style>
download the CSS part 3 examples at:
http://www.dalesplace.net/css3.zip
Cascading Style Sheets - Are they worth it?
If you're anything like me, our foray into CSS has raised as many (or
more) questions than it provided answers. CSS is not easy to learn. Not
only is there a lot to it, but it requires completely rethinking web page
design. On top of this, even the "mostly compliant" browsers seem to have
some significant bugs and can not be counted on to display CSS content the
same between brands and versions.
On the other hand, CSS does provide some intriguing tools. The ability to
separate layout from content has a strong pull, as does the ability to
simplify some of those screwy html work-arounds we've used to force web
pages to look the way we'd like them to.
Now if only the Browsers would act right. For now, this web author will
stick to the "Keep It Simple" model. A lot of the basic CSS stuff works
without having to do a lot of fooling around - and still looks "ok" in
pre-CSS browsers. For now, I'll limit my use of CSS to the basics. Once
the version 6+ browsers become dominant - maybe - it'll be time to learn
CSS in detail and build web pages the "right" way - and separate content
and layout.
Web references:
http://www.webreference.com/html/tutorial19/
http://www.w3.org/TR/REC-CSS1#formatting-model
http://hotwired.lycos.com/webmonkey/authoring/stylesheets/
http://builder.cnet.com/webbuilding/pages/Authoring/CSS/
http://www.webreference.com/html/tutorial9/
|