Blog Tags: 

9 things about CSS any web developer should know

9 things I didn't know about CSS that I should have known years ago but I only picked up from a couple of good CSS books.

Having dabbled in web development over the years, I've had a basic working knowledge of CSS for quite some time. In fact, I've been around long enough to remember what the web was like when we were all using font tags and transparent pixel tricks. Back when it wasn't unusual to come across a web site using the BLINK tag. Let me tell you it was ugly and it was a mess. (Now get off my lawn!).

As soon as browsers started supporting CSS I picked up just enough to save myself from committing the geek equivalent of a war crime, but I never got around to fully mastering CSS in all its glory. Advanced subjects such as floats and layout still seemed a bit mysterious. And every so often I would come across a bit of CSS code that made no sense yet rendered perfectly in every single browser I tested. Clearly my CSS skills were behind the times.

Then a few months back I started working on a few improvements to the TurnKey web site and decided it was time to get back to basics. So I bought a couple of books which were recommended by a friend:

If you need to pick just one I would say both were good but I think the definitive guide has an edge. It's better organized, more comprehensive, and a better reference. It also provides better "theory" that helps create a useful mental model of how things are supposed to work.

OK, now on to the list:

  1. Learn how to use FireBug to test CSS on the fly: in hindsight, the most important thing I learned while reading these books and experimenting wasn't directly related to CSS itself - it was how to efficiently use FireBug to test CSS code on the fly. Previously I would write my CSS in a file text editor and then tweak the values in FireBug's inspection mode. I found myself hitting reload a lot and there was always a lag between writing CSS and seeing its effect on the web page. I found non-trivial tweaks to the CSS were much easier to write/experiment with in FireBug's "edit" mode, which just lets you mess around with the CSS in a simple editor and immediately applies those changes to the currently displayed browser window. In this mode you have to watch out not to hit reload or you will loose your CSS edits. After things are done, you can copy the result to a permanent file containing the stylesheet.

  2. Modern browsers (gasp) follow the rules: with regards to CSS itself the main thing I learned is that there are precise, non-browser specific rules governing web site presentation and lay out. Those of us who learned the ropes in earlier times when older browsers such as IE6 ruled have this misconception that browsers may interpret your CSS unpredictably. Modern browsers can be relied on to lay out your web site according to a rigorously defined, standard box model with rules that aren't so difficult to understand.

    What this means is that nearly all of the things I tried in Firefox 3.5 looked pretty much the same in IE7 and IE8. Down to the pixel level. And you may need that sort of pixel level control to implement visual effects such as rounded corners.

  3. Use the background Luke: the visual workhorse in CSS is the background family of properties:

    background-color # `transparent' is a color
    background-repeat # repeat-x repeat-y no-repeat
    background-image
    background-position
    

    "background" is a convenient short hand when you don't want to define background properties separately:

    background: <background-color> <background-image> <background-position>
    
    

    The primary limitation with the background property is that an element can only have one background. In some cases when that isn't enough you'll see designers inserting empty <div> hooks which are precisely positioned to create the illusion that a graphical element has multiple background (e.g., the round corners of fluid / variable-width element)

  4. Advanced selectors: CSS allows you more flexibility in selection than just the "standard" ancestor / descendant relationship:

    body h1 {
        # this matches any h1 element inside any other element inside
        # the body
    }
    

    You can also select direct children:

    body > h1 {
        # only h1 that is the direct child of body will match
    }
    

    Siblings:

    h1 + h2 {
        # only h2 that comes immediately after h1 will match
    }
    

    The first child of an element:

    ul li:first-child {
        # only matches the first li item
    }
    

    Global selector:

    * {
        # matches any element
    }
    
    *.myclass {
        # the better known .myclass is just shorthand
    }
    
    *#myid {
        # the better known #myid is just shorthand
    }
    

    Attribute selectors:

    img[title]
        select only img tags with "title" attribute
    
    input[type="text"]
        input fields of type text
    
    a[href][title]
        select a that has both href and title attrs
    
    *[title]
        any element that has title attribute
    
    img[title~="Figure"]
        any img with title that contains Figure in it
            regexp match?
    
    img[title^="bar"]
        any img with title that starts with "bar"
    
    img[title$="bar"]
        any img with title that ends with "bar"
    
    img[title*="bar"]
        any img with title that contains substring "bar"
    
  5. Things to remember about absolutely positioning elements

    • They are taken completely out of the presentation flow. No space is made on the page for that element.

    • They are positioned relative to the nearest absolutely or relatively positioned ancestor element (or otherwise the body).

      In other words, if you want to position element A relative to element B, you can put element A inside element B and define B as relatively positioned. You don't have to actually define an offset for the relative position of B.

  6. Margins collapse: margins are not just padding that goes beyond an element's borders. Margins collapse so that if the margins of two elements touch the smaller margin will collapse. They won't be accumulated!

    In other words if M1 > M2, M1 + M2 = M1

  7. Any element can be turned into an inline or block element:

    display: inline|block
    

    Block elements and inline are elements are different in that blocks will insert a break and expand to the available in their parent box UNLESS THEY ARE FLOATED. By contrast, inline elements are happy to live side-by-side with other inline elements.

  8. The rules for floating is precisely defined by the standards. That's important because you should be able to rely on them down to the pixel to figure out in advance if an element will be floated along side an existing element or below it.

    You can forget about older broken browsers such as IE6 where you would sometimes get a broken result.

    The precise rules are a bit complex, but you don't really need to know them unless you need pixel perfect perfection.

    A few tips to help you get by:

    • Floated elements are rectangle block boxes who's border dimensions are calculated to exactly fit their contents + padding + border. In other words, a float is as small as it has to be.

    • Floats can float up and right but never up. So they'll never show up higher in the page than where they are inserted.

    • In Firefox (tested up to 3.5) a parent element that contains floated elements doesn't expand to contain its floated children unless it's either also floated or has the "overflow: hidden" property.

      This confused me a bit as I didn't expect floated elements to spill out of the bottom of the containing element.

  9. Relative/absolute positioning is also rigorously defined. Once you know the rules you should be able to get predictable results. If you experiment in a modern browser you can expect the result to look the same in other modern browsers.

Coming up next week: my CSS cheat sheet.

Add new comment