Setting rather than Resetting Default Styling

Future of Web Design London 2010

Editors Note: In his first article for Think Vitamin Thierry Koblentz discusses the issue of “resetting” your CSS.

“base.css” versus “reset.css”

For a long time, the very first line in my styles sheets was:

* {padding:0;margin:0;}

This simple rule was very convenient as it leveled margin and padding values of all elements across browsers. This “hard reset” was short and simple and it had the advantage of belonging to the main styles sheet rather than being an external file.

Later, this technique was denounced as bad practice as it makes the rendering agent style (check) every single element in a document. It also triggered issues with form controls, but authors were used to specifying styles for these.

Then came “reset” styles sheets. These files go way beyond resetting margin and padding. The most complete in terms of properties/elements involved has to be Eric Meyer’s. It “unstyles” everything you could think of, from a to var.

Authors start with a clean slate. From there, they most often write rules to style elements that were originally styled by the browser’s styles sheet, but overwritten by the reset file. In short, many elements are styled three times:

  1. by the browser’s styles sheet (see User Agent Styles Sheets).
  2. by the “reset” file.
  3. by the author’s styles sheet.

Criticism of this Approach

Jonathan Snook, Jens Meiert and others have “criticized” this approach, saying more or less that there was no use for a “middle man”. On Jen’s site, “randomCommenter” summarizes the issue pretty well when asking: “Wouldn’t a well written base style sheet render a reset style sheet redundant and therefore useless?”

Actually, I believe Eric Meyer himself hints in that direction when he says:

“I don’t particularly recommend that you just use this in its unaltered state in your own projects. It should be tweaked, edited, extended, and otherwise tuned to match your specific reset baseline. Fill in your preferred colors for the page, links, and so on. In other words, this is a starting point, not a self-contained black box of no-touchiness.”

In any case, people should at least evaluate the rules in these reset files before copying and pasting their content. For example, if one authors documents as HTML 4.01 Strict! one may safely remove from a reset styles sheets any reference to elements like:

  • iframe
  • applet
  • strike
  • u
  • font
  • s
  • center

My Base Styles Sheet

Following the idea of “tweaking” a reset file, I came up with this “base styles sheet“. It sets default styling for many elements, follows a couple of recommendations regarding usability/accessibility, and addresses a few “common issues” as well.

What does it do that a reset doesn’t?

It fixes a few things

  • It forces a gutter for a vertical scrollbar (when content is too short to require a scrollbar)
  • It includes an IE button width fix
  • It removes “sticky” outline (not in Internet Explorer though)
  • It prevents “mysterious gaps below images
  • It prevents descenders letters in legend from being cut-off in Internet Explorer
  • It vertically aligns checkboxes and radio buttons with their label
  • It sets a default color background for the document with no shrink wrap effect on body1

It styles lists by default

It is easier to remove markers on lists than to style them. So, by default, lists are styled to show indentation and markers depending on hierarchy and list types. But the styles sheet contains a class to reset this styling. When applied to a UL or OL – it will remove markers and left margin on their items.

It creates vertical “gutters”

Left and right padding are applied to most block-level elements to create vertical gutters. This allows to build layouts without having to use “padding” on main containers which helps to produce designs that do not break in IE 5 (or IE 6 in quirks mode) as width and padding values are not mixed. This is also an alternative to using non semantic wrappers as a workaround to avoid mixing these properties.

Why using padding instead of margin to create that space?

Using padding allows to paint elements’ background all across their parent container. Stretching from one edge to another. When this behavior is not sught, for example when styling a heading with a bottom border that should be no wider than what appears to be the “content box”, authors can use a class (in the sheet already) to revert that styling (swaping padding values with margin values).

It creates horizontal white space too

  • Via margin – By default, vertical space is obtained through top margin. A top margin of 1.2em is applied to most block-level elements.
  • Via padding – Authors can uncomment two rules in the styles sheet to create spacing using padding instead of margin. The advantage of this method is that it prevents two common “issues”:
    • Collapsing margins - Margins will not collapse since elements are not styled with vertical (top/bottom) margins.
    • Loss of top margin when clearing floats – When an element clears a float, it “loses” its top margin, but that gap is preserved if top padding is used instead.

