Create a Killer Band Site in Drupal – Part 3 – XHTML

Turquoise Flag-Tip

This tutorial is another special series written guest author Sean Hodge from aiburn.com and Connection Cube. He is an expert in Drupal, which I am totally not familiar with. He intrigued me when he told me that the majority of the bands on Sony’s record label are powered by Drupal. Drupal is basically an open source CMS, and I was interested in learning more about it. So that’s why he’s writing this tutorial for us. You can learn along with me!

Read the introduction – What’s Drupal and why?
Read Part 1 – Design it Illustrator
Read Part 2 – Slicing it Illustrator
Read Part 4 – Theming in Drupal
Read Part 5 -Drupal Admin

Introduction

In our last tutorial we sliced up our graphics. Now we are going to take those graphics and move on to coding the XHTML and Cascading Style Sheets.

File Setup

I’m on a Mac. The programs I use for coding are firstly Coda. Its a great program that you can use for coding and ftp. You can see a screenshot below. When I need a more specific tool to a need at hand I use CSSEdit, TextMate, or Transmit.

First off, below is a screenshot of the file directory. You’ll want yours to match this structure for this tutorial. You’ll need the exported photos from the last tutorial as shown below as well.

Files

Standards Based XHTML

Standards based design is a common part of web design today. Here are a few links if you need to beef up your skills in this area: A List Apart, 465 Berea Street, and SimpleBits. Standards based design is a movement away from table structured layout. There is also a focus on semantics, which basically means naming your classes and id’s on what they do and not what they look like. Overall, you want to create html code that is simple and structured around the data. Of course in practice you often end up with a handful of extra divs that are there just to support the appearance of the site. Its still a huge step forward from the bad old days of Font tags, ouch.

This tutorial will hand you the XHTML code. We will cover the more interesting parts with some detail as we work our way through the Cascading Style Sheets. We’ll skip the basics of inserting paragraph tags and things like the doctype setup. Refer to the XHTML download below for that. This tutorial will focus on the process of creating a Standards Based site and on the most important CSS elements. It will present some of the XHTML as it relates to the CSS as well.

** Edit: Zip file with all of the XHTML / CSS files here. **

Here is a link to the XHTML Code. We will also give you the final CSS as a resource as well, CSS Code. You may want to reconstruct the CSS as we go along for practice though, or at least to review it carefully. Here are links to our IE specifc stylesheets ie_6.css and ie_7.css. We’re concerning ourselves with coding and testing back to IE6 in this tutorial, not further. Refer to this Working Example as you follow along as well.

Files

CSS Reset

After a section that names the document and tracks the dates of updates my stylesheets almost always start with a CSS Reset. A CSS Reset is used to balance out browsers default behavior. Every browser has there own default styles for elements. So, there are differences in the way Firefox and Internet Explorer will display the hr tag for example. By using a reset they will both display the hr tag the way you specify it without discrepancies. So the goal of a CSS Reset is to create a clean slate to start your CSS coding from. Here is a link to the Reset I use: Reset Styles at MeyerWeb. After naming your stylesheet go ahead and place the reset next.

CSS Reset Styles

Note: This CSS Reset though does not reset the default stylesheets that are set up in Drupal. There are numerous stylesheets that will need to be accounted for when we move over to Drupal. We will discuss this further when we get to the next tutorial in this series.

Base HTML

This is the name I give to the group of styles that make up our basic HTML elements. Its a good starting point for any style sheet after the Reset. The elements styled in this section are not exhaustive, but are a good start. Refer to the stylesheet download for the list.

Base HTML

Our Layout

In the next section of our stylesheet we account for our page layout and design. Its important to plan our entire page at this point. We’ll start out with defining our outer most layers and then work our way in. First off all, we will have page wrappers to use to define our content width and to assign our background to. We assign our page background to the page_wrapper id. I set the background to this wrapper rather than the body because there is a module I almost always use in Drupal that would have a small conflict if assigning the background to the body. I’ll cover that in the coming tutorials.

Page Wrappers

The page_wrapper is floated:left, given a width of 100 percent, and the background image is set to repeat-x so it will stretch the length of the browser screen. We also make sure to set a position of relative to the page id so if we use absolute positioning later on it will be placed within the wrapper. We will review this technique in the Top Navigation and Search section.

Page Wrapper Html

<div id="page_wrapper">
 <div id="page" class="two_column">

 </div><!-- /page -->
</div><!-- /page_wrapper -->

Page Wrappers CSS

#page_wrapper {
 background: #28201d url(images/bg/bg_page.jpg) 
repeat-x 0 0;
 float: left;
 width: 100%;
}
#page {
 width: 960px;
 margin: 0 auto;
 position: relative;
}

