A Single Article
Read it, comment, and share it with your friendsCSS techniques I use all the time
I’m always learning new things with CSS. It’s interesting because I’ve thought of myself as a CSS expert for a while now (I’ll challenge anyone to a competition, seriously) but I still keep learning and improving. I’ve come across some techniques lately that are extremely valuable and worth sharing. Have a look:
- Initial Settings
- Years ago I used the * selector as so in all my CSS:
* { margin:0; padding:0; }. This eliminated all differences in padding and margin across browsers so I was free to go about styling my page. Unfortunately, this isn’t a good practice. It’s very heavy on the rendering agent to apply rules to every single element in the document, especially with large web pages, and this can also destroy a lot of good default styling, especially when you want to have default styled submit buttons. I learned from KuraFire Network that it’s far better to have a complete list of default settings to apply from the beginning that targets the specific browser inconsistencies. I use something very similar to what is described at “Starting with CSS: revisited” site down: use my initial.css copy with the addition that I applyfont-family:inherit;to inputs, textareas and buttons. It works great and there’s no need for the * selector. - Text Readability
- Ever since I read the “100% Easy to Read Standard,” I have stuck to some basic but highly important initial settings for text; “
line-height:1.4” for readable lines, reasonable line-lengths that avoid lines much longer than 10 words, and colors that provide contrast without being too far apart. For example, pure black on pure white is often too strong for bright CRT displays, so I try to go with an off-white (#fafafais a good one) and a dark gray (#333333, another good one). - EM calculations
- Sizing text is always an important part of making a usable design. I start all my CSS files with the following rules:
The explanation for this comes from “CSS: Getting Into Good Coding Habits:”html { font-size:100.01%; } body { font-size:1em; }This odd 100.01% value for the font size compensates for several browser bugs. First, setting a default body font size in percent (instead of em) eliminates an IE/Win problem with growing or shrinking fonts out of proportion if they are later set in ems in other elements. Additionally, some versions of Opera will draw a default font-size of 100% too small compared to other browsers. Safari, on the other hand, has a problem with a font-size of 101%. The current “best” suggestion is to use the 100.01% value for this property.
Point taken, moving on. I like to keep my body copy at 1em for the main content; this fits the default text sizing that users have in their viewing agent. All browsers convert relative EM sizes to pixel sizes, and most users have browser defaults at 16px. Something I have been doing recently is actually calculating EM font size throughout my design to this base of 16px. Because browsers have to round fractional EM sizes to whole pixel values, it’s very important to really think about what the final pixel value will be. In my most recent text-sizing work, I used the following calculation: 14px/16px = .875, 18px/16px = 1.125. So my default text at 1 em would translate to 16px for most users, and my small text I sized at .875em which I can trust to result in 14px for most users, while my large text I sized at 1.125em which I can trust to result in 18px. Note that I avoid going lower than 12px for default sizing at all costs; anything smaller than that is too small for me to read and I would be a hypocrite if I expected others to read that. - Safe Fluid-width Columns
- I work with hybrid fluid layouts all the time, usually with max-width set at anywhere from 900 to 1000px. I usually have floated columns with percentage widths, and browsers will calculate these percentage widths to whole pixel values when rendering the columns. A typical problem is the following: when a user has the viewport at a size that makes the outer container 999 pixels wide, if the first column is 60% and the second is 40%, IE 6 will always calculate the two columns as 600 and 400 pixels and as a result, the two will not fit (600+400 = 1 more than 999) and it will drop the second column. This is obviously not intended behavior, and in a world where we still have to use floats for columns (I can’t wait for display:table support across all browsers), it’s important to work around this problem. I used to give my last column 1 less percent (in this example, it would have 39% instead of 40%, but this would usually result in columns that don’t quite fill up the container. Of late I have been giving the last column .4 less percent (in this example, 39.6%), which seems to work perfectly. Browsers will calculate this width and round up, but it will still fit even with an odd container width like 999px and I won’t have to worry about dropped columns.
- Filtering for Old Browsers
- To be honest, I barely support IE 6 nowadays. If there is something special about my layout that doesn’t work in IE 6, I will simply filter it out of the CSS that IE 6 understands. One example would be max-width… a layout with a fluid width and pixel max-width is just plain fluid in IE 6, and therefore doesn’t work at all. Because old browsers like IE 6 don’t support the “first child” selector (right caret >), I can do the following to make sure that IE 6 only gets the basic setting and all the new-fangled browsers get the right result:
div#container { width:900px; } html>body div#container { width:auto; max-width:900px; } /* This overrides the previous declaration in new browsers only, IE 6 simply ignores it. */ - Alphabetical Properties
- I don’t know where I got the idea, but I have been alphabetizing my CSS properties for months now, and believe it or not, it makes specific properties much easier to find. Here’s an example:
body { background:#fdfdfd; color:#333; font-size:1em; line-height:1.4; margin:0; padding:0; }
These are just things I do that have worked extremely well in my experiences; this isn’t a definitive guide of everything one should do nor is it everything that I do. Hopefully you find this useful and by all means, share your own techniques too.
p.s.: Please, Digg this article.
Get a Trackback link
82 Trackbacks/Pingbacks
Other blogs referencing this article53 Comments
Responses to my articleI am stunned at how many people continue to use hacks like the first-child selector to hide things from IE. Why not just use conditional comments? That’s what they’re there for! (Of course, this means we need to spread the word about conditional comments… which is part of what this comment is for!)
Kai, conditional comments are a proprietary extension that do not fit correct HTML rendering and only generate code bloat. The first-child selector is not a hack; it is completely valid CSS and it supports other browsers besides IE that also need it as a filter.
Of course the first-child selector isn’t a hack. I meant that using it as a way to hide a block from IE is a hack. In pretty much exactly the sense that people usually mean by the term “CSS hack”: relying on an undocumented feature of a browser.
I prefer to rely on documented features.
Since conditional comments fit into standard HTML/SGML comment syntax, I don’t see what you mean about them “not fit[ting] correct HTML rendering”.
Kai, it’s not a hack, it’s progressive enhancement:
http://css-discuss.incutio.com/?page=ProgressiveEnhancement
Conditional comments may fit the standard of HTML comment syntax, but the rendering behavior of IE’s engine does not. Anything contained within an HTML comment is supposed to be hidden from view, NOT rendered. IE’s rendering of conditional comments is a real “hack” as you describe the word and I try to avoid supporting such hacks as much as possible.
Further, the available of conditional comments in the IE rendering engine is a scapegoat the Microsoft has used on numerous occasions to excuse themselves from the responsibility they have to developing a compliant CSS rendering engine. Far too many times the IE team has said, “we didn’t manage to implement this CSS property correctly, so hack around it by using a conditional comment.” That’s unacceptable; developers should not have to do extra work to make up for the lack of work that Microsoft has done in their browser implementation.
By the way, let me mention that the topic of conditional comments vs. CSS filters has come up numerous times in the past and I have argued my position in a couple communities, mainly CSS-d and the Web Standards Group. So in case you were thinking that CC’s might be something I haven’t heard of before, I have heard of them, I’ve used them, and I’ve realized that I find them to be very wrong.
Plus there is the danger of a browser introducing support for first-child selector but not max-width or other attributes contained within the selector when used like a hack.
Conditional comments are reasonable, not ideal, in the face of a dominant browser that has rendering problems.
Since CSS doesn’t allow to define constants for color schemes, i define all colors (and fonts) in an extra block. Like:
a, #content h2 { color: #287; }
header, h1, #navigation h2, a:hover { background-color: #287; }
One of the best blog entries about CSS tips i read in while!
Paul: Fat chance, and if it did, it would never achieve the dominance IE 6 had. IE 6 won the browser wars because back in 1998, it had the best CSS support of all. If a new browser comes along with any sort of user base, I think I can assume that it will support CSS somewhere as well as things on the market now.
Besides, if you don’t support max-width, you get a 100% fluid layout. What’s lost?
I’m going to make a post soon about how I feel about conditional comments. I’m not condemning the use of them; I know there are reasons. I just choose to reject them in favor of progressive enhancement.
beza1e1: That is a good idea. Containing all color definitions in one section is also useful to make sure that the right color and background color combinations are used.
Great page, I’ll be back for sure.
-j
I’ve got to agree with Kai here.
Both conditional comments and the child selector use are “hacks”. Both are valid markup and both produce out of spec behavior in MSIE. But the child selector is the accidental artifact of IE’s implementation, while the conditional comment is an officially documented and supported behavior.
It also has the nice side effect of consolidating and isolating all your odd IE style overrides in one place and getting them out of the way when reading the styles for more compliant browsers.
So David, Kai, et. al, what does conditional comments do for IE 5 on the Mac? Which solution (the child selector filter or the conditional comment hack) ensures that IE 5 on the Mac gets the best fallback?
Great artile, great tips!
My own tibdit: I don’t order rules alphabetically inside a selector, I order them “hierarchically”, from “outside to inside”.
selector-thingie {
display
position
(top | right | bottom | left)
float
clear
margin
border
padding
background properties
line-height
text-* properties
font-* properties
letter-spacing
content (whenever used)
}
Anyway, great tips all of them. I also recommend The Elements of Typgraphic Design Applied to the Web (http://webtypography.net/) as it has several great advice on using your text to empower your design.
Excellent tips presented coherently, thanks!
Somewhere I read to use 62.5% as the font-size so that 1.2 em would be 12pt, 1.4em is 14pt, and so on, but I’m making a new design and it’s turning out to be a pain since that default is so tiny. Maybe I’m doing it wrong, any info on this practice? I may go for the 100.01% trick.
Nicolás: I could see how that would work, if you learn to think of it that way.
smithee: Your welcome
Keizo: 62.5% comes from the fact that 10px/16px = .625. So the default starts at 10px and then you can multiply from that 10 base. But you are right, 10px is very small text and it’s usually easier to just work off 16px as the base if that’s what your main text size will be.
Also, keep in mind that none of these measurements quite work if the user has their default text size at something larger (18 or 20px, for example), but it’s just relative sizing so it’s nothing to worry too much about.
body {
margin: 0;
padding: 0;
}
Is my Fave code
Why do you require email for comments?
Thanx Dude!
I learn a lot from your article above. Thanx for sharing.
Fake: So people can sign up to get e-mail notifications on comments, and I can associate e-mails with gravatars. How do you think some of these commenters have fancy pictures?
I just wanted to thank you for a very nice article. It’s so rare these days to come across css best practices article that makes me rethink my own set of standards, but this article offered a lot of tips I find very interesting and useful.
Conditional comments vs child selectors seems a worthy debate, but introducing IE 5 for Mac seems a bit desperate. I’ve been promoting Yahoo’s list of A-Grade browsers to clients to indicate what we will support (not that I especially like Yahoo and realize it only mentions Windows and Mac OS’s.)
I’m currently building my site and came across your post. I noticed you said you dont support IE6 much and that’s something I’m trying to decide for my site… How do you justify/evaluate this decision?
Great tips !
I also order rules “outside to inside”, but I also like to séparate my CSS into 2 categories : “layout” and “decoration” into the same CSS file.. or some times even splited into 2 CSS files :
/* LAYOUT /
mySelector {
display
position
(top | right | bottom | left)
float
clear
margin
padding
}
[…]
/ DECORATION /
mySelector {
border
background properties
line-height
text- properties
font-* properties
letter-spacing
content (whenever used)
}
Excellent, excellent round up — I really like the alternative to the star selector whitespace reset.
I agree with the alphabetizing tip: it really does make things easier. I make an exception for height and width, though: I tend to place those properties at the bottom, since they’re so often related.
beza1e1’s tip is ridiculously simple — I can’t believe I hadn’t thought of that.
http://jigsaw.w3.org/css-validator/validator?profile=css21&warning=0&uri=http%3A%2F%2Fwww.christianmontoya.com%2F2007%2F02%2F01%2Fcss-techniques-i-use-all-the-time%2F
Since you passed, I’ll read it now.
Congrats.
Frank: Well I made that comment in reference to my personal websites where I can make that decision for myself. Obviously for clients I have to support IE 6 and usually I can find a way to make the CSS work just as well for that browser. Anyway, the way it works out I do support IE 6, I just filter out the bells and whistles that don’t work on IE 6.
Michael: I saw an instructor today using IE 5 on the Mac. Not everyone is up to date with OSX. I really to prefer to use a filter that is platform independent and I’m not making a stretch when i say that.
dhjapan: I’ve done that before, it’s very effective for building the layout first and then adding details and design.
alliotsy: I make an exception when I do position:absolute, for example, because I always have to follow it with top and left.
html, body {margin:0;padding:0;}body {
color:#333;
font:1em/1.4;
background-color:#fdfdfd;
}
Nice. Learned somthing today too!
IMHO, the first-child selector is no more a hack than the @import directive (used instead of the link element to filter old browsers). I’m not against the use of CC, but I don’t think it is good practice to use them as downlevel-revealed conditional comments.
Great methods Christian, thank you very much for sharing!
sigh Why can’t Microsoft just do the right thing and start integrating Firefox instead of Internet Explorer into it’s OS? IE is half-baked.
Because then all the sites that depend heavily on ActiveX scripting won’t work. A good example would be ijji.com, where I go for online games. It’s an IE-Windows dependent system and losing that backwards compatibility would shut them down.
Another comment on the * selector: I’ve run into severe performance problems on large pages in (you guessed it) IE.
IE5 for Mac is waaaaaay more dead than IE6. I don’t see why anyone would still support IE5/Mac.
I love it when I can read a css-related article that has the ability to make me think, “Wow - interesting! I didn’t realize that … maybe I should shift the way I do things.”
Those kinds of articles are a gift and I thank you for yours.
For people that are worried about whether which browsers will suddenly support the direct-child selector and what will be broken… we already know what they are.
IE-Mac is no longer being developed, so we don’t need to worry about that one. IE7 already supports the direct-child and we know exactly which new things it supports and old things it still doesn’t support. And since all other browsers based on (mostly) compliant rendering engines all support it, they are not a worry either: Presto (Opera), iCab, KHTML/WebKit (Safari), Gecko (Firefox, et al).
Essentially, there will be no new surprises. Therefore, it’s not a breakable “hack”.
In the example of the article, since IE7 supports max-width, it too will not be “broken” by this “hack”. And even if it break, it would be a liquid layout without a maximum boundary (max-width). Less elegant, but certainly not broken.
PS: As much as I’d like to discontinue my support for IE-Mac, I too am surprised how many Mac users are still using. Can you blame them? I am always baffled by the number of sites out there with secure customer log-ins that list IE Mac as the only supported browser for Macintosh users.
Still, in many areas, IE-Mac is still more standards-compliant that IE7 (in particular because it’s not beholding to the f’ed up “hasLayout” modeling).
I don’t spend much time supporting it; and “supporting” it usually means just quickly /*/ backslash-commenting /*/ out the CSS you don’t want it seeing. Not complicated, not confusing to ANY other browser and won’t break in the future (remember, no more IE mac development).
sorry, that backslash comment example got messed up by your CMS. I’ll see if /\/ This one /**/ works.
Closer but nope.
/*\*/ curse you markdown! /**/
That should have worked. If it didn’t, I give up.
Okay, so /*\*/ THIS is an example /**/ of CSS hidden only from Mac IE. Conditional comments, rightly so, are ignored by it, so this is the only way to hide code from it. And a slight modification of the same backslash comment hack makes it so you can pass rules ONLY to it. But I’ve digressed enough.
John, sorry Markdown had to be such a hindrance to you comment. I think if you wrap something as code:
/*\*/ as so /**/with back ticks then it might work better, but I’m not sure.
I always use body{ font-size: 62.5%; margin: 0; padding: 0}
Why? Because then 1em equals 10px and 1.6em equals 16px and so on. Very easy to remember and to work on.
I really don’t get the “Please Digg this” obsession?!
Sérgio: That’s because you’ve never been dugg. I’ll have an article soon to explain the obsession.
Uhm, one common default style you “forgot” in your stylesheet is:
a img { border: none; }I think no one uses the default border around link images. It’s useful without css, but having css around it’s really pointless to leave it there, as there are much better ways of indicating that the image is a link.
(Of course, you only use <img /> when the image has semantic weight, otherwise you use background-images … but that’s another whole story :P)
Meh, your blog ate my img!
The paragraph in parenthesis above should say “you only use <img />…”.
Nicolás: fixed.
The reason I don’t include that in my “default” is because there are designs where it might be intentional to have some sort of border around images, so I choose to apply that on a site-by-site basis.
I remember reading this when you first wrote it and then with some issues I had at present I re looked hear and wolla my problem is solved. Thanks
Oh, I’m glad it was so helpful for you!
About the Safe Fluid-width Columns. Instead of decreasing the percentages, I started adding “margin: 0 -1px;” instead.
Nicolas: Yeah, that’s gotta be the best way to do it. I’m going to revisit the topic soon and see if I can put together a “best practices” guide.
Psst… site’s been up all along, it was just down very briefly when you made this post.
Christian, is there anything you would be doing different now, than a year or so ago since this post?
Stefan: I haven’t been doing anything different. These techniques are solid and I’ve been using them consistently since before I wrote this post and in all the time after.
Leave a comment
Share your thoughts with the worldYou can use Markdown, or you can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>Please keep comments respectful and on topic.
This form is guarded by Akismet, so don't waste your time trying to submit spam. It won't work. Ever.