KuraFire Network


Latest addition: Jan 19, 2007: Times are changing

Log

Starting with CSS: revisited

· By Faruk Ateş on Jul 26, 2005 · 41 comments ·

Subject level: Beginner

Little over a week ago I posted about my initial.css file, which I have used for a few years now to start off my CSS-powered layouts. Posting about it publicly spurred quite a lot of interest it seemed (the post caused a huge traffic peak that tripled my average), but there were also a few concerns raised by some readers. As a result, I bring you the revised initial.css file.

One of the issues is that my old habit will confuse some people (or at least those that don't notice it and didn't read the comments). I had the following:

html, body {
        font: 80%/130% Verdana, Arial, Helvetica, sans-serif;
}

Having worked with that myself for a few years, I'm used to the text-size being small and dealing with that where necessary, but people new to CSS entirely will not only not have that experience, they may well not quite get why their text is being rendered so small. Bad rule for them to start out with, so that alone was enough reason to revise my initial.css file. There is more, though.

The other thing is the use of the "star-selector," or * { } in CSS. The star selector selects every single element, which produces an overkill of style-nullifying. Sander pointed out that Mozilla (for one) has a great deal of default styling on form controls, which the star selector nullifies when applying margin:0 and padding:0 to it. As a result, buttons don't behave like buttons anymore, and so forth. I never really noticed that, which only goes to show that I'm no longer used to buttons behaving like buttons. I did some research in this, and as it turned out, most of all the weblogs I frequently comment on have this same problem: buttons not behaving like buttons. In most cases, it was indeed the star selector being the culprit.

Additionally, Mozilla developers have stated that the star selector slows down things. While this is apparently not noticeable for end-users in most cases, it may slow down other aspects that interact with the CSS as well. And don't forget that it's definitely a bit overkill to loop through all elements when you only have to alter a dozen of them, roughly.

So, I've come to revise my initial.css file and as a result, I've dropped the star selector entirely in favor of a much safer solution.

The new start:

html, body, form, fieldset {
        margin: 0;
        padding: 0;
        font: 100%/120% Verdana, Arial, Helvetica, sans-serif;
}

Instead of using a star selector, I specified the elements that need to be completely stripped of any default margins and/or paddings. I also specify the renewed font: property here because the html element is targetted. This font styling will now inherit on every element in the page, unless overruled by later styling that you apply yourself. The 100%/120%-bit makes the text behave more like how people new to CSS would expect (or those who switch to using my initial.css in their existing projects).

Then comes the second change:

h1, h2, h3, h4, h5, h6, p, pre,
blockquote, ul, ol, dl, address {
        margin: 1em 0;
        padding: 0;
}

Instead of going through every conceivable element I'm just giving a vertical margin to the elements that greatly benefit from it, then removing any horizontal margin and all padding that may exist.

The rest of the previous file is still fine:

li, dd, blockquote {
        margin-left: 1em;
}
form label {
        cursor: pointer;
}
fieldset {
        border: none;
}

Robert Nyman pointed out that form fields don't inherit all font-specifications as you might expect them to, so for more text-scaling consistency we've added the following:

input, select, textarea {
        font-size: 100%;
}

Here's the new, complete initial.css file that is more safe to work with and has less side-effects that may confuse or annoy you:

/* =INITIAL 
   v2.1, by Faruk Ates - www.kurafire.net
   Addendum by Robert Nyman - www.robertnyman.com */

/* Neutralize styling: 
   Elements we want to clean out entirely: */
html, body, form, fieldset {
        margin: 0;
        padding: 0;
        font: 100%/120% Verdana, Arial, Helvetica, sans-serif;
}

/* Neutralize styling: 
   Elements with a vertical margin: */
h1, h2, h3, h4, h5, h6, p, pre,
blockquote, ul, ol, dl, address {
        margin: 1em 0;
        padding: 0;
}

/* Apply left margin:
   Only to the few elements that need it: */
li, dd, blockquote {
        margin-left: 1em;
}

/* Miscellaneous conveniences: */
form label {
        cursor: pointer;
}
fieldset {
        border: none;
}
input, select, textarea {
        font-size: 100%;
}

For your convenience, you can also simply download the completed initial.css file (right-click / command-click and choose Save Target As).

