December 3, 2004

Redesigning A Website Using Only CSS

After setting up the new ‘Autumn Eve’ alternate style sheet, I thought that some people might be interested in the reasoning behind it, some of the problems, and how I overcame them.

The idea was to give the site a completely different look to the default style sheet layout, and most importantly, to do so without touching the underlying XHTML. Of course, as has been mentioned elsewhere by Dunstan Orchard with his superb redesign of the Mozilla Europe site, this is not always as straightforward as it might seem…

The New Layout Design

When taking on something of this nature, it’s important to decide upon a layout that takes the underlying document structure (HTML/XHTML, etc.) into consideration. Many site layouts have specific design ‘hooks’ in place to enable certain effects, such as extra <div> containers to enable boxes with rounded corners and drop-shadows. If you’re in a situation where it’s not possible to add this extra markup, then certain design ‘flourishes’ may not be possible (I use the word may, because browsers such as Firefox or Opera support certain CSS properties that Microsoft Internet Explorer does not, and effects such as these can be applied without altering the markup.)

I decided to go with a reasonably basic fixed-width layout once more, but to have a contrasting colour scheme, to re-position a few of the container boxes, and to add a little Mozilla-only tweak (rounded corners). Dark, orange/brown/red autumnal colours contrasted pretty well with the white/pale blue default scheme, so I based everything upon a desktop wallpaper image that I’d seen at Photo Decor named ‘Autumn Afterglow’.

As Internet Explorer browsers don’t come with a built-in tool allowing the user to switch style sheets (and the Firefox gizmo doesn’t remember the change for future visits) I went with a small, drop-down menu positioned at the top-right hand corner of the page, and decided to store the user’s style sheet values within a cookie. This will allow him or her to leave the site, shut down their browser, and return the next day to the same page style (user persistence is the terminology I’m managing to avoid using here!)

Layout Problems (and Solutions)

All of the information shown here is based upon working with web-standards based browsers such as Firefox 1.0 or Opera 7.54. Although the main style sheet contains some of the browser-specific hacks, most of the Internet Explorer changes are made through external style sheets via Microsoft’s conditional comments feature.

The Menu

As the default style sheet layout has a vertical, left-aligned menu, I thought that it might be nice to go with a horizontal version, positioned at the bottom of the new header container. As the markup for the menu itself is actually near the bottom of the document, absolute positioning is required - but the problem was how to position the menu at the bottom left of the header container. Dunstan’s solution is, unsurprisingly, pretty neat, but here’s my line of thinking:

website menu shown 232 pixels from top of browser viewport

  1. The header container has a specific height (330 pixels)
  2. I gave the menu itself a specific height (80 pixels)
  3. As positioning values in CSS refer to the top left-hand corner of a container, the correct vertical position is the height of the header (330 pixels) minus the height of the menu (80 pixels), which comes to 250 pixels (note that I wanted the menu to appear in front of a ‘bar’ that was just a little higher up than 250 pixels, so I actually used top:232px instead of top:250px)

And for horizontal positioning:

website menu shown left:50% and margin-left:-364px

  1. The width of the header (like the content area) is 730 pixels, so I set the width of the menu container to the same value.
  2. As the menu needs to move horizontally in line with the content area whenever the browser window is re-sized, I first positioned the menu using left:50%
  3. Next, to ‘pull’ the menu to the left into the correct horizontal position, I used a negative left-hand margin value of half the width of the actual menu container itself. Half of 730 is 365, so it’s margin-left:-365px (I actually used -364 pixels on the menu as I wished to allow a pixel or so for a border) [IE 5.5 version]
The Menu Part II - Absolute Positioning and a Box Within a Box

In order to deal with a previous fix for the default layout on the Weblog pages, I had to work out how to position both the menu and the other items (vertical Google Ad, etc.) from within an extra containing <div>. The answer, as I’m using absolute positioning, is pretty similar to that given above for just the menu alone:

weblog page Google Ad and menu container: apply the rules left:50%, margin-left:239px, and top:330pxreposition the menu on the weblog page: use margin:-330px 0 0 -665px

  1. The containing box holding both the vertical Google Ad and the menu is given a width of 124 pixels
  2. This container needs to be moved over to the right-hand side of the page (it will take up position as a third vertical column), so once again it’s a case of declaring left:50% but this time using a positive left-hand margin value is necessary - width of page area/2-width of vertical Google Ad/menu container, or 730/2 - 124 = 241 pixels (I actually used margin-left:239px within my style sheet) [IE 5.5 version]
  3. The Google Ad is vertically positioned at a known height (the height of the header): 330 pixels
  4. Now the menu itself needs to be correctly re-positioned by moving it up and to the left again. The solution is a margin:-330px 0 0 -665px declaration (move up by 330 pixels and left by 665 pixels) [IE 5.5 version]. The reason for this is slightly complicated, and requires taking the menu positional values given earlier into account - if you’re really interested, see the footnote (and don’t worry about losing you’re place here - there’s a link back!)
The Style Sheet Selector

This is based upon the easy-to-use Son of Suckerfish Dropdown menu. When I did my first re-design of this site a couple of years ago, I wanted to avoid using Javascript altogether, but as this dropdown menu is such a useful, unobtrusive little tool, I thought why not (the Javascript is only for Internet Explorer after all!) Each menu item links to a PHP file that re-writes the <link> tags (and Google Ad colours on the weblog pages) depending on the style chosen. As stated earlier, the users’ choice is stored in a cookie for repeat visits.

The HTML for the style sheet selector is a simple, unordered list and is thus only a very small addition to the site pages. It’s added to the bottom of document and then absolutely positioned in exactly the same way as the menu, so I won’t go through it again!

The only real problem that I had with the selector itself was on pages that do not parse PHP - the weblog search results page and the 404 error page. My solution for these two (and ONLY these two) pages was to simply read the style sheet cookie using Javascript and enable/disable every <link> element on the page as necessary. Fortunately for me, as I’m not a particularly BIG fan of re-inventing the wheel, there is a script already out there that I could use to do exactly that: Paul Sowden’s Style Sheet Switcher. Unfortunately, it IS a little bit more Javascript but it DOES work, and for two pages that see comparatively little usage (and won’t be unduly compromised by disabled Javascript), I feel that it’s an acceptable compromise.

Browser Issues and CSS Hacks

Firefox

Firefox: before and after the Clearfix hack

The main background container (div#main) does not fully ‘contain’ the content container (div#content) without a clearing element, so the graduated background image that appears on the right-hand side in pages using more than one column does not display. As my aim was to avoid adding extra markup (<div style="clear:both"> would have solved the problem) the Clearfix hack came to my rescue. I applied it to div#main and that sorted out the problem.

Internet Explorer

The biggest issue with Internet Explorer (both Macintosh v5.2 and Windows v5.5/v6) was the lack of support for the semi-transparent 24-bit PNG images that make up the menu buttons. There are ways around this, as can be discovered if you do a quick search on Google, but I decided to use a separate style sheet accessed through conditional comments to provide IE with transparent GIFs instead.

Macintosh Internet Explorer 5.2

Mac Explorer 5.2: overflow:hidden declaration causes positioning to fail

The header container was ignoring the margin-left:auto and margin-right:auto declarations that should position it centrally. The bug is well known and is triggered by the overflow:hidden declaration. One way of fixing it would have been to use absolute positioning once again, but I was unable to get around a problem with IE 6 on the PC seemingly unable to comprehend a necessary top-margin for the main content container. My solution was to avoid giving Mac Explorer this particular declaration altogether through the use of the Commented Backslash Hack, like this:

 /* commented backslash hack */
 div#header {
   overflow: hidden;
 }
 /* end hack */

Mac Explorer 5.2: extra containers refusing to float alongside content container

Another Mac bug raised its ugly head on the main Weblog page where there are a few floated containers. Ideally, when you left-float a tall item followed by other, shorter left-floated items, these shorter floats should stack up alongside the taller item. Unfortunately, as Mac IE 5.2 incorrectly inherits the containing block’s clear value, and the Clearfix hack required for Firefox actually applies a clear:both declaration to the containing block, I ended up with only one floated item and all the other items wrapped underneath the main content!

