Bloggers blog

Yes, I know that when you have a weblog the idea is that you'll not only post to it but also make sure that you finish designing it. I'm also aware that I've been a bit lax in these areas, but that's just me - when left to my own devices I tend to leave until tomorrow rather than do today, with pretty much everything imaginable. Maybe I'm just lazy? Probably, but I have been a bit busy too - besides moving house and holding down a full time job, I've been involved in a couple of projects with Sarah and Paul, along with some client work for Sarah's company. So, as you can see, I haven't been totally bone-idle this time around :)

Bookmark this:
  • del.icio.us
  • Ma.gnolia
  • blogmarks
  • Simpy
  • Spurl
  • StumbleUpon
  • Technorati
Up arrow

Introduction to the CSS Box Model - part two

Internet Explorer and its Broken Boxes

In part one we looked at the CSS box model, how it works, and how we can manipulate it to achieve our design aims. In this article we need to look at what can go wrong when, despite its simplicity, a browser doesn't know how to use the model correctly, and how we can compensate for it.

To summarise the main problem with the box model - Internet Explorer versions 5.01 and 5.5 both use a broken box model; that is they don't use the box model that will produce the neat, precisely dimensioned, boxes that we looked at in article one. Instead of defining the width setting as belonging to the box contents IE 5x was built to use width for setting the overall boundaries for the content area, plus the padding area, and the border. Considering that the CSS specifications are quite clear on how this setting should work it's quite remarkable that the engineers responsible for the Windows implementations of IE 5x would make this error - but they aren't alone. Not only does IE 5x for Windows use the broken box model but, unless you are careful and prevent it from doing so, IE 6 can, and very often does, use the same model as its predecessors.

To be fair to Microsoft the model used for IE 5x is quite a logical one. If we remember our previous explanation for the box model and how we compared a CSS box to a cardboard one we can begin to see how easy it would be to assume that the IE 5x way is the right way. If we were to look at a cardboard box and ask someone to tell us how wide it was they'd measure the external width of the box, from one outer border edge to the other. They wouldn't open it up and measure the free inner space. IE 5x was engineered to do just that - but it's very wrong to do so, not just because it's against the specifications but also because it removes a degree of control over how we are able to manipulate our boxes. A loss of control is usually a bad thing, and it is here too. All that wouldn't be so bad, though, if all of the other browsers decided to follow that lead, at least there would be consistency of implementation. That, however, would require dozens of software groups to reproduce an error made by one of their competitors rather than taking their guidance from the standards body that created the box model specification in the first place - fortunately, for the future of standards, they didn't.

So, what's the real problem with this box model?

That's quite an easy question to answer - take a look at any web page on any site, it has a width that is constrained by the width of the available viewing space (the viewport), which is itself limited by the size of your monitor and monitor resolution. Due to this constraint we have clearly defined boundaries for our design area. If we overflow from these then part of our page spills over and off the page - this most often leads to the need for horizontal scrolling, but in some circumstances it can mean that the overflowing section is completely inaccessible to the viewer. I'm confident that you will agree that that's a bad thing, so we need to make sure that doesn't happen to us. The most common resolutions used are 800px wide by 600px high, and 1024px wide by 768px high, with 80-95% of all internet users having one or the other in an almost equal distribution. This means that we need to set ourselves a page limit of 800px wide if we hope to ensure that as many users as possible can see our page without the need to scroll, and without the need to overly limit our available design space. While many designers opt for this fixed-width page limit some choose to have a flexible/liquid width design that can stretch to fill more space and others choose to accept the scrolling and design for users with a higher resolution. It's not for me to tell you which type of designer you should be, nor am I going to try to.

A more detailed look at IE 5x's broken boxes

Let's review one of the rule set examples given in article one:

  1. img {
  2. width: 210px;
  3. height: 150px;
  4. border: 1px solid black;
  5. padding: 0;
  6. margin: 5px;
  7. }