What else?

Rules in this base styles sheet are well commented and values that one would like to change (font-family, font-size, line-height, color, padding, etc.) are placed near the top of the file.

You can download base.css with comments or a minified version. My advice is to use these rules as a starting point to create your own styles sheet. Do not link to an external file to then override property values, instead, add, remove and edit anything you want to end up with a main styles sheet for your own project(s).

My base.css styles sheet is a work in progress. If you play with it, and if you see things that should not belong in there or to the contrary things that should be included, please join the discussion.

1 The YUI reset styles sheet sets a background-color on html. This styling makes the browser paint the background of body no taller than its content instead of matching the viewport’s height (this is by specs). I believe a future release of YUI reset will include this change.

Free Workshops

Watch one of our expert, full-length teaching videos. Choose from HTML, CSS or WordPress.

Start Learning

Treehouse

Our mission is to bring affordable Technology education to people everywhere, in order to help them achieve their dreams and change the world.

Comments

0 comments on “Setting rather than Resetting Default Styling

  1. I like this idea a lot actually. Btw, the link to the base.css with comments and base.css minified are broken :(

  2. This is a really good idea. I was just reading some of the opposition to reset stylesheets yesterday.

    I think I’ll start working on my own base stylesheet.

  3. I agree fully, but I’ve sort of created a blend of the two. I have a reset stylesheet that’s similar to Blueprint’s: it combines both Eric Meyer’s reset and some base styles for typography and other elements. This way everything get’s reset so I’m starting on a blank slate for all browsers, but then establish clean rules and commonly used elements that I utilize on every project.

    Just like yours, mine is a work in progress that I continually refine for every project, so I’ll have a look at yours and see what I add to mine :)

  4. This is the way I’ve been writing stylesheets for the past 10 years. I’ve always thought the reset stylesheet was pointless.

    Especially when using CMS systems (like Drupal) where the website will have a life of its own after launch with features continually being added, you’ll never know what markup will be thrown at your design.

    You _need_ to be prepared and create a baseline style for all your HTML elements. Nothing else makes sense.

    In the early days of reset stylesheets I saw people saying that the best part of a reset stylesheet was making it easy to recognize un-styled content. Oh, really? And you’ve got sample content that has all possible markup in it? Didn’t think so.

    Its much easier to just take a pre-made list of HTML Elements and go line-by-line and add your design’s styles to them all in one go.

    This is the approach I’ve been sharing with Drupal’s zen theme for the past 3 years: http://drupal.org/project/zen

    Thank you, Thierry!!!! For writing the article I’ve been meaning to write for so long.

  5. Yoink! We use a reset where we work that one of the developers cobbled from somewhere. I’ve meddled about with it over the last year, but have been meaning to produce something more like this which gives us a starting base instead of unstyled madness, along with adding in key divs etc. When I get a chance I’ll probably go through it all properly and hash it together with our reset. I much prefer your solution to random whitespace under images! (Produced by the browser thinking it’s text and leaving room for the gs and the ys I’m told).

    Cheers.

    • Strictly speaking, the browser doesn’t ‘think images are text’ :-) Images are inline elements by default – this means they share some of the styling properties that text does, including the ‘extra space for descenders’ that you’re referring to.

  6. I feel like a bit of an idiot – i’ve never thought of the reset stylesheet in that way at all. It’s always been used by me as a way to have a blank slate and not have my own default values.

    Thanks for opening my eyes!

  7. In your base.css file, there is a comment about sup/sub tags and the styling applied.

    The reason for the CSS declaration is that IE doesn’t resize the text properly. IE interprets “sup” as shift the text up… not shift it up and shrink it a bit so that it actually looks like superscript text.

    In addition IE is picky about the order of tags – thus if you do [small][sup]TM[/sup][/small] it renders differently than [sup][small]TM[/small][/sup]

    • Hi Steve,

      Are you sure about this?

      I did not check the issue about nesting, but regarding text-size it seems that browsers do *not* resize the text.

      Thanks for your feedback

  8. Here it is! I’ve been looking for this article to come out for some time now. I’ve used Eric Myers reset in loads of my projects and started to notice rooms for improvement. Time to get my base.css on now. Thanks!

  9. I wasn’t hinting, I was saying outright that the reset CSS is meant to be modified to match one’s personal preferred defaults. At the end, you should have what I sometimes call a “reboot” style sheet.

    Of course, not everyone does: a number of people just use the reset as-is, and write overrides on a per-project basis. That might not work for you or me, but it does for them. No big deal either way.

    I’m really heartened to see you present and discuss your own “reboot” styles, Thierry. I think that’s a great way to start conversations about how we all go about styling. Thanks for the article!

  10. Very well thought. I like the small touches for captions, checkboxes, etc. Not very fond of classnames that describe styles like “noMarker” or “padding2margin”, but it’s a great starting point.

    • Hi Ricardo,

      If you have better names, I’m opened to suggestions :)
      But note that these class names are *tied* to the styling and have nothing to do with the content.

      Thanks

  11. Interesting approach. I made something similar couple months ago. But my project is more typographical reset (or maybe reset is not the right word) better Base Rendering Typographical Library http://code.google.com/p/azbuka/.

    But I think is better not to mix reset with base. They have two completely different purpose. Reset is killing all defaults CSS and totally rebuilding everything and the Base is directly overwriting everything. The problem with Base(Also with my project Azbuka) is too personal maybe you don’t wont Georgia to be your default style for H1-H6 or blockquote to be italic. So in some case is better to use direct overwriting(Base) in other total Reset.

  12. Great Article. I started out using just plain reset style sheets but am now working to create a proper base style sheet much like yourself though I am still in the initial stages. Thanks again for all the info!

  13. here’s a better idea: tell the dumbass browser developers (YOU HEAR ME, REDMOND?!) to code their browsers so they render according to web standards. we shouldn’t have to use reset.css, base.css or other dipshit.css. power to the people. truth to power. etc. etc.

    btw, loved the article.

    • Although *some* of Thierry’s styles are related to fixing browser bugs, a lot of them relate to maintaining consistency across browsers. The differences between margin lengths, font sizes, etc. between browsers are NOT bugs; the specs say very little (if anything) about default user agent styles, which gives vendors a lot of flexibility in how they style markup by default, hence the need for explicit overrides by the stylesheet author.
      The real shame is that default user agent stylesheets have barely improved over time. Default line heights are still (IMHO) too low by default, margins around certain elements don’t make a great deal of sense, etc. Many different vendors are guilty of poor housekeeping here, not just Microsoft.

  14. Cool i never realised resetting the padding and margins would have such an effect when rendering a html page. I’ll keep this in mind for my next project :) Thanks a lot!

  15. That’s a good article and a good base CSS that you have there. Topics like this are much more interesting than the usual repeated collections that some other sites pump out.

    One small thing, though: “seeked” should be “sought”.

    • Hi Robert,

      Thanks for spotting this. English is not my native language, but that’s no excuse…

      Stay tuned for my next article: “40 best ways to do this with CSS”
      Just kidding :)

  16. Thank you! I’m the type of person who hates code redundancy, so I could never stomach using a plain reset. I’ve always modified a base. I will be taking a more in-depth look at yours in order to make some improvements on mine, so thank you for that as well.

  17. Your base stylesheet is a very nice way to establish common basic styling. But simple star selector reset (* {margin: 0; padding: 0;}) is still more useful to reset paddings and margins, unless the page has extremely large number of dynamically modified DOM nodes.

    Let me quote Steve Souder’s on its performance impact:
    “That single universal simple selector is going to be faster than downloading a stylesheet.”
    http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/#comment-657

    • Hi Krzysztof,

      It seems you’re ignoring 2 points made in this article:

      1. this is not about zeroing styles, but rather setting specific values (as John pointed out)

      2. the performance impact is not related to download (something the browser does once anyway), but to the fact that the parser has to go through every single element in the document.

      Thanks for your feedback

  18. I gave away using a reset in favour of your method Thierry a while ago. I have my own default stylesheet that I use at the start of every project that I have developed and modified over time.

    @Krzysztof I disagree that the star selector reset is more useful to reset margins/padding. The reason I gave up using it was because I found that I explicitly stated margins and padding on all my elements anyway, so there was no need for me to remove them by default before starting.

      • Yes, I read the article; it’s quite interesting and has sparked a great conversation.

        Perhaps I should re-state with more clarity: The Meyer reset linked in the article is out of date and if one chooses to use the Meyer reset (or build upon/extend it), then using the most recent version will yield better results.

  19. Great article, good to see people pushing away from accepted norms to develop cleaner code, I have been tempted by various CSS frameworks overtime but have now decided that there is no cure all for each site CSS code. There is a however a genius CSS framework we should all be looking at very seriously at the moment.

    http://unobtrusivecss.com

    :)

    • I think you could save a few extra bytes by using class names only (without the DIVs).
      I think that should work as well :)

  20. While this makes sense in genereal (defining your OWN defaults), it doesn’t make sense to publish it, because it’s too specific to be a genereal purpose stylesheet.

    Nonetheless you made some points worth thinking about.

  21. Agree with Dan, here – the theory and principles you’re espousing are very worthwhile, but the specific example is less useful. A couple of other comments:

    1. Wouldn’t the ‘preventing borders around linked images’ be done better with a ‘a img { border: 0; }’ ?

    2. The way you refer to collapsing margins sounds pretty negative – I hope you’re not suggesting that they aren’t a very useful feature of CSS :-)

    3. I agree with an earlier comment about the problems with naming your class ‘noMarker’. If someone else were to use your stylesheet, they should rewrite that selector according to the semantic class names of any lists that they don’t want markers to display on.

    Anyway, a few gripes aside, some great points here, Thierry, thanks.

    • Hi Bobby,

      The specific example is a starting point, it is not meant to be used “as-is”. Authors may tweak it for their own use or not even use it at all, only edit *their* existing styles sheet with one or two things they may have found valuable here.

      I’m not sure ‘a img { border: 0; }’ is better than ‘img { border: 0; }’. Why do you think the former is better? Because of the comment in the styles sheet or for another reason?

      Regarding collapsing margins, no I’m not saying that :-)
      The comment in the styles sheet says “this is a different approach which may be less frustrating for novice because it avoids running into collapsing margin”.
      And as you noticed, this is the one that is commented out, not the rule setting margins

      I don’t like “noMarker” either, but I don’t have any markup to relate to (for context)…

      Thanks for your feedback

      • On the ‘a img’ point (your response dealt with everything else), I guess it’s a) a case of speed (if ‘* { …}’ is bad, surely an unnecessary ‘img’ selector is also) and b) a case of clarity (including the context makes everything that little bit clearer, I think). But, sure, this IS nitpicking :-)

  22. Doesn’t this mess with vertical rhythm? Wouldn’t you be better with a base.css which uses vertical rhythm and applies some of the other fixes?

    • Hi Banzaik,

      If I understand your short post, you mean that reset.css slows the reflow by more than 7%.
      But why do you call that bad practice? In regard to performance only or as a general rule?
      And what is the alternative you think authors should favor?

      Thanks

      • Yes, you understood me correctly.
        Slow reflow – bad for the fast sites (eg google, yahoo, facebook)
        better apply the reset to a specific tag (contact him through the class and no cascades) and try not to use tags that require reset
        It is better to use tags that do not need to reset – for example, div, span, and other
        Yes, it hurts semantics, but also improves the speed of the site

  23. @Andy: Thanks for clarifying. The article does reference an older version of Eric’s reset, but I don’t think it changes anything regarding my base styles sheet as it is not used as a “starter”.

  24. @banzaik: I knew you would come there :-)
    imho, best practice should *not* be dictated by performance alone. Even less when it means cheating with content.

    Another point is often discussed when it comes to styles sheets and performance. It is the fact that authors should “only” use selectors that are relevant to the document. But how does that make sense in term of maintenance, cache, etc.?

    Thanks for joining the discussion

  25. @Bobby:

    nitpicking is not necessary a bad thing :)

    I agree that the “a” brings context, but I’d think that styling directly the “img” elements instead of targeting them via “a” is *faster*.

    I believe contextual selectors slow down things, but I’m not 100% sure. Could somebody confirm the performance issue?

  26. That was a really a strategic post. It is discussions like these which make the world of websites and stylesheets great. And to have some big names join the discussion only makes it all the more better!
    A big thanks to Thierry. To Eric. And to everyone else!

  27. I definitely understand your approach here, I just know it will be a bit of growing pains for any dev who wants to start using this (and is used to using a reset.css).

    I only mention that because when I first started using the ‘donkey reset’ ( *{margin:0;padding:0} ) I had some growing pains because I was used to inputs with padding, etc. Then when I switched over to the YUI reset, I had a bit more of the same.

    Switching back will cause this all over again, but like I said, I definitely understand where you’re coming from, and what better time to get started, right?

  28. Wow, finally i find somebody who thinks the same way i have been thinking about this for years. I actually have a “common.css” file that sets and fixes common elements/problems that i adapt to every project, instead of a reset.css.
    Nice to know that i wasn’t that crazy…

  29. Glad somebody finally said this! Seems a bit silly to set everything back to zero, then set it to the way you want it to display again after that.

    If you are supplying your client with a CMS, there really are only a handful of tags they will be able to use anyway, so there’s no point going over the top and resetting everything.

    I would want tags to display in some tailored form, even if I hadn’t added CSS for them. So, for instance, if I hadn’t restyled a list item and someone used it on the site, it would be better to display as the default browser list item, than to have no margin, padding, or bullets because I’d reset everything.

  30. I am constantly baseline “setting” CSS that has been “reset” rather than “set” right from the beginning. I’m glad I’m not the only one the subscribes to this methodology.

  31. Hey Thierry, I want to reduce the font-size on a global scale, I know of the issues with the font size and different browsers, and I already declared the font-size:100.01% in the html tag, now where is the best place to globally reduce the font size? is it in the body or in my main wrapper? and should it be with em or %?

    Thanks for this! It’s my first project trying this style sheet :-)

    • Hi Jorge,

      As the base styles sheet shows, I do not set font-size on html nor body.
      If I need to reduce default font-size across the board, then I use em on the main wrapper.

  32. There’s a little gotcha: an Ol inside an UL is styled as if it were an UL.

    You need to replace ol li {/*styles…*/} with ol li, ul ol li {/*styles…*/} so that the UL rule doesn’t apply blindly to OL inside UL.

  33. Hi Thierry,

    Thanks for a great post. A good read and lots of knowledge from you and the discussion here. I had been using a plain reset and never occurred to me to cut out the middle man, you did a good job with this base style sheet I am starting a new project today and will be using something like this now. :)

    Question though I am having a tough time understanding the font sizing. I had been setting a base font size of 62.5% in my reset and then sizing with em’s inside. What is the best way to accomplish that now? I do not understand the 100.1% part.

    Thanks again!

    -Ryan

  34. Shouldn’t you add h1,h2,… to the following rule?
    /* this is to reset the left/right gaps (created by the previous and next rules) on nested elements
    */
    dd p, dd pre, dd ul, dd ol, dd dl, li p, li pre, li ul, li ol, li dl, fieldset p, fieldset ul, fieldset ol {
    padding-right: 0;
    padding-left: 0;
    }

    Because if I have

    Heading
    some text

  35. Shouldn’t you add h1,h2,… to the following rule?
    /* this is to reset the left/right gaps (created by the previous and next rules) on nested elements
    */
    dd p, dd pre, dd ul, dd ol, dd dl, li p, li pre, li ul, li ol, li dl, fieldset p, fieldset ul, fieldset ol {
    padding-right: 0;
    padding-left: 0;
    }

    Because if I have

    Heading
    some text

  36. sorry, hit the tab key.

    when there is a H1,H2… tag is nested, then it is indented relative to a paragraph beneath it.

  37. Hi Paul,

    As you say, this rule is to reset padding on elements in DDs, LIs, and fieldsets.

    If I decided to leave all headings out, it is simply because I rarely include them in those elements (never in DDs I believe) and when I do (in LIs for example) it almost always calls for custom styling anyway…

    In any case, people who are used to this type of nesting should definitely include headings in there (may be not the h1 though).

    I think the idea is to not over do it. For example, people who use a single h1 per document may want to remove this selector from the base rules if they are already “custom-styling” it somewhere else in the styles sheet.

    In short, we want to avoid redundancy and we do not want to create rules that don’t really style anything across the documents.

  38. Thierry,

    I see that you have.

    body, p, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, blockquote, th, td {
    margin: 0;
    padding: 0;
    }

    This is not much difference from.

    * {
    margin: 0;
    padding: 0;
    }

    What is wrong with default margins,

    http://css-class.com/test/css/defaults/default-margins.htm

    and controlling margin collapse with ‘auto’.

    http://css-class.com/test/bugs/ie/haslayout-margins.htm

    Ask yourself if you would use a reset.css or base.css file if there was no browser named IE7 or IE6?

    BTW, your base CSS is larger than my non IE7- CSS.

    http://css-class.com/test/zeta-0-1.css

    • Hi Alan,

      “This is not much difference from…”

      I think being explicit here is what matters. It allows authors starting with these rules to simply remove whatever they don’t need. And there are many they could remove…
      For example, I often leave form and table elements out of the styles sheet as I usually only include this styling in the HEAD of documents that contain form and table markup.
      It’d be the same for pre, code, dl/dd/dt, etc. It really depends on the common markup used across the site.

      “What is wrong with default margins…”

      I think your test cases demonstrate pretty well what’s wrong ;)
      My own “conclusions” are a bit different than yours though. For example, in your test 2d you say IE is wrong “because this should only appear if there was a padding or a border”. I believe it would appear the same if the container was a block formatting context, and isn’t what hasLayout does in IE? hasLayout creates block formatting contexts, hence it will prevent collapsing margins. In short, I’d say this is expected behavior, it’s not really a bug.

      For 4a & 4b, I see something different. You say “The container has hasLayout and this causes the paragraphs’ and headings’ vertical margins of ‘auto’ not to resolve to ‘0’ and are contained by the containers’ content/padding edge”. I do not see padding playing a role in there. In these cases, I believe IE simply *ignores* the (auto) declarations and defaults to default margin values. And because those containers have a layout the margins of these elements do not collapse.

      “BTW, your base CSS is larger than my non IE7- CSS…”

      That’s great!

      Thanks for linking to your test cases.

    • Sorry, I do not really care for CSS validation so I forgot to mention this.
      I should have pointed this out in the article.

      Anyways, those who want the “badge” can either drop these fixes or use Conditional Comments to hide the “CSS filters” I use for IE 6 and 7.

      • No problem. but as you said , you do not care for CSS validation .but validation purpose is not only to get “Badge”.

  39. Your base styles with comments reads like a CSS text book, or a CSS cheatsheet of common problems & solutions. Can’t say how much I appreciate your efforts.
    I’ve been using one of several resets, mostly E. Meyer’s and then sometimes the recommended styles here:
    http://www.w3.org/TR/CSS21/sample.html

    Any thoughts on the w3.org css default styles then, how it compares to your styles or if it creates any problems your styles fix overall. Just curious, it’s made a pretty decent base stylesheet starter kit.

    thanks,
    T.

    • T,

      As that doc says, this is a current UA practice, so I’d say using such styling goes against the idea of this article which aims at:
      1. avoiding redundancy,
      2. setting explicit styles rather than resetting values.

      PS: Thanks for the kind words.

  40. Thanks for sharing your base.css it is really helping me research and develop my own.

    However, I have found that your attempt to over-ride FF default line-height on form elements (specifically buttons) is, unfortunately, wishful thinking. The default FF stylesheet defines line height for buttons using: normal !important and, at least in my experiments, cannot be over-ridden. This makes sense for things like select, I suppose, but why they decided to include button makes no sense to me.

  41. This seems to encourage presentational markup. Also, on a large site — why would you want to preset styles for elements that you will just have to override anyway?

  42. Hi there! Well done and endless discussion. Well, better for the community. You point to use vertical-align:bottom; for images to prevent a gap from showing below images in some browsers. But can I (we) use display:inline-block; instead of vertical-align?

  43. Thierry,

    Is there a Github repository for this somewhere? I couldn’t find anything. If not would you mind throwing this on Github? Would make forking it and iterating on it a lot easier.

    –Max