Bookmark: Newsvine del.icio.us Digg

Comments

41 comments

#1 · Robert Nyman · Jul 26, 2005 (21:06)

First, I appreciate your humble and professional approach when it comes to doing the revising.

However, for me, I usually work in pretty large projects where I don't produce all the HTML (it may be from other web developers, CMS etc). What this means is that I don't know what tags might come up (and there are actually a few of them to choose from).

The only part I do have full control of is the CSS, hence using the * selector to remove margin and padding from every element.

While I do understand the technical aspect of it, I have never experienced any downside to using this when it comes to slowing down the page, halting the rendering and so on. And we're talking on pretty crappy computers as well.

Therefore, I'd be interested in any benchmark tests to see what affect it actually has.

#2 · Faruk Ateş · Jul 26, 2005 (21:55)

Robert,

I believe that the above covers all elements that have any default styling (margin or padding). All other elements simply don't have any, thus there is no need to nullify it.

Also, the form control issue still applies.

#3 · Robert Nyman · Jul 26, 2005 (22:24)

It might cover all elements with that, but a warning bell rings in the back of my head telling me that there's more that do. :-)

Form control is an issue, but it might also be a deliberate design/interaction decision.

#4 · Sander · Jul 27, 2005 (09:44)

All (non-form, non-quirks-mode) default styling in gecko.
Look at forms.css in the same place to see what happens with form-elements.

I don't have time to look at it extensively right now (minutes ticking away in an internet cafe in Cairns here, plus it's much too nice weather outside anyway), so I'll leave the drawing of conclusions up to you.
Other rendering engines do different things of course, but I'd say it's a safe bet that if an element doesn't have any default styling that affects its dimensions in that file (or quirks.css), it won't have any default styling in IE/Opera/Safari/... either. (Cause the bug reports about "my site doesn't look right" would be flooding in with them (or us (mozilla) in the case of IE).)

#5 · Matthew Pennell · Jul 27, 2005 (10:05)

Just a quick comment - that default styling on all the block-level textual elements (headers, paragraphs, etc.) will cause margin collapsing between elements that directly follow each other, such as a series of paragraphs (so instead of a 1em bottom margin and a 1em top margin = 2em, it will just have a 1em gap between elements).

Obviously you're used to it, but it might be confusing for less experienced CSS users.

#6 · Faruk Ateş · Jul 27, 2005 (10:35)

Sander,
Seems like my initial.css is pretty much solid, then. The default margins I specify remove the differences between Mozilla and other browsers, without being all that different from the defaults.

The only thing I hear (just now, from Robert Nyman) is that form controls in IE might have unexpectedly large font-sizes from this. I'll do some testing...

Matthew,
Yep, but that's the same behaviour as browsers do by default: they give a 1em margin on such elements (generally), too.

For all who want to learn more about that, here's a good read on margin collapsing by Andy Budd: No Margin for Error.

#7 · Mike Stenhouse · Jul 29, 2005 (15:13)

I've got a whole bunch of stylesheets I use when I start my projects. initial.css looks like a more toned version of my typo.css sheet but I've got ones I plug in for tables, forms and navigation lists. I wrote it up a little while ago, if you're interested: A CSS Framework.

#8 · Faruk Ateş · Jul 29, 2005 (15:34)

Mike,

Nice stuff, thanks :-)

#9 · Scott L Holmes · Jul 30, 2005 (00:13)

This comes in just in time for a big 'ol project I'm working on.

But from what I'm seeing, all text butts right up to the far left edge - so what's some good techniques for proper margins? Right now I got:


body{
margin-left:.5em;
margin-right:.5em;
}

tiny margin because my text is all inside a portlet - but you get the idear.

#10 · Faruk Ateş · Jul 30, 2005 (02:47)

Scott,

Generally, a design is either centered or has a specific column on the left side. In both cases, there is no need for a margin on the left on the body element, hence why it's not been added as default styling.

You can apply a margin, a padding, anything you'd like, after the initial.css. It's only meant to neutralize browser differences.

#11 · Scott L Holmes · Jul 30, 2005 (15:11)

Oh, wait. Yes. I got that wrong. I was brain dead when I wrote that (month end financial close!)

Yes. right. I got those margins on the div that makes up the portlet. I left the body alone - thanks.