In the above rule set we defined the properties for an image and it's associated box. We gave it a width, a height, and set its padding, border and margin properties. Images, however, tend not to cause us too many problems, after all many of us omit the width and height settings from the style rule, allowing the image's inherent height and width properties to impose themselves on its containing boxes. In order to properly use the box model in a way that we are likely to see IE 5x break our boxes we need to use an element that doesn't have its own inherent dimension settings. To that end we'll use paragraphs as our rule set targets. Most of you will already know, but for those that don't - the HTML mark-up for a paragraph is <p> - and our selector is a p.

  1. p {
  2. width: 180px;
  3. height: 180px;
  4. border: 1px solid black;
  5. padding: 10px;
  6. margin: 10px;
  7. background: #328DAF;
  8. color: #000;
  9. }

Here I've created a very similar rule set for our p selector as the previous one for our image selector. This gives us a 180 pixel by 180 pixel square paragraph, with 10 pixels of padding surrounding it and a 1 pixel, solid black border around that. Surrounding the whole of this is a 10 pixel margin keeping other elements away from our bordered paragraph. I've also given it a background and text colour so that you can copy and paste the rule set into your own style sheet and exactly reproduce the following image using CSS.

Graphical depiction of the CSS box model applied to a paragraph of text

That image was made by applying the above rule set to a paragraph of text on a web page viewed in Mozilla 1.6 and then a screen shot pasted into a graphics editor. As you can see we have a nice neat 180 pixel square block of text with, as specified in the CSS specifications, a 10 pixel padding space around it, and then our single pixel black border and our margin.

If we look at the same paragraph in IE 5.5 we can see the difference in how our dimension settings are used and abused:

Graphical depiction of IE5x's broken box model applied to a paragraph of text

We can clearly see the difference - the IE 5.5 version is narrower than the Mozilla version. In fact it's exactly 22 pixels narrower - the sum of the left and right padding, and the left and right border dimensions. You'll also notice that the height of the box has stretched, but that's another IE bug and one that we won't discuss here.

The combined width of our content width, padding and borders totals 202 pixels, and if we measure from the left border to the right of the Mozilla rendered version that's just what we have and is in line with the CSS 1 specifications. However if we were to take the same measurement using our IE 5.5 rendered version that width would be 180 pixels, equivalent to the width setting given in the rule set. However, as we've already discovered width in CSS terms equals content width, and not border to border width. So IE 5.5 is very wrong in it's implementation, and when we design our pages to fit in a set space we need to know that all browsers are going to show that same space as being filled by our beautiful design and content.

So how do we manage to use the box model in IE 5x?

Fortunately for designers all over the world a number of methods to fix IE 5's broken boxes have been devised. Most of these being thought up by Tantek Celic who was also the head of the Microsoft team that produced the Tasman rendering agent found in the version of Internet Explorer 5 that Microsoft produced for the Macintosh - it also happened to be the first browser to offer full CSS level 1 support, something that no version of Internet Explorer for Windows has achieved yet, including IE 6. The most widely known box model fix available is the Tantek Hack, or Box Model Hack. We'll review that later in the article, along with several of Tantek's more recent fix discoveries. First, though, we'll have a look at several simpler fixes and discuss the pros and cons of their use before moving on to the more effective solutions devised by Tantek.

Fix 1: Avoid setting widths, or borders and padding

The problem with IE5's box model is that it misinterprets width settings. If we didn't set a width we could avoid the issue altogether. It's sometimes possible to do this, as mentioned previously in regards to images. Occasionally we can also get away with it when using boxes for other purposes. If you can, then do - it'll allow for cleaner more semantic mark-up (cf. fix 2) and cleaner CSS rules. If it's not possible to avoid using a width setting, it may be possible to avoid using borders and padding. Before creating the rule set for an element think - does it need a border? If not then don't use one, and don't use any padding; if padding is required you can always simulate it using the margin setting (remember, margins aren't affected by the broken box model, only borders, padding and widths). If both a width and border are required then this fix won't work for you, but one of the others may do.

Fix 2: Use nesting