The fix for the ‘inherited clear value’ problem was found at Le Chatte Noir: you need to remove the float value from the floated items that are not behaving correctly and use a display:inline-block declaration instead, like this:

 * html>body div#recentEntries {
   float:none;
   display:inline-block
 }
Windows Internet Explorer 5.5

Windows Internet Explorer 5.5: menu positioned incorrectly when page is left-aligned

IE 5.5 is not able to position a block item centrally using the declaration margin:0 auto (nor margin-left:auto and margin-right:auto, come to that) so I decided to offer up a fully left-aligned page. Incidentally, I could have applied a text-align:center declaration to the body selector, but that would have meant resetting the text alignment to the left elsewhere - far too much trouble for an outdated browser like this one. I created an external IE 5.5-only style sheet containing the following menu-related rules:

 div#menu {
   margin: 0 0 0 -495px;
 }

back to related horizontal menu position fix

 div#menuAdsFeedsMT {
   margin: 0 0 0 102px;
 }

back to related menu/Google Ad position fix for weblog pages

 div#menuAdsFeedsMT div#menu {
   margin: -330px 0 0 -658px;
 }

back to related menu position fix for weblog pages

Once again, I used conditional comments to offer a specific external style sheet.

Other Web Browsers

As far as Microsoft browsers earlier than 5.5 on the PC and 5.2 on the Mac are concerned, I’m afraid that they are going to have to stick with the default style sheet - life is just too short!!

The other main problem browser is Konqueror v3.0.5 (viewed at Browsercam). For some unfathomable reason, the main content area is positioned to the extreme right-hand side of the browser viewing area - I’m hoping that this problem doesn’t occur in more recent versions (apparently, v3.3 was released in August this year, but I have not been able to test with it as yet). I’m not sure exactly how many visitors this issue will affect, but even in a worst case situation the page is still usable and readable.

Invalidity Bites

Oh dear! The new style sheet doesn’t validate! Click the ‘valid css’ link at the bottom of the page, and it will say that it does, but if you look carefully down the page you’ll see that it’s actually validating the default style sheet. If you run the new style sheet through the validator, you’ll see two errors noted:

  1. The Mozilla-only property -moz-border-radius - as you might guess, this provides rounded corners to floated boxes and <form> fields, and it’s supposed to be appearing in CSS v3 as the property border-radius. So why’s it in here? The simple answer is, I wanted rounded corners without extra markup! Browsers other than the Mozilla family ignore it, so it’s not really hurting anyone is it?
  2. the display:inline-block declaration is invalid (inline-block is not a valid value for the display property) - this is fair enough, it’s not valid in CSS version 2, but it IS valid in CSS version 2.1 AND, of course, Mac IE 5.2 needs it because of a bug!

So OK, the new style sheet doesn’t validate, but firstly, the -moz-border-radius property is extremely easy to remove, and secondly, the validator should really by validating against CSS 2.1 and not CSS 2 by NOW! :)

In Conclusion…

If you’ve read this far, you’ll be in no doubt relieved to hear that I don’t feel the need to cover the new style sheet design in any more detail. If you do have any questions or comments, obviously feel free to ask or make them in the usual manner!


Footnote: Repositioning the Menu on Weblog Pages

After setting the position of the menu/Google Ad container, the original menu position declarations (top:232px; left:50%; margin-left:-365px;) still apply. If you actually calculate the position of the menu on the Weblog page after applying these rules, it would be:

 top:562px;  /* (330 + 232 pixels) */
 left:665px;  /* (730 + (-365 + (239 + 50%x124)) = 666 pixels or
                 content-width + (menu-margin-left
                 + (menu/Ad-container-margin-left
                 + menu/Ad-container-left
                 x menu/Ad-container-width)) */

Hope that’s cleared that up!

Return to article


Top of Page

Previous Entries

Categories

Monthly Archives

Also available...