#12 · Julian Krause · Aug 5, 2005 (08:09)

I just redid my blog stylesheet using initial.css as a base, and it actually removed code from my stylesheet. Thanks for making this. I'm now redesigning every site with this as a base.

#13 · Faruk Ateş · Aug 5, 2005 (08:47)

Glad to have been of help, Julian. :-)

#14 · michelle · Aug 26, 2005 (21:04)

any examples of this in use?

#15 · Faruk Ateş · Aug 30, 2005 (12:51)

Michelle: not yet, as I haven't started on any project since putting the revised initial.css together, but there is one in the pipeline which I'll be announcing soon enough. It's a big one :-)

#16 · Edward O'Connor · Sep 6, 2005 (23:50)

See also Tantek's undohtml.css.

#17 · Michael Allan · Sep 7, 2005 (00:26)

Might it be worth changing the default font-size to 100.01% ?

Works around some display bugs, explained here and in Listing 16 here

#18 · Anton · Sep 7, 2005 (00:56)

Brilliant! Thank you for that write-up.

#19 · Faruk Ateş · Sep 7, 2005 (01:02)

Michael:
100.01% seems to be for some versions of Opera - if there's one browser where you really shouldn't support older versions any longer, it's Opera.

Also, using 100.01% is risky, as it'll interfere with elastic layouts that have em-to-px calculations used for defining (default) widths (such as my newest, upcoming project).

#20 · Dean Clatworthy · Sep 7, 2005 (14:16)

Hey Faruk,

Long time no speak. I was pointed to this post, and I'd like to ask you to elaborate on how "buttons stop acting like buttons" when using the star selector.

I've never had this problem before and thus would like some insight on it.

Regards,
- Dean

#21 · Faruk Ateş · Sep 7, 2005 (16:18)

Dean,

If you click on a default, square button, it'll invert the bevel and move the text slightly to make it appear as if you've actually pushed it in, pushed it deeper. Using the * selector removes that functionality, and when you then click a button, it'll not look as if you're pushing it in.

#22 · Adam Brunner · Sep 12, 2005 (13:17)

First of all, thanks for this stuff, it's great and using on my next site i've started developing in these days!

I found that if I change the default font-size later in the style for html to i.e. 80%, the table don't inherit the value, so I put the table to the first group in yout CSS, where the html, body, etc. is in, and that solved the problem!

- Adam

#23 · Bob · Jan 19, 2006 (09:44)

I like what you are doing, but it still is causing me a problem. I have the fillowing code:

h1 Title /h1 ... of a book

I want the text above to all appear on one line, but the text in the h1 appears on one line and the non h1 text appears on a second line. margin:0 and padding:0 don't seem to have any impact. Is this even possible?

I had to omit the carets in order to get this "code" to appear.

#24 · Faruk Ateş · Jan 19, 2006 (12:25)

Bob, the h1 element is a Block level element. If you want it to be on a same line with other content, either float it or add:


h1 { display: inline }

#25 · Bryan · Jan 19, 2006 (14:40)

At first, I was like WTF when I read this...but did a test and realized that YES, the buttons DON'T behave like buttons in Firefox when using the *. Good find.

One problem though, which you have shown in the above for applying vertical margins, is that the UL in Mozilla has a default padding to the left side (to typically indent), and unless you specifiy on a certain UL what the padding is, it will indent itself.

You corrected yours by saying margin: 1em 0; padding: 0px;

I just replaced the * selector on a buildout I am doing with your above html, body, etc... and my left navigation had to have padding: 0px; added to the UL because of this quirk.

Hopefully no other elements pop out at me using this method, I will keep my eye out.

#26 · Steve · Jan 19, 2006 (21:50)

I'm a little late on this topic. I tried your revised version, and my form buttons still lost their default styling, at least in Firefox and IE6. Is there a way to preserve that?

#27 · Bob · Jan 19, 2006 (22:58)

Thanks Faruk... the display:inline worked. And to think I spent 2 hours on this last night.

#28 · Faruk Ateş · Jan 19, 2006 (23:17)

Steve:
Maybe send me an example / URL by e-mail?

Bob:
No worries, we're all constantly learning more. I started out just the same, just like everyone did.

#29 · James · Jan 28, 2006 (01:55)