Most designers are familiar with nesting elements, it's been in practice since the first days of using tables for laying out page designs, and it's still in use today both with tables and CSS. The difference with doing it with CSS is that it doesn't bloat a web page nearly as much. Whichever way you go it'll always be necessary to use some nesting of elements - for example a paragraph set within a container, or a series of link sets within a navigation bar. Nesting is essential to modern page design, and it can help us out with IE 5's broken box model too. Consider the following XHTML mark-up and CSS rule sets:

  1. The CSS
    1. #outer {
    2. width: 202px;
    3. margin: 10px;
    4. }
    5. p {
    6. border: 1px solid black;
    7. padding: 10px;
    8. background: #427C1B;
    9. color: #000;
    10. }
  2. The XHTML
    1. <div id="outer">
    2. <p>Some Content</p>
    3. </div>

Here I've split the box settings up into 2 separate rule sets and applied the rule sets to a div and a paragraph, then nested the paragraph within the div. As you can see the "outer" div has the width and margin settings applied to it, while the inner paragraph has the borders and padding but no width setting - it doesn't need it as it will stretch to fill the box created by the div that surrounds it. You'll also need to note that we've had to use a width of 202px, rather than 180px, so that when the inner paragraph stretches to fill the outer div the combined width of content, borders and padding comes to 202px, leaving a content width of 180px. It produces the following results in Mozilla and IE 5.5 respectively:

Graphical depiction of fix 2 as displayed in the Mozilla browser
Graphical depiction of fix 2 as displayed in Internet Explorer version 5.5

As you can see the widths of the boxes are the same - we've overcome the broken box model with a very simple workaround. There are issues with this method, however, at least if you're concerned about using clean, semantic XHTML mark-up. The issue being that it isn't clean, at least not as clean as it would be if we didn't have to overcome poor browser implementations of standards by dropping our own a level. That aside, I still use this method to a limited extent on pages that I create, for elements such as header bars where the need for further nesting of elements is limited. I limit the use simply because applying the method to all boxes on my web pages could potentially double the amount of mark-up used, in some cases more so, and doing this totally defeats the object of leaving tables behind and using CSS and XHTML for laying out a web page design. So, it's a useable workaround in some circumstances, but what about other circumstances where the nesting could lead to excessively bloated mark-up? See fixes 3 to 5 for that answer:

Fix 3: The Box Model Hack

As mentioned earlier, the Box Model Hack was devised by Tantek Celic, an expert in CSS, creator of the rendering engine in IE5/mac and a contributor to the CSS level 2, 2.1 and 3 specifications. Considering his obvious interest in CSS it's no surprise that this fix relies solely upon CSS to be achieved. You may want to pause for a breath at this point, as it's going to get interesting :)

With his in-depth knowledge of CSS and the way browsers work, notably those produced by his employers, Tantek was able to see a use for, and find, other bugs in IE 5's CSS capabilities, and turn this to our advantage. He noted that Internet Explorer 5 for windows had a number of CSS parsing bugs which were able to confuse it and cause it to stop reading a rule set at a certain point. Compare our earlier rule set with our Tantek hack version, both included below (minus the height setting):

  1. Our original rule set
    1. p {
    2. width: 180px;
    3. border: 1px solid black;
    4. padding: 10px;
    5. margin: 10px;
    6. background: #328DAF;
    7. color: #000;
    8. }
  2. Our Tantek Hack rule set
    1. p {
    2. width: 202px;
    3. border: 1px solid black;
    4. padding: 10px;
    5. margin: 10px;
    6. background: #328DAF;
    7. color: #000;
    8. voice-family: "\"}\"";
    9. voice-family:inherit;
    10. width: 180px;
    11. }

