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.
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”:
Bill Weinman sounds a bit depressed. But a tad bit depressed is much better than overly cheerful. He's a good teacher.
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.
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.
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.
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 { ... }
Nicole Sullivan, the woman who coined the expression “Object-oriented CSS”, gets it. Unfortunately, this Nettuts tutorial does not.
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; }
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:
Weinman should have reset the padding around his list to 0 for the space on the left to become the same across browsers. Why?
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:
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.)