The process of building my blog - part 2: XHTML/CSS
Posted by Min Tran on 02 May 2008. 23 comments
In the previous post, we had a go behind the curtain to see what I’ve done with my blog design. Now let’s continue to dig into a very important phase - the blog development. In this article, instead of covering all the xhtml/css code (which is really boring), I will show you the pre-coding process, also some cool techniques that I use across this process.Being a web designer, our creativity is always constrained by the computer screen and browsers' strict. That is, when starting with an initial sketch, web designers should determine how the design would be viewed in browsers, and how it would be coded, etc... For instance, we will be thinking in terms of columns and structure, including mashead, footer, and copy body... Anyhow, first things first, I always put my design under my own "pressure" - it's how my background images will be organized and designed. That’s because the amount of backgrounds and the way they display will determine the code structure and how properly the website will work across a big number of web browsers.
Whatever to follow, results are still what count, so here we go.
Let’s turn the x-ray machine on
The backgrounds in layered mode
To keep my code clean and semantic, I reduce the number of background "layers" to 4 or 5. The more backgrounds you add, the more complicated your code is. So just be reasonable! Of course, you can use the CSS 3.0 multiple background attribute to add more than one background into a tag, but this attribute isn’t supported by old browsers. Don’t fall into your own nested-div trap!
Another good reason for limiting the use of numerous background images is that the site would be lightweight and fast-loading.
Reset the style
As we already knew, every browser has its own way to generate the default CSS rules, and thus it becomes a real challenge for developers to code how to have all the pages look and behave the same in all major browsers. By using an appropriately defined set of CSS "reset" rules, it is possible to override default browser styles, allowing us to build our CSS on a "standard" foundation. The simplest method is adding this rule right in the top of the stylesheet.
* {
margin:0;
padding:0;
}
This rule works without a doubt. However, putting the universal selector * ahead, which means forcing the margins and padding of all elements to zero, will potentially cause some trouble with rendering speed. Fortunately, Eric Meyer got an approach with a more comprehensive and safe solution. His code is becoming popular and seems to be the perfect way to reset the browsers' rules.
Setup the typography foundation
Mac OS X offers a beautiful clear-type style, I can assume that. It looks gorgeous when dark text displays on a bright background. But conversely, when bright text is put on a dark background, the thin style becomes bold! This effect obviously kills the readability and makes the content look hefty. Happily, Shaun Inman suggested a brilliant solution to fix that issue.
I simply put into use this declaration body{text-shadow:0 0 0 #3b1900;} and it works out of the box. The thin text now looks as it’s supposed to be!
In the previous step, we reset the browsers’ default rules. But don’t let those elements too plain naked! So now I’ll dress them up by adding some basic styles so-called “typography foundation”.
body {
font:0.82em/160% "Lucida Sans Unicode", Verdana, Helvetica, Arial, sans-serif;
color:#d7b37a;
text-shadow:0 0 0 #3b1900;}
h2 {
font:2em/150% Georgia, "Times New Roman", Times, serif;
padding-bottom:0.5em;
color:#945103;
}
h3 {
font:1.5em/150% Georgia, "Times New Roman", Times, serif;
margin-bottom:1em;
color:#945103;
}
h4 {
font:1em Georgia, "Times New Roman", Times, serif;
color:#a54e1a;
border-bottom:1px dashed #4a2e01;
padding-bottom: 5px; margin-bottom: 1em;
text-transform: uppercase;
letter-spacing: 2px;
}
h5 {
font:bold 1em/160% "Lucida Sans Unicode", Verdana, Helvetica, Arial, sans-serif;
color:#a54e1a; }
p { padding-bottom:1em;}
a {
color:#ae4d13;
border-bottom:1px solid #532501;
text-decoration:none; overflow:hidden;
padding-bottom:1px;}
a:hover{color:#e45600; border-bottom:1px solid #692f01; }
blockquote {
font: italic 1.1em/150% Georgia, Verdana, "Times New Roman", Times, serif;
padding-left:1em;
border-left:2px solid #552d00;
margin-bottom: 1em;
color: #b08355; }
em {font-style:italic;}
Build the XHTML barebone
I know there’s more than one way to do it, but I always get the xhtml started with prototype markup. By coding this way, I can quickly structuralize the layout. What you can benefit from this methodology is that you’re able to put aside your design issues and it’s easy to setup a test-case when debugging. My approach for building up the XHTML barebone is similar to constructing a house – the framing and structure go first, and follows the decoration.
<div id="wrap"> <div id="mashead"> <h1 id="logo"><a href="#">Min’s blog - the online journal of a Vietnamese designer</a></h1> <ul id="nav"> <li id="home"><a href="#">Blog</a></li> <li id="archive" class="select"><a href="#">Archives</a></li> <li id="about"><a href="#">About me</a></li> </ul> <!--close the navigation --> </div> <!-- --close the mashead ----> <div id="left"> </div> <!--close left--> <div id="right"> <div id="subRight1"> </div> <!--close right1--> <div id="subRight2"> </div> <!--close right2--> </div> <!--close right--> </div> <!--close wrap-->
Add the CSS skin
Now let’s take some CSS to skin the barebone:
body {
background: #402202 url(images/masheadBg.jpg) repeat-x; // the background color is #402202 with the masheadBg.jpg spreads across the top of the pages.
font:0.82em/160% "Lucida Sans Unicode", Verdana, Helvetica, Arial, sans-serif;
color:#d7b37a;
text-shadow:0 0 0 #3b1900;
}
#mashead {
width:722px;
height:320px;
background: top right no-repeat;
margin-left:235px;
}
#wrap {
width:960px;
margin:0 auto;
overflow: auto;
}
#left {
width:565px;
float: left;
margin:0px 0 0 0;
border-top:1px solid #4a2e01;
}
#right {
float:right;
width:370px;
padding-top:5px;
margin-bottom: 20px;
border-top:1px solid #503201;
overflow: auto;
}
#subRight1 {
width:175px;
padding-top:10px;
float: left;
}
#subRight2 {
float:left;
width:175px;
margin-left: 20px;
padding-top:10px;
display: inline;
}
The basic shape of the layout is supposedly done. The result should be rendered like this:
Everything stays in the right position. Now I can move ahead to styling such significant elements as logo and naviation.
Styling the logo
To optimize the site for search engine, I use h1 tag to wrap the site name and tag line, then apply image replacement technique to replace the text (tag line) with the logo image, and last, add a simple rollover effect to make it catchier.
logo.jpg
The logo size is set in 159px width and 100px height while the background image is sized with 159px width by 200px height. At the normal state, the background position by default is defined by top-left (x-coordinate:0 and y-coordinate:0). When the logo is hovered, the position will turn to x-coordinate:0 and y-coordinate:-100px, that is, only half of the background bottom part appears. So, I gotta apply this declaration background-position:0 -100px; for the hover state.
#logo a {
display:block;
background:url(images/logo.gif) no-repeat; // set the background image for photo
width:159px;
height:100px;
position:absolute;
text-indent:-9999px; // push the tagline to 9999px from the left side of the screen.
margin:25px auto auto 455px;
border:none;
z-index:10;
}
#logo a:hover {
background-position:0 -100px;
}
And as you can see, I use only one background image for both states. The key advantage to do so is that browser sends one http request only, instead of two. Thus, the loading speed is optimized.
Styling the navigation
First, the navigation is positioned by adding some properties to the ul#nav and setting its width to ensure that it never stretches outside of the mashead.
ul#nav {
list-style:none; padding:130px 0 0 450px;
width:170px; position:relative; margin:0;}
The navigation position is finished. I continue with styling the menu items.
#nav li {
margin-bottom:10px;
padding-bottom: 12px;
border-bottom: 1px dashed #8b3e10;
}
#nav li a {
display:block;
text-align:center;
width:145px;
height:12px;
padding-bottom:0px;
text-indent:-9999px;
border:none;
}
I add an extra space for every item in the navigation by adding margin-top and padding-bottom. Since the a element by default is an inline element, which it’s impossible to set width and height for, I have to add display: block; to force browsers to render each link in the navigation as a block element, then I can set width:145px and height:12px to define the links size.
For me, the most effective and pleasant technique to style the navigation is that only one background is used for all the link items. It's practically trouble-free, provided that the background is to be properly positioned, and hence the background state of each item functions respectively with the specific ids assigned to the items. There’s no secret here, the code is manipulated using the "Matrix Navigation" technique.
#nav #home a {
background: url(images/nav.gif) no-repeat 0 0;
}
#nav #archive a {
background: url(images/nav.gif) no-repeat 0 -13px;
}
#nav #about a {
background: url(images/nav.gif) no-repeat 0 -26px;
}
#nav #home a:hover, #nav #home.select a {
background-position: -150px 0;
}
#nav #archive a:hover, #nav #archive.select a {
background-position: -150px -13px;
}
#nav #about a:hover, #nav #about.select a {
background-position: -150px -26px;
}
Again, I'd like to give more emphasis to this utmost technique by a supposed scenario like this:
We have a sequence of images put into a menu and they act in the form of multiple menu items or icons. This menu has 10 items, of which each is defined with 3 different states (normal, hover, and active). If we use a separate image for each state then we need a total of 30 images, that also means browsers will send up to 30 requests when users mess around with those states. Yuck!
By using the above technique, we will save 29 superfluous browser requests. This is a killer one, isn't it?
Transparent PNG solution for IE6
In my design, I use a semi-transparent image in 24-bit PNG format as the mashead background. Most of modern browsers support PNG24 images with full alpha channel transparency, excluding the painful IE 6 and its older versions. Transparent images display just fine on Firefox, Safari, and IE7, but IE6 displays a weird white background instead.
It’s really a headache for those who want their designs to display perfectly on all major browsers. But whatever you target, IE6 is still the one I take most for granted. There's a few solutions out there that seem to solve this problem, and the most common (and simple) technique is using a filter call AlphaImageLoader. Unfortunately, this is not a standard solution due to the filter not supported by W3C.
A List Apart has a very comprehensive article about this issue and the author came up with Javascript-based solution. Yes, it works. However, it’s not good for performance since this technique needs an additional code to detect the browser and apply the rendering. Like I mentioned above, most of browsers support PNG24 images so the ideal solution is let the browsers themselves render the transparent PNG. The script is only responsible to render the image if the browser is IE6 or its older versions.
Luckily, Drew McLellan helped me fix that matter with a Javascript called "SuperSleight". The script is very easy to use. I simply link to the script and wrap it in a conditional statement to ensure that the script only executes if it encounters IE6 or older.
<!--[if lte IE 6]> <script type="text/javascript" src="js/supersleight-min.js"></script> <![endif]-->
It works like a charm. There is a little bit delay for the background to render from white to transparent, and it’s a fair trade-off though.
Let the footer be the footer
In layout coding, the footer normally is set under the content typically and its position changes dependently on the content length. There would be no complaints if the content is so sufficiently filled in that the footer could be pushed to the bottom of the browser. But what if we have a much shorter content? The footer consequently will stay right under the content, and it looks more weird in the case the background of the footer displays unmatched with that of the entire webpage.
I stumbled upon this article by Cameron Adams and footerStickAlt is what I'm looking for. It real saves my grey hair!
html {height: 100%;}
body { height: 100%;}
#wrap { position: relative; min-height: 100%;}
* html #wrap { height: 100%;}
#wrap { padding-bottom: 140px;}
#footer { position: relative; margin-top: -110px;}
See, the footer is now always at the bottom of the page, no matter how long the content is. The footer is no longer a suspension footer.
Final words
Finishing a design doesn't mean that your work ends there. The most challenging part of any project is to bring it to life and give out best solutions to its problems. Though this article might not have covered exactly and fully what the development process is, I hope I could share the way I've done with a project like this weblog, and introduce you some interesting techniques that you may consider using in your projects.