Remember earlier when I mentioned that our border to border dimensions should total 202px? Well we use that knowledge here in creating two separate width settings - the first one (202px) is for IE 5x, the second is our real one of 180px for browsers that get the box model right. The way it works is that IE5 reads the rule set, sees that it needs to set a width of 202px, does so then takes the border and padding dimensions off that width to leave a content width of 180px. IE 5 then stops reading the rule set at the point of the added hack. Luckily most of the modern browsers that get the box model right don't have that same parsing bug and are able to continue to read the rule set until they get to the second width setting - which then overrides the first one to set a 180px wide content section as it would do in the original rule set. There are one or two issues with using this hack though. One is that using it means that you are using aural CSS style rules, so you can't validly set a non-aural media type for your style sheet. If you do set one then your CSS will be flagged as not being totally valid by the W3C CSS Validator when using it to validate your HTML page. It'll validate your style sheet in isolation as the media type is set within the HTML page and not the style sheet. To get around this you have to make your web page less accessible by omitting the media type attribute from the link to your style sheet.

There's another problem - not all browsers that can do the box model right can get past the hack. Some versions of the Opera web browser have the same parsing bug as IE 5 does, and so we are left needing another fix - fortunately it's a simple one. IE 5 doesn't recognise CSS 2 level selectors, not surprising as it gets a fair bit of CSS level 1 wrong too, and so this can be exploited by using a CSS 2 selector to reapply the correct width setting for Opera. We use a child selector to add in this rule set - note: this must immediately follow the Tantek Hack rule set, if you put it anywhere before it then it will be overridden by the 202px width setting that would then follow. There's a second factor for putting it immediately after, and not following any other rule sets - when using the Tantek Hack IE 5 will fail to apply any styles to the target element unless it is immediately followed by what it considers to be a nonsense rule set, it's inability to recognise CSS 2 level selectors makes the following just that: html>body p { width: 180px; }

We now need to combine both parts so that we can see it how it needs to appear in our style sheet:

  1. p {
  2. width: 202px;
  3. border: 1px solid black;
  4. padding: 10px;
  5. margin: 10px;
  6. background: #FF6600;
  7. color: #000;
  8. voice-family: "\"}\"";
  9. voice-family:inherit;
  10. width: 180px;
  11. }
  12. html>body p { width: 180px; }

With another colour change this gives the following results in Mozilla and IE 5 respectively:

Graphical depiction of fix 3 as displayed in Mozilla
Graphical depiction of fix 3 as displayed in Internet Explorer version 5.5

Another success! It's not all glory though - there's still the issue of the media type selection, sometimes we just have to specify one, but using this hack we can't. It can also add quite a lot to the size of our style sheets when used to correct the box settings for a lot of elements. So what can we do? See fixes 4 and 5, once again courtesy of Tantek Celic.

Fix 4: The Inline High Pass Filter

This is a more complicated fix that, once again, capitalises on parsing bugs within IE 5x. It's intended for use with an embedded style sheet (within the head of a HTML page) and works by stopping IE 5 from being able to read any rule sets that follow it - giving us the chance to override rule sets that we've set specifically for IE 5. Remember earlier when I said that IE 5 can't parse escaped CSS code? Well this fix uses that in conjunction with a nonsense rule applied to an i (italic) selector in order to achieve the effect we need. As we shouldn't be, and hopefully aren't, using the presentational italic (i) in our mark-up it's safe to apply the nonsense rule to it:

  1. <style type="text/css">
  2. p {
  3. width: 202px;
  4. border: 1px solid black;
  5. padding: 10px;
  6. margin: 10px;
  7. background: #FF6600;
  8. color: #000;
  9. }
  10. i {
  11. content:"\"/*"
  12. }
  13. p {
  14. width: 180px
  15. }
  16. </style>

IE 5 is unable to do anything with the CSS level two property "content" which is only usable with the :before and :after pseudo selectors. So nothing happens when it's encountered. Then when it reaches the escaping \ it assumes that the value string has been completed, and then encounters the /* which it treats as the beginning of a CSS comment (CSS comments are contained within /* and */ symbols) and is confused into believing the remainder of the CSS is the contents of the comments and stops at that point. Browsers that support CSS level 1 aren't confused by that and so continue on to the next declaration, ignoring the nonsense property/value pair for the i selector. Another success - but using this method means using a page embedded style sheet, doing that means we lose a lot of the benefits of style sheets, notably the ability to have a central repository for all of a site's style rules, ones that can be applied with ease to hundreds or thousands of pages saving a lot of bandwidth expenditure and requiring only one file to be edited to achieve site-wide changes. They're important benefits to lose, so fix 5 is better.