Overall Page Layout

Next we define the layout for our major sections. We have the Top that will hold our Top Navigation and Search Area. The Header that will hold our header design. Our Primary Navigation Bar is a part of the basic page layout though we’ll cover it in our navigation section. Then we have our Content section that will hold our content backgrounds: our Main content column and our Sidebar_Right column. The Footer will hold our legalese and some links.

Layout Sections Html

<div id="top">

</div><!-- /top -->

<div id="header">

</div><!-- /header -->

<div id="primary_nav_bar">

</div><!-- /primary_nav_bar -->

<div id="content">

</div><!-- /content -->

<div id="footer">

</div><!-- /footer -->

Layout Sections CSS

Most of our sections will utilize floating layouts. Here is a link to read up on using floats for layouts if your not familiar with it: Floatutorial.

Floatutorial

The top is an exception. We’ll discuss the top shortly. The primary navigation will be discussed shortly as well. The footer is simple enough that it doesn’t require a style to define its dimensions, although it is its own section in regards to the HTML layout.

The header defines its exact dimensions because we have an image to put in there that has a specific width and height. The content section will begin after the primary navigation bar and then end before the footer. Like most of the layout, the header and content are floated.

#header {
 background: url(images/bg/bg_header.jpg) 
repeat-x 0 0;
 float: left;
 width: 960px;
 height: 204px;
}
#content {
 margin-top:15px;
 width: 960px;
 padding: 0;
 display: block;
 float:left;
}

Content Section

Our Content section is made up of three outer divs. content, content_top, and content_bottom. We target these divs by first targeting a class of two_column that we applied to our page div. This is done so that we can have a one column layout as also. We will cover that in our next tutorial.

Content Section HTML

<div id="content">	
 <div id="content_top">	
  <div id="content_bottom">

  </div><!-- /content_bottom -->
 </div><!-- /content_top -->
</div><!-- /content -->

Content Section CSS

All of the three ids below are floated and they fit within each other. To take advantage of the document flow, the middle background is applied to the first content div. Then the top and bottom backgrounds are applied to the subsequent divs and therefore will rest on top of the middle background. This is how we get the pieces to fit together. They overlap.

.two_column #content {
 width: 960px;
 padding: 0;
 display: block;
 background: url(images/bg/bg_content_two_col_mid.jpg) 
repeat-y 0 0;
 float:left;
}
.two_column #content_top {
 width: 960px;
 padding: 0;
 display: block;
 background: url(images/bg/bg_content_two_col_top.jpg) 
no-repeat 0 0;
 float:left;
}
.two_column #content_bottom {
 width: 960px;
 padding: 0;
 display: block;
 background: url(images/bg/bg_content_two_col_bottom.jpg) 
no-repeat left bottom;
 float:left;
}

These boxes are special. They are rounded and the top background image has a gradient applied to it. As long as the top background is cut after a point where its gradient becomes solid then it will work out fine to put these together. The middle section needs to be a solid repeating color that connects to the top background image after the gradient has fully broke to a solid color. I’ll also mention that you don’t want the top background to be longer than your sites content or else the gradient will get cut before it connects to the middle part.

If our content was ever as short as the image below then our gradient would not look right. This is because the top background image has to be as long as the gradient. Fortunately, our content will never be this short.

Goband Content Background Gradient Issue

You can see in the image below that if the content is just a little longer there are no gradient display issues.

Goband Content Background Gradient Issue Fix

Inner Content Sections: Main and Sidebar_Right

Inner Content HTML

The basic setup of the Inner Content is two columns. We have already taken care of the presentation of our background boxes. We do need to get our columns to float correctly though. Below is the basic setup of the two columns. Refer to the download for the rest of the HTML inside.

Inner Content HTML

<div id="main">

</div><!-- /main -->
							
<div id="sidebar_right">

</div><!-- /sidebar_right -->

Inner Content CSS

First of all we float the main column to the left. Then we float our right_sidebar to the right. We set our width with the padding subtracted for both columns. We have a standard two column float layout for our inner content.

/* @group main */
#main {
 width: 600px;
 display: block;
 float: left;
 margin-left: 0;
 padding: 0 20px 30px;
}
/* @end main */

/* @group sidebar_right */
#sidebar_right {
 float: right;
 width: 260px;
 display: block;
 padding: 0 20px 30px;
}
/* @end sidebar_right */

Later in the stylesheet we list all the aesthetic style for the main and right_sidebar columns. Refer to the stylesheet download for that. Of special interest is the promotional area. We establish an area for the photos in our main column that uses the same techniques as above to float the layout. So these promotional areas are floated within the floated main column. View the CSS below.

