nrkn

Image Slicing for fluid CSS designs

Building the basic layout

Our initial, basic layout will look something like this (preview has been scaled to 50%).

To get to this stage we will:

  1. Cut our image up into slices
  2. Save our slices
  3. Create our HTML page
  4. Mark up our layout using HTML and CSS

1. Cutting our image up into slices

The first thing that we will do is cut our images up into 9 slices. It is important that the top middle and bottom middle slices tile nicely horizontally, and that the left middle and right middle slices tile nicely vertically.

Top middle and bottom middle slices tiling horizontally:

Left middle and right middle slices tiling vertically:

^ Back to top


2. Saving our slices

We will save the 9 slices like this:

  1. mainTL.png
  2. mainT.png
  3. mainTR.png
  4. mainL.png
  5. mainC.png
  6. mainR.png
  7. mainBL.png
  8. mainB.png
  9. mainBR.png

This naming is based on the location of the slice, TL = top left, T = top (top middle), TR = top right etc. C is center, the central slice.

^ Back to top


3. Creating our HTML page

Now we want to create a new HTML page and save it as index.html:

            
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Basic Fluid CSS Layout</title>
    <script type="text/javascript"></script>
    <style type="text/css">
* {
  margin: 0;
  padding: 0;
}

body {
  font-family: sans-serif;
  font-size: 100%;
}
    </style>
  </head>
  <body>
  </body>
</html>
            
          

I am using an HTML 4.01 Strict doctype as using XHTML is unnecessary and would just complicate things; see "No to XHTML" by Spartanicus for more information.

We have an empty JavaScript element to prevent the Internet Explorer flash of unstyled content bug.

We set the margin and padding for * (everything) to zero in CSS to remove any inconsistencies between different browsers. We will explicity state margin and padding on any elements that need them.

Finally, we set the font-family to sans-serif and the font-size to 100%.

View our page so far. Note that the page will appear blank as it doesn't currently have anything in it, use your browsers "View Source" or equivalent to see the HTML and CSS.

^ Back to top


4. Marking our layout up as HTML and CSS

To get the desired effect, we use a technique similar to A List Apart's CSS Sliding Doors.

This works by nesting elements (in our case div elements) and giving each a different background. The illustration shows this in action for the top slices of our layout, in an exploded perspective view to help you see how it works.

Here is the HTML for the three div elements that make up the top part of our layout, color coded to help you see how they relate to the illustration:

                      
<div class="mainT"><div class="mainTR"><div class="mainTL"></div></div></div>
            
          

Here is the CSS that applies the background images to the div elements and sets the correct height, again, color-coded to match the illustration:

            
.mainT {
  background: url( mainT.png );
}

.mainTR {
  background: url( mainTR.png ) no-repeat right;
}

.mainTL {
  background: url( mainTL.png ) no-repeat left;
  height: 220px;
}
            
          

Notice that we only need to set the height on the innermost div (.mainTL) and that we don't set width at all. Not setting width means that the div elements get their default width of auto, which means fill the available horizontal space. If you wanted to make a fixed width site you could set the outermost div (.mainT) to have a width of say, 760px.

The HTML for the middle row of our layout is similar, except we have put some test content in as well:

                      
<div class="mainC"><div class="mainR"><div class="mainL">
  <div id="content">
    <p>
      A paragraph of text.
    </p>  
  </div> 
</div></div></div>
            
          

The CSS differs in the way it repeats. repeat-y tells the browser to only tile the background image vertically:

                      
.mainC {
  background: url( mainC.png );
}

.mainR {
  background: url( mainR.png ) repeat-y right;
}

.mainL {
  background: url( mainL.png ) repeat-y left;
}
            
          

Notice that we haven't set a height this time. That's because the content inside the innermost div (.mainL) will determine the height.

Now we add some CSS for the content, to keep it inside the bounds of our layout:

            
#content {
  margin-left: 70px;
  margin-right: 70px;
  padding-left: 1em;
  padding-right: 1em;
}            
            
          

We add some HTML for the bottom row, which is exactly the same as the HTML for the top row except for the class names of the div elements:

                      
<div class="mainB"><div class="mainBR"><div class="mainBL"></div></div></div>
            
          

Finally, we add the CSS for the bottom row, again, exactly the same as the CSS for the top row except for class names:

            
.mainB {
  background: url( mainB.png );
}

.mainBR {
  background: url( mainBR.png ) no-repeat right;
}

.mainBL {
  background: url( mainBL.png ) no-repeat left;
  height: 220px;
}
            
          

Our HTML and CSS is shown below, or you can view the page so far, or you can download a zip file containing all of the files that make up the basic layout (ZIP, 53KB).

            
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Basic Fluid CSS Layout</title>
    <script type="text/javascript"></script>
    <style type="text/css">
* {
  margin: 0;
  padding: 0;
}

body {
  font-family: sans-serif;
  font-size: 100%;
}
    
.mainT {
  background: url( mainT.png );
}

.mainTR {
  background: url( mainTR.png ) no-repeat right;
}

.mainTL {
  background: url( mainTL.png ) no-repeat left;
  height: 220px;
}

.mainC {
  background: url( mainC.png );
}

.mainR {
  background: url( mainR.png ) repeat-y right;
}

.mainL {
  background: url( mainL.png ) repeat-y left;
}

#content {
  margin-left: 70px;
  margin-right: 70px;
  padding-left: 1em;
  padding-right: 1em;
}
    
.mainB {
  background: url( mainB.png );
}

.mainBR {
  background: url( mainBR.png ) no-repeat right;
}

.mainBL {
  background: url( mainBL.png ) no-repeat left;
  height: 220px;
}
    </style>
  </head>
  <body>
    <div class="mainT"><div class="mainTR"><div class="mainTL"></div></div></div>
    <div class="mainC"><div class="mainR"><div class="mainL">
      <div id="content">
        <p>
          A paragraph of text.
        </p>  
      </div>  
    </div></div></div>
    <div class="mainB"><div class="mainBR"><div class="mainBL"></div></div></div>
  </body>
</html>
            
          

^ Back to top