Fix 5: The High Pass Filter

The high pass filter is essentially the same as the inline high pass filter, except we use external linked style sheets, rather than an embedded one. There are one or two minor differences, which need to be explained, as follows. Once again the methodology is seemingly complex when first encountered, but it's relatively simple in practice. Step one is to create a link within the head of our page mark-up to an external style sheet:

  1. <head>
  2. <title>High Pass Filter</title>
  3. <link rel="stylesheet" type="text/css" href="filter.css" />
  4. </head>

Step two involves creating the style sheet filter.css (though you can call it what you wish), the contents of which follow:

  1. @import "null?\"\{";
  2. @import "realstylesheet.css";

In the same way as the inline high pass filter works, the high pass filter uses escaping to confuse IE 5. IE 5 is tricked into trying to import a style sheet called null. Then the first escaping \ confuses it into believing that the instruction to import null has been completed, and then encounters the remainder of the string associated with the first @import instruction which appears as a nonsense declaration which it can't continue beyond. IE 5 then takes no further action and ignores the following @import. Browsers that lack IE 5's parsing problems are able to proceed and read the second @import rule, and in doing so import the real style sheet which will contain all the rule sets to lay out your web pages properly. In order to prevent problems with validating your style sheets or with IE5/mac a file called "null" (without a file extension) needs to be created, and to have contents - which just need to be a comment, for example /* null */. As a result of this fix no older browsers will get the real style sheet, which means they will be unstyled. The browsers which are able to cope with this fix include: IE5+/Mac, IE6+/Windows, Netscape 6+, Mozilla and Firebird, Opera 5+ and any other browser able to pass section 7.1 of the CSS1 test suite.

At this point you may be thinking that if you use this method then your pages will be unstyled in IE5 - and if you only use the high pass filter as above, then that will be the case. However it doesn't have to be. CSS places a priority on rule sets based on the order they appear - a style sheet will override equivalent rule sets contained in a previous one, including when linked in the page head. So, in order to have a nicely styled page in IE 5x using this method we have to go on and make another style sheet just for that browser and link to it before we link to our filter.css style sheet. Like so:

  1. <head>
  2. <title>High Pass Filter - IE 5 Friendly Version</title>
  3. <link rel="stylesheet" type="text/css" href="forie5.css" />
  4. <link rel="stylesheet" type="text/css" href="filter.css" />
  5. </head>

We then set our IE 5 version of the rule sets in the forie5.css style sheet, while placing our standards compliant rule sets within realstylesheet.css as mentioned above. Doing this with the following rule sets will achieve the results in the images below:

  1. The "forie5.css" style sheet
    1. p {
    2. width: 202px;
    3. border: 1px solid black;
    4. padding: 10px;
    5. margin: 10px;
    6. background: #CCC;
    7. color: #000;
    8. }
  2. The realstylesheet
    1. p {
    2. width: 180px;
    3. border: 1px solid black;
    4. padding: 10px;
    5. margin: 10px;
    6. background: #FFF;
    7. color: #000;
    8. }

Graphical depiction of fix 5 as displayed in Internet Explorer version 5.5
Graphical depiction of fix 5 as displayed in Internet Explorer version 5.5

We've now managed to correct the box model problem with IE 5x - however, as you will have noticed every fix has its own pros and cons, it's up to you to decide which is the best for you to use depending upon what you hope to achieve. To finish we need to recall a comment I made, about IE 6, very early on in the article - in some circumstances IE 6 will use the same broken box model as IE 5, but not all. In order to prevent IE 6 from becoming buggier than it inherently is you need to ensure that it renders your pages in standards compliant mode. To do this you need to ensure that you use a valid doctype declaration, including the link to the relevant document on the W3C site. If your pages use XHMTL then you may find yourself using the XML prologue - if you want IE 6 to render in standards compliant mode, don't use the prologue as IE 6 gets confused when it's there and so goes into quirks mode, and breaks the box model, also some versions of IE/mac may display a blank page.