#promo_one_front {
 float: left;
 width: 408px;
 display: block;
}
#promo_two_front {
 float: right;
 width: 178px;
 display: block;
}

Primary Navigation

Horizontal Navigation is a popular choice on the web and its not that difficult to achieve.

Primary Navigation XTHML

We create our XHTML first. We are making some unique ids. We are also placing classes that we will be able to tap into once we get over to Drupal.

Note: the HTML below is not exactly what the Drupal default output will look like, but what we are taping into will be there. Drupal will output more classes as well. But what is listed below is what we will be concerned with for our style sheet. It will work in our next tutorial were we theme in Drupal.

<div id="primary_nav_bar">

<ul id="primary_nav">
<li class="first"><a class="active" href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Blog</a></li>

<li><a href="#">Booking</a></li>
<li><a href="#">Tour Schedule</a></li>
</ul><!-- /primary_nav -->
				              
</div><!-- /primary_nav_bar -->

Primary Navigation CSS

First we set the background for for the primary_nav_bar. We continue to use floats in this layout. The primary_nav_bar creates another section for our theme. We set a height to work with for the primary_nav_bar. So it is not vertically flexible. Its easier to work with for our design at an exact size.

Then we attach our divider image to the primary_nav_li on the right to give some added detail of shading and highlight in between each nav button.

Next we start coding our button links. Notice that using padding means you need to shorten the height to correspond to the added padding. Our images for the primary_nav a, primary nav a: hover, and primary_nav a.active are actually the same sliced image. We are just telling the image to move to show either the normal or active images. This technique is called Sliding Doors. Here is a link to the original article on A List Apart Sliding Doors. If your not familiar with that technique than its a good place to get started reading up on it.

Sliding Doors CSS Styles

To show our unique home button we will take advantage of the first class. We are using the same technique here and virtually the same code, but we use a unique image that has the left side rounded.

#primary_nav_bar {
 background: url(images/bg/bg_primary_nav.jpg) 
repeat-x;
 float: left;
 color: #fff;
 text-transform: uppercase;
 width: 960px;
 height: 30px;
 margin-top: 8px;
}
#primary_nav li {
 float:left;
 display:inline;
 height: 30px;
 margin: 0;
 background: url(images/bg/bg_divider.jpg) 
no-repeat top right;
 padding: 0 2px 0 0;
}
#primary_nav a {
 background: url(images/bg/bg_btn_primary_nav.jpg) 
no-repeat top left;
 color: #698f24;
 float:left;
 display:block;
 position:relative;
 height: 22px;
 padding: 8px 14px 0;
 text-decoration:none;
 font-weight:bold;
 vertical-align: middle;
 font-size: 12px;
}
#primary_nav a:hover {
 color: #b7d62d;
 background: url(images/bg/bg_btn_primary_nav.jpg) 
no-repeat 0 -30px;
 cursor: pointer;
}
#primary_nav a.active {
 color: #b7d62d;
 background: url(images/bg/bg_btn_primary_nav.jpg) 
no-repeat 0 -30px;
}
#primary_nav .first a {
 background: url(images/bg/bg_btn_primary_nav_home.jpg) 
no-repeat top left;
 color: #698f24;
 float:left;
 display:block;
 position:relative;
 height: 22px;
 padding: 8px 14px 0;
 text-decoration:none;
 font-weight:bold;
 vertical-align: middle;
 font-size: 12px;
}
#primary_nav .first a:hover {
 color: #b7d62d;
 background: url(images/bg/bg_btn_primary_nav_home.jpg) 
no-repeat 0 -30px;
 cursor: pointer;
}
#primary_nav li.first a.active {
 color: #b7d62d;
 background: url(images/bg/bg_btn_primary_nav_home.jpg) 
no-repeat 0 -30px;
}

Top Section: Top Navigation and Search

Now lets get into the details of absolute positioning inside relative containers. I’ve always liked this technique. It works really well. Here is a good link that explains this technique in detail: Making the Absolute, Relative.

Absolute Relative CSS

For our purposes the top has been given a position of relative and it is already centered because its inside the bounds of the centered page_wrapper. It also has a width of 960px. When we position our elements within the top absolutely they will be placed according to this relative wrapper.

Without absolute positioning the top section would be in the document flow. It would push our header content down and make it not match up with our background image. Not what we want. See the image below.

Top Positioning Problem

Below is the orrected version after absolute positioning has been applied.

Top Positioning Problem Corrected

Top Section HTML

