Lynda.com CSS Positioning Best Practices course reviewed

What do you have in CSS, Lynda? Nothing much, n'est-ce-pas? Apart from Adobe stuff and other stuff that's just too plain old...

About a month ago, I needed CSS material to get my CSS juices flowing again, ideally in screencasts form. I ordered the book and DVD bundle Handcrafted CSS by Dan Cederholm and Ethan Marcotte. I received the book and DVD two weeks ago but haven't really started on that yet. At about the same time, I also decided to do the Lynda.com CSS Positioning Best Practices course. The “best practices” bit was alluring, and positioning is what's hard in CSS, so... I added each chapter of it (the course) to my ActionMethod, and promised myself to hit the finish line. So I did. Here's the post-mortem of my generally unpleasant experience.

What do you have in CSS Lynda

Didn't learn much anything

My overall impression: the positioning explanations were okay. As I was going through the screencasts, I was constantly investigating it all, trying my hand at harder things. For example, what if the nearest positioned ancestor of an absolutely-positioned element has padding and a border, what will the latter rest again? Other example: I tested the ins and outs of using percentage and pixels for background-image positioning. I've always had a little trouble with that. What else? The negative margin applied to the current tab — I liked that. What I didn't like: too many unnecessary wrapper divs. Why wrap your navigation ul in a div, when you can position that ul just as easily...? There wasn't enough lists used for menus. A regular paragraph was always used for the following common menu “pattern”:

Horizontal Menu Pattern

Bill Weinman sounds a bit depressed. But a tad bit depressed is much better than overly cheerful. He's a good teacher.

Levels of stylesheets

Bill Weinman says in the chapter titled Understanding levels of style sheets that:

“There are 3 major levels of stylesheets in CSS, and one is applied first, and then another, and then another.”

According to him, these major levels are:

According to him, styles defined in style tags will always override those defined in external stylehseets.

That's wrong.

Styles defined in style tags are on the same exact “level” as styles defined in external stylesheets.

Bill Weinman goes on to show that a rule put in a style tag overrides another rule placed in his external stylesheet, but the cause of this has nothing to do with “levels of stylesheets”. The real cause is the source order in which these rules are declared. When two CSS rules have the same specificity and belong to the same level as they do here, the rule declared last is applied. Weinman only needed to swap his link and style tags to view his paragraph in the color specified in his .css file.

His code is:

<head>
  <title>CSS Examples: Style Sheet Levels</title>
  <!-- In external.css we have p.intro { color: black;	} -->
  <link rel="stylesheet" type="text/css" href="external.css" />
  <!-- AFTER so text will be blue -->
  <style type="text/css" media="screen">
    p.intro {
      color:blue;
  }
  </style>
</head>

Blue text.

That's confirmed in Firebug.

If he had swapped link and style tags, the rule in the CSS file would have “overridden” the one in the style tag:

<head>
  <title>CSS Examples: Style Sheet Levels</title>
  <!-- BEFORE -->
  <style type="text/css" media="screen">
    /* same specificity as in stylesheet */
    p.intro {
      color:blue;
    }
  </style>
  <!-- In external.css we have p.intro { color: black;	} -->
  <!-- This comes after so it's applied, text will be black. -->
  <link rel="stylesheet" type="text/css" href="external.css" />
</head>

Black text.

That's confirmed in Firebug.


Conclusion:

There are only 2 levels: in head vs inline.
What's in a style *tag* has as much weight as what's in an external stylesheet.
If 2 rules have the same specificity and belong to the same level, order matters, latest rules.

Naming convention for id and class attributes

Bill Weinman uses camelCase for his id and class attributes because he claims you can only use alphanumeric characters here, and he doesn't like to separate words with an underscore, and that's his “personal preference”.

The alphanumeric bit isn't true. You can use any of these characters: [A-Za-z][A-Za-z0-9:_.-] for class and id attributes, in both XHTML and HTML 4.

Most designers use the dash to separate words:

<div id="main-content">

Bill Weinman prefers camelCase:

<div id="mainContent">

Both ways are valid.

Note: Rails' HTML helpers use the underscore, which is also valid.

From the W3C specification: id and name [and class] tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

Rules that are too specific hurt reusability

Bill Weinman pretty systematically uses selectors that begin with the id of a specific region on the page. Also, he often adds tag name to his id and class selectors for no reason. Like so:

/* ====- main content ===== */
 
#content div#mainContent {
    ...
}
 
#mainContent p {
    ...
}
 
#mainContent h1, #mainContent h2, #mainContent h3, #mainContent h4 {
    ...
}
 
#mainContent h1 {
    ...
}
 
#mainContent h2 {
    ...
}
 
#mainContent h4 {
    ...
}
 
#mainContent ul {
    ...
}
 
div#youtubeVid {
    ...
}
 
/* ====== main content left menu ====== */
 
#mainContent p.leftMenu {
    ...
}
 
#mainContent p.leftMenu a {
    ...
}
 
#mainContent p.leftMenu a:hover {
    ...
}

Weinman does define a few global styles near the beginning of his stylesheet, but clearly not enough. Through his stylesheet, he repeats himself ad nauseum, redefining again and again the font-family, font-size, and color properties for his elements. What happens if some day someone changes the “left menu” container to a ul? Why use this:

#mainContent p.leftMenu {
    ...
}

When the following is flexible and reusable:

.horizontal-menu {
    ...
}

Conclusion

“Although long selectors that follow the structure “grand-parent parent child” are more readable, their specificity make them less reusable, and they also make a web design less flexible.” — moi

About object-oriented CSS

Nicole Sullivan, the woman who coined the expression “Object-oriented CSS”, gets it. Unfortunately, this Nettuts tutorial does not.

View more presentations from Nicole Sullivan.

Lists in Internet Explorer: not a bug. Just different browser defaults.

Bill Weinman claims there’s a bug in Internet Explorer that’s never ever been fixed. Bill Weinman uses the following CSS, and complains that it looks all wrong in IE:

#sideBar ol {
  margin: .5em 0 1.5em 0;
}

Not enough space on the left in lists in IE

However, if you were to apply a left padding of zero to the list, it would begin to look “funny” in Firefox as well. Look at that:

Not enough space on the left in lists in both browsers

Weinman should have reset the padding around his list to 0 for the space on the left to become the same across browsers. Why?

Firefox's default styles adds padding to the left of lists.

He should apply some sort of reset first, and only then pick a left margin:

#sideBar ol {
    margin: .5em 0 1.5em 2em; /* Adding some margin to the left */
    padding: 0; /* Resetting the padding all around */
}

The space on the left of the list is the same across all browsers now:

The space on the left of the list is the same across all browsers now.

But the author doesn't do this. He doesn't reset anything and picks a left margin that's a compromise. The compromise makes his list look sort-of-okay-but-not-great in Firefox and Internet Explorer.

(Ideally, we place our reset rules inside a reset.css file, and we import that file inside our main stylesheet using @import.)

Conclusion

Each browser has its own default styles, and that's okay, it is not a bug. To avoid discrepancies across browsers, it's best to use a reset.