Valid HTML and XHTML doctype declarations and an example XML prologue follow:

  1. HTML 4.01 doctype declarations
    1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
      "http://www.w3.org/TR/html4/strict.dtd">
    2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
      "http://www.w3.org/TR/html4/loose.dtd">
    3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
      "http://www.w3.org/TR/html4/frameset.dtd">
  2. XHTML 1.0 doctype declarations
    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
  3. The XHTML 1.1 doctype declaration
    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
      "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  4. An example XML declaration (prologue)
    1. <?xml version="1.0" encoding="ISO-8859-1"?>

References:

Bookmark this:
  • del.icio.us
  • Ma.gnolia
  • blogmarks
  • Simpy
  • Spurl
  • StumbleUpon
  • Technorati
Up arrow

Wordpress is cack

No doubt there's going to be a few out there that disagree with me on this is issue, but I have to say that wordpress is about as good as a mountain of doggydo on a wet and windy morning.

What the hell is the issue with it inserting line breaks and paragraph tags willy nilly? So far in a post, which I've just had to take back off the front of the blog, it has broken the display of code within code tags, deciding that it wants to insert empty paragraphs throughout the code and also to displace the location of the closing code tag, thus ensuring that the post breaks.

If that wasn't enough for the mountain of do, it also has taken to hiding any content that requires special characters to be displayed rather than treated as code, such as the character code for less-than. Not only that it likes to insert a line-break after its omission.

Here's hoping that someone out there knows a way to fix this before I waste any more time or just scrap it and try a different blog script.

Bookmark this:
  • del.icio.us
  • Ma.gnolia
  • blogmarks
  • Simpy
  • Spurl
  • StumbleUpon
  • Technorati
Up arrow

More accessible 'more' links

Visit most blogs, including those of accessibility minded web designers, and at some point you'll stumble upon a "more" link. These are links to the full version of excerpted posts which allow bloggers to reduce the volume of text on their home pages. In theory they're a great idea, in practice though they're poorly implemented from an accessibility standpoint. The WAI's guidelines state that link text should be meaningful enough to make sense when read out of context, clearly something that "more" fails to do. Also, as is mentioned in the WCAG recommended techniques for writing link text, if more than one link on a page shares the same link text, all those links should point to the same resource - once again, something that "more" generally fails to do.

The problem is, though, that these links and their associated link text are added by the blog software rather than the blogger, and the code running behind the scenes that makes this happen is very often a mystery to the average blogger. Considering the current trend for focusing on accessibility it may be worthwhile for blog software developers to modify this feature. In the case of wordpress, the software used on this site, it was quite easy to adapt the feature to use more appropriate link text than its version of "more" - thanks to a helping hand from Sarah who analysed the template functions files and found a way to achieve what I wanted - which was to have the "more" link include the article's title in the link text.

If this is something that you'd like to implement on your own wordpress blog you need to edit the template-functions-post.php file located in the wp-includes directory. To do so you need to locate line 86 and replace the existing code found there with the following:

  1. $output.='<a href="'. get_permalink().
  2. "#more-$id\">$more_link_text". get_the_title()."</a>";
Bookmark this:
  • del.icio.us
  • Ma.gnolia
  • blogmarks
  • Simpy
  • Spurl
  • StumbleUpon
  • Technorati
Up arrow

Introduction to the CSS Box Model - part one

All elements on a web page are contained within rectangular boxes with properties that we're able to manipulate directly via the use of CSS. This gives us precise control over their dimensions and, therefore, their impact upon their surroundings. We can set the size of the area used to contain the contents, via the width setting, the width of the borders around the box, the amount of space between the contents and the border, and the amount of space between the borders of one box and those of its neighbours. The precision that's possible to achieve with these settings gives designers a fine degree of control over the layout of the web pages they create.