<div id="top">		
 <div id="top_nav">
  <ul>
   <li><a href="#">Link</a></li>
   <li><a href="#">Link</a></li>
  </ul>
 </div><!-- /top_nav -->
				
 <form action="/search/node" method="post" id="search-theme-form">

  <div id="search" class="container-inline">
   <div class="form-item">
    <input type="text" maxlength="128" name="search_theme_form_keys"
id="edit-search-theme-form-keys"  size="15" value="" 
title="Enter the terms you wish to search for." class="form-text" />
   </div><!-- /form-item -->
		
   <input type="image" src="files/icons/ico_search.jpg" 
name="op" value="Search" id="search_icon"  />
   <input type="hidden" name="form_token" 
id="edit-search-theme-form-form-token" 
value="26c6ef5d24a9b8af03b19f05131a19bc"  />
   <input type="hidden" name="form_id" 
id="edit-search-theme-form" value="search_theme_form"  />
						
 </div><!-- /search -->
 </form>	

</div><!-- /top -->

Top Navigation CSS

There are a few way you could do this I decided to target the top ul. This will effectively pull the top navigation out of the document flow. We give it a position of absolute and then place it down a bit from the top and over from the right far enough to leave room for our search area. That covers our major placement for this. The rest is aesthetics.

Note: I tend to copy code from previous projects I made. This saves time. But it has the disadvantage of having to remove unnecessary styles. You might see a few styles that are unnecessary here and there. Feel free to point them out in the comment section for some *kudos*.


#top {
 position: relative;
 display: block;
 width: 960px;
}
#top ul {
 position: absolute;
 top: 8px;
 right: 210px;
 margin-top: 2px;
 float: right;
}
#top ul li {
 color:#120900;
 display:inline;
 font-size: 12px;
}
#top_nav a {
 color:#120900;
 margin: 0 6px 0 0;
 padding: 0;
 font-size: 12px;
 text-align: right;
}
#top_nav a:hover {
 text-decoration: underline;
}

Search CSS

We place our Search with a position of absolute, which removes it from the document flow as well. We give it a specific width so our search button shows up correctly. And we continue to use floats to get our elements to align correctly. Again, some aesthetics in the code below as well.

#search {
 background: url(../images/bg/bg_search.png) 
no-repeat 0 0;
 position: absolute;
 top: 8px;
 right: 0;
 width: 202px;
 display: inline;
 clear: none;
 z-index: 100;
}
#search .form-item input {
  background-color:#f2f6f9;
  border:1px solid #003e57;
  float:left;
  height:16px;
  margin:2px 5px 0 0;
  width:170px;
}
#edit-search-theme-form-keys {
 height: 14px;
 display: block;
 float: left;
}

Targeting Internet Explorer and Testing in Internet Explorer

Internet Explorer will almost always need some special styling to get your standards based design to look right. Conditional comments is one method of targeting styles for Internet Explorer browsers. Here is a good link about conditional comments on Quirksmode: Conditional Comments.

Conditional Comments

Place the following code just before the end of the head of your index.html file:

<!--[if IE 7]>
<link href="ie/ie_7.css" rel="stylesheet" type="text/css" />

<![endif]-->
	
<!--[if IE 6]>
<link href="ie/ie_6.css" rel="stylesheet" type="text/css" />
<![endif]-->

You can see that this will link to a separate style sheet for IE7 and another one for IE6. Often you’ll need some additional special care for IE6 as IE7 does have a lot of standards based improvements.

The ie_7.css file only needs a small fix for the top unordered list placement:

#top ul {
 margin-top: 6px;
}

The ie_6.css file needs that same fix as well as some adjustment to the width of the search:

#search {
 width: 206px;
}
#top ul {
 margin-top: 6px;
}

With testing for Internet Explorer I use a Virtual Machine on my Mac. I haven’t found a Virtual Machine I’m happy with. I may break down and buy a PC at some point. I always start on the Mac and Test in Firefox predominately (and Safari also) and then jump over to Windows to test Firefox and IE on the PC towards the end of the coding process. I only test for Opera and other browsers when the client specifically requests it.

Conclusion

We covered a lot of ground in this tutorial. For those of you just getting started with standards based design check out the classic links provided in this tutorial and utilize the comments below to ask any questions you have. I’ll be happy to help and I know there are some experienced web designers following along with this series that can help out as well. Stay tuned for the next tutorial were we will be learning to build a Drupal theme.

Read the introduction – What’s Drupal and why?
Read Part 1 – Design it Illustrator
Read Part 2 – Slicing it Illustrator
Read Part 4 – Theming in Drupal
Read Part 5 -Drupal Admin

Discussion

We want to hear what you have to say. Do you agree? Do you have a better way to approach the topic? Let the community know by joining the discussion.