Thank you for that write-up. Good stuff

#30 · Kenneth Fraser · Feb 7, 2006 (16:19)

Greetings,

Nice article, I've been using a template like your original version for a while now. There is one thing I'd like to add and it is only something I use when I am working on large sites as some pages require slight differences in formatting.

/* ===== Generic Classes ===== */
.alignleft { text-align: left; }
.alignright { text-align: right; }

.floatleft { float: left; margin: 0 10px 10px 0; }

.floatright { float: right; margin: 0 0 10px 10px; }

.clearboth { clear: both; }
.clearleft { clear: left; }
.clearright { clear: right; }
/* ===== End Generic Classes ===== */

With that said you wouldn't require these classes on small sites as they're easy to maintain. I've found with experience dealing with clients who have large sites these classes have saved me from inline styles when a client asks if I can move an H2 element or something to the left, right, etc... on a specific page.

Later days,
Kenneth

#31 · Edward Clarke · Feb 7, 2006 (20:52)

@Kenneth
I'm the same. On top of a similar set of CSS instructions used by default on every build, I also have a library of classes that you know you're going to call on.

#32 · Edith K · Feb 14, 2006 (12:32)

I also found that Mozilla applies its own font-family to form fields such as input and select (I'm using FF 1.5.0.1).

To counter this difference I've therefore made the following amendment:

input, select, textarea {
font: 100% Verdana, Arial, Helvetica, sans-serif;
}

Otherwise the font-family in Mozilla is "MS Shell Dlg". Not a big difference but if you want your design to be exact, it's worth knowing.

#33 · hubbers · Feb 20, 2006 (19:56)

This is my fav catch all initial css snippet:


a img { border: none; }

Saves writing border="0" on the few images that survive the transition to CSS.

#34 · riccard0 · Mar 4, 2006 (10:48)

A complete analisys on html defaults removal from Eric Meyer: Really Undoing html.css

#35 · Sherwin Techico · Apr 13, 2006 (09:39)

Just revisiting the article. Great resource if I must say. But in terms of what Ed said above (more like pointing to Tantek's CSS), it is stripping out the margin and padding.

.../* form elements are oddly inconsistent, and not quite CSS emulatable. */
/* nonetheless strip their margin and padding as well */
dl,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input
{ margin:0; padding:0 }

Now with that, am I to assume that the "button" you were referring to above is the following?

<input type="submit"...> and/or <input type="button"...>

If so, it looks like your article is more recent than his CSS of 3/21/05. Point being that it might be good to consider this when comparing notes. HTH

PS. Being almost up to a year, has there been any further developments/findings about the * {} and its side-effects if still any, or none?

#36 · liz · Jun 28, 2006 (12:23)

Hello,

I'm glad I stumbled across this. I usually copy some generic rules to each of the sites i create, but this is much more thorough.

one silly question though. Does the div element have any pre-styled rules? It hasn't been included so i assume not?

thanks

#37 · Faruk Ateş · Jun 28, 2006 (20:42)

Liz,

That's right, the div element has no pre-styled rules of any kind. It is a block level element, but that's it.

Glad to hear you're finding the initial.css useful. :-)

#38 · Red · Jul 4, 2006 (15:59)

Hi

I have been fiddlig with CSS for a while now.. trying to become good at it, but have never fully understood the significance of TWO settings on the font size:

font: 80%/130% .......

Firstly.. WHY is there 2 settings, and secondly how does this affect the em settings that I use from there on in?

#39 · Faruk Ateş · Jul 4, 2006 (22:04)

Red,

The first setting is the font size, the second setting is the line height. Hope that clears is up for you :-)

#40 · Red · Jul 7, 2006 (16:59)

Doh!

Thanks Faruk - think someone told me this before and I forgot.

Now that IS cleared up I am going to quit my job and see if I can make it in the web design world.

I have just started a blog, where I will detail my experiences:

The Accidental Web Designer

#41 · Teddy · Aug 9, 2006 (14:33)

Such an old topic, but still visited I guess and since comments wansn't turned off I hope you don't mind ;)

fieldset { border: none; }

isn't enough to get rid of the fieldset border in Opera (version 8 I think), you'll need to use:

fieldset { border: solid 0 transparent; }

Cheers

All times are in CET. It is now 19:44.