So what are the settings, and how do we use them?

If we consider that a CSS box is no different to an ordinary cardboard box, with the exact same properties, then it'll be easier to both visualise and understand the settings we use. The cardboard part of a box is identical in properties to the border that surrounds a CSS box, it's the part that surrounds and contains the box's contents. Inside the box is the content area, which in some examples may take up the entire inner area of the box depending on how we pack it. However, sometimes we may want to protect the contents with padding to keep it away from the inner surface of the box. With a cardboard box this may be achieved by padding it with polystyrene, with a CSS box we pad it with empty space. Then, just as with a cardboard box, we may surround it with empty space to keep it away from other boxes - by using a margin. The combined effects of all four of these properties adds up to create the dimensions of a CSS box:

Graphical depiction of the CSS box model

Even the image above is a box that we can manipulate using the CSS box model. It has a width and a height that defines the content area, in this case the size of the image itself. It can be given a border to surround it, and it can have padding between the image and the border, and a margin to surround it all and provide space between it and all of the other objects on this web page. Which brings us to the magic of CSS - and how we manipulate these properties.

In case you aren't familiar with CSS I'll give a very brief rundown of some of the terminology and the syntax involved in creating a CSS style rule. Style rules consist of two principle parts - 1. an element identifier, the selector and 2. the style declaration. Selectors may be the name of the HTML element that is the target, or they may be names given by the designer and targeted via either a unique ID or a class. There are other types of selector, however for the purposes of our exercise we don't need to know anything more about them now. A declaration contains the style properties that are applied to the element targeted by the selector, and consist of two parts separated by a colon (:) and closed by a semi-colon (;) which is used to separate one style declaration from subsequent ones within the same rule set, and each rule set can contain one or more declarations that we contain within curly braces like these {}.

Now we know a little about how we write CSS we can begin to apply that knowledge to setting the dimensions of our image box. To demonstrate this I'll use 3 different examples to target images under different circumstances using the three methods of naming selectors mentioned above.

Example one, targeting all images on the page

If we use the element's name as the selector name, in this case img for image, then our style rules will be applied to every example of that element type on the page unless we subsequently override the rules we create here, or target individual examples more specifically. If you need to review the syntax described above before proceeding then please do so.

  1. img {
  2. width: 210px;
  3. height: 150px;
  4. border: 1px solid black;
  5. padding: 0;
  6. margin: 5px;
  7. }

