7/10/2012

CSS

To motivate Cascading Style Sheets (CSS), let's take John Doe's home page from the latest post of my web development overview and add some style.

Say, we want to have two centered boxes side-by-side, each of them having a width of 480 pixels and equal height. They shall have a light gray background, a 10 pixel padding with rounded corners and a gap of 20 pixels. The left one will hold John's profile, while the right one will be used later on and remains just empty right now. Additionally, every second level headline shall be red. Now, good ol' HTML:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title>John Doe</title>
  </head>
  <body>
    <center>
      <table cellspacing="0" cellpadding="0" border="0">
        <tr>
          <td width="10" height="10">
            <img src="corner_top_left.png" alt="corner_top_left">
          </td>
          <td bgcolor="lightgray" width="480" height="10"></td>
          <td width="10" height="10">
            <img src="corner_top_right.png" alt="corner_top_right">
          </td>
          <td width="20" height="10"></td>
          <td width="10" height="10">
            <img src="corner_top_left.png" alt="corner_top_left">
          </td>
          <td bgcolor="lightgray" width="480" height="10"></td>
          <td width="10" height="10">
            <img src="corner_top_right.png" alt="corner_top_right">
          </td>
        </tr>
        <tr>
          <td bgcolor="lightgray" width="10" height="750"></td>
          <td bgcolor="lightgray" width="480" height="750">
            <h1>John Doe</h1>
            <img src="doe.jpg" alt="John Doe">
            <h2><font color="red">Hobbies</font></h2>
            <ul>
              <li><a href="http://en.wikipedia.org/wiki/Fishing">Fishing</a></li>
              <li>Cars</li>
            </ul>
            <h2><font color="red">Employer</font></h2>
            <a href="http://www.defense.gov/">United States Department of Defense</a>
            <h2><font color="red">Bio</font></h2>
            <p>Hi, my name's John Doe. I'm working for DOD, the world's biggest employer.</p>
          </td>
          <td bgcolor="lightgray" width="10" height="750"></td>
          <td width="20" height="750"></td>
          <td bgcolor="lightgray" width="10" height="750"></td>
          <td bgcolor="lightgray" width="480" height="750">
            
          </td>
          <td bgcolor="lightgray" width="10" height="750"></td>
        </tr>
        <tr>
          <td width="10" height="10">
            <img src="corner_bottom_left.png" alt="corner_bottom_left">
          </td>
          <td bgcolor="lightgray" width="480" height="10"></td>
          <td width="10" height="10">
            <img src="corner_bottom_right.png" alt="corner_bottom_right">
          </td>
          <td width="20" height="10"></td>
          <td width="10" height="10">
            <img src="corner_bottom_left.png" alt="corner_bottom_left">
          </td>
          <td bgcolor="lightgray" width="480" height="10"></td>
          <td width="10" height="10">
            <img src="corner_bottom_right.png" alt="corner_bottom_right">
          </td>
        </tr>
      </table>
    </center>
  </body>
</html>

This is what's called a table layout and common practice from the HTML 3.2 era. If you see anyone still producing documents like this (but me), just hit him in the face. The problems with this approach are quite obvious.

A quick explanation what's happening: Everything's wrapped in a <center> tag, taking care of the centering. Within it, there's a table defining a grid for the content. The <table> tag's attributes disable spacing and borders, so the default table styles do not apply; otherwise the background would have gaps. In the table, there are three rows (<tr>), defining the 10 pixel top padding, the content and the 10 pixel bottom padding.

Every row holds seven table cells (<td>). In case of the top and bottom rows, these are: left corner, padding and right corner of the left box, the 20 pixel gap and left corner, padding and right corner of the right box. The middle row holds: left padding, content and right padding for the left box, gap and left padding, content and right padding for the right box.

The corner cells hold an <img> tag including a rounded corner image. You can generate a set at RoundedCornr, if you want to test it. Other cells get a "lightgray" background color. The headlines are dyed by wrapping their content in <font color="red"> at every position necessary.


CSS to the rescue. CSS level 1 has been published December 1996, level 2 in 1998. The latest version, 2.1 needed some time until finally being approved in 2011, but many of its features had long been implemented into various browsers. So, let's rewrite the document for use with a style sheet. Since we do not need deprecated elements (center, font) and attributes (width, height, bgcolor, color) anymore, I'll proceed to HTML5.

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <title>John Doe</title>
  </head>
  <body>
    <div>
      <h1>John Doe</h1>
      <img src="doe.jpg" alt="John Doe">
      <h2>Hobbies</h2>
      <ul>
        <li><a href="http://en.wikipedia.org/wiki/Fishing">Fishing</a></li>
        <li>Cars</li>
      </ul>
      <h2>Employer</h2>
      <a href="http://www.defense.gov/">United States Department of Defense</a>
      <h2>Bio</h2>
      <p>Hi, my name's John Doe. I'm working for DOD, the world's biggest employer.</p>
    </div>
    <div>
      
    </div>
  </body>
</html>

OK, that's much better. What's new? Just a <link> tag in the <head> section, including a file called style.css and supposedly of type text/css as style sheet, and a surrounding <div> element for John's profile and another yet empty division. Everything else is going to happen within the style.css file. If you want, create a new empty file and paste the following CSS code. Save and reload the page when done.

body {
  margin: 8px auto;
  width: 1020px;
}

h2 {
  color: red;
}

div {
  width: 480px;
  height: 750px;
  padding: 10px;
  border-radius: 10px;
  background: lightgray;
  float: left;
  margin-right: 20px;
}

div:last-of-type {
  margin-right: 0;
}

This CSS code defines rules for four so called selectors. Three of them are simple tag names and define styles for every element with this respective name. div:last-of-type gives some rules for the very last div element.

The two-value margin attribute for the <body> tag defines an 8px top and bottom margin and auto-magic left and right margins, effectively centering the body. Instead of the whole browser window, the body tag is defined to have a width of 1020 pixels.

Both <div> elements get the chosen dimensions, the designated padding of 10 pixels, a border radius of 10 pixels (yes, no more images here) and a lightgray background. They are floated to the left, so they can be side-by-side. Otherwise, they would be positioned below each other (Note: there's another technique for this based on display: inline-block. Both have their pros and cons). Finally, they get a right margin of 20 pixels to form the desired gap. The last div gets no right margin. This rule precedes the other margin-right attribute, since the selector div:last-of-type is more specific (and if it wasn't, it would still be more important, since it's defined later).

So, to sum it up: The use of style sheets separates content and semantics from presentation, easing maintenance and development and giving additional flexibility. E. g. one can think of a website providing different layouts by simply using different style sheets.

To say the least, the border-radius attribute is from the CSS backgrounds and borders recommendation published this April and the :last-of-type pseudo-class is from the selectors level 3 recommendation published last September. Both are part of the modular CSS level 3 standardization process. They should be available in any recent browser released within the last two years, but front-end development always means researching the compatibility of features, trying, heavily testing, failing, searching for solutions and workarounds and starting over again. I'll address browser compatibility issues in the browser section and give some testing and debugging advice when we come to tools.

CSS is in no way bound to HTML. E. g. it's used for plain XML files, too. We'll have a look at XML and XSL in the next post.

No comments:

Post a Comment