The above code shows a simple example of a CSS rule set which contains all of the required components mentioned earlier. We begin with our "img" selector which will target all of our images. We then open the declaration block with an opening curly { before proceeding with our declarations. Although I've separated each declaration by placing them on their own lines it's not necessary to do so, but it's helpful when reviewing and editing our rule sets as they're easier to read. The first two declarations relate to the dimensions of the content area within our box, in this case the image dimensions, but it could just as easily have been the dimensions imposed upon a paragraph of text - the same method is used in all cases. We have our width and height properties on the left separated, by a colon, from the property values on the right, and we end the declaration with a semi-colon. So the first box property that we are manipulating is the width, and we're giving the width a value of 210 pixels - the addition of a unit is important with any numerical value greater than zero, in this case we used px to establish that our units are pixels. Property three sets the border around both the contents and padding, and you'll notice that we've given that property several values, these establish the width of the border, its colour and the line type. Later I'll give some examples of other property values that could have been set. We then have property four, the padding. In this example the padding has been set to zero, so that the border is in contact with the image, and you'll note that we haven't specified the unit of measurement - this is because a value of zero is zero regardless of the unit of measurement used, and so it's not necessary to include. Then we added our margin, with a setting of 5 pixels, before closing the rule set with the closing curly }. It's that simple - but it can get slightly more complex as we'll find out shortly.

Example two, targeting groups of images

There may be instances where we need to apply rules to some, but not all, images on a page. If we were to use the element name (img) as our selector name then it wouldn't be possible to do that, and so we have to create a rule set that targets our special class of images whose boxes we wish to manipulate differently to the rest. To do this we use a class. A class in CSS is a name, of our own choosing, that is identified as a class name by having a leading full stop (period), for example .specialimages. The creation of classes in this manner increases the power of CSS a great deal, giving us far more control over the elements on our web pages. Before proceeding review the previous example if you need to as the method of writing our rule set is the same, however we're going to look at how to increase the control over the box properties by manipulating them in an even more precise manner.

  1. .specialimages {
  2. width: 210px;
  3. height: 150px;
  4. border-top: 1px solid black;
  5. border-right: 5px dotted yellow;
  6. border-bottom: 2px dashed #CCCCCC;
  7. border-left: none;
  8. padding: 1px;
  9. margin: 5px;
  10. }

As you can see, this example is clearly more complicated than the previous one and as a result begins to show the follow of including white space by separating the declarations onto individual lines. You should also note that our rule set won't target any images unless we let it know that it needs to - we do this by adding the class name to the image tag within our HTML mark-up by including a class attribute in this format: class="specialimages". That goes within the opening <img> and, as you can see, doesn't include the leading full stop. Besides changing the selector from targeting a HTML element name to using a class we've also broken up the border into its four component sides and set the properties of each individually. Note the order that they appear in, I've specifically used that order in preparation for our final example so that you can familiarise yourself with the sequence. I've also demonstrated a couple of the other possible line types with the dotted and dashed settings on border-right and border-bottom respectively, along with a demonstration of another way of setting the colour, using the hexadecimal code #CCCCCC, and the syntax for setting no border, using none unlike the use of a zero for margins and padding, on border-left. In the final example we'll advance on some of the declarations further as well as demonstrate how to target an ID and discuss the significance of their use.

Example three, targeting a single image

In order to target a single image to the exclusion of all of the others, and also to override any general rules that may have been set via the img selector if necessary, we need to give it a unique ID. Doing so allows us to manipulate individual elements in isolation from other examples of the same element, this gives a tremendous amount of control and is particularly useful when used in conjunction with element positioning. As with the leading full stop present on class selectors IDs also have a special symbol which identifies them as an ID, the hash or pound symbol #. Once again review the previous example before proceeding.

  1. #extraspecialimage {
  2. width: 210px;
  3. height: 150px;
  4. border: 1px solid #000;
  5. padding: 1px;
  6. margin: 5px 2px 10px 3px;
  7. }

Although more advanced than the class example it's possible to make our rule sets less complicated by the use of shorthand on properties that allow it - which all of border, padding and margin allow. In this case I've used shorthand on the margin to condense the property values for each side into one declaration, whereas in the previous example I used multiple declarations for the different border sides. As mentioned in example two the order is of great importance and has a clockwise sequence reading from top to right, to bottom, to left. It's clearly a lot easier to do it that way than it is to create a separate declaration for each side - however separating the border sides into individual declarations is needed to also set the line type and colour, without which the border would be invisible even though it will take up space on the page. Still with the theme of using shorthand, I've also included a shorthand version of the hexadecimal code for black - shortening it from #000000 to #000, this works when the hexadecimal code can be divided into three groups of identical code pairs, for example #ff0033 can be shortened to #f03, but f0cd30 can't be shortened. To finish we need to know how to target our individual image containing box with the unique ID and, as with classes, this is done by including a reference to it within our opening image tag - this time in the form id="extraspecialimage", once again the leading character is dropped in the mark-up.

Hopefully you now have an understanding of what the box model is and how it works, which will hopefully be a better understanding than Internet Explorer versions 5.01 and 5.5 have. Both of these browsers fail to use the CSS box model correctly due to a misinterpretation of the W3C specifications of the CSS version 1 box model. We'll cover this, and how to fix it, in part two.

Bookmark this:
  • del.icio.us
  • Ma.gnolia
  • blogmarks
  • Simpy
  • Spurl
  • StumbleUpon
  • Technorati
Up arrow