Really Undoing html.css

Published 14 years, 3 months ago

There’s an aspect of document presentation most of us don’t consider: the browser defaults.  If you take an HTML or XHTML document—for the purposes of this exercise, assume it contains no presentational markup—and load it up in a Web browser with no CSS applied, there will still be some presentational effects.  A level-one heading, for example, is usually boldfaced and a good deal larger than other text, thus leading to the old stereotype of headings being “big and ugly”; the pre element typically honors whitespace and uses a monospace font; a paragraph is separated from other elements by a “blank line”; and so on.  From a CSS point of view, all this happens because the browser has built-in styles.

Tantek recently wrote about his creation of a file called undohtml.css, whose sole purpose is to strip away some of the default browser styles applied to common elements.  By resetting all headings to the same size, for example, he avoids the inconsistencies of heading sizes across browsers and brings everything to a common baseline.  If a different size is desired, the author has to do it manually.  (He should probably zero out the margins on headings as well, as those too tend to be inconsistent across browsers.)  He also zeroes out their margins, using a separate rule that I overlooked when I first posted.  Apologies to Tantek for my initial claim that he didn’t take that step.

Of course, Tantek isn’t really removing all the default styles, but (so far) just those that have given him the most trouble.  When it comes to Gecko-based browsers like Firefox and Mozilla, however, you can completely eliminate all built-in styles.  These browsers use a series of style sheets to control the presentation of documents, forms, MathML markup, and so on.  In OS X, you can find most of these style sheets by showing the package contents of the browser’s application file and navigating to Contents > MacOS > res.  On just about any other OS, it’s even easier; just search your hard drive for html.css and open the directory that contains that file.

If you look in html.css, you’ll find all of the styles that make what we think of as “unstyled” documents act the way they do.  Consider, for example:

area, base, basefont, head, meta, script, style, title,
noembed, noscript, param {
   display: none;
}

That rule is why the head element and all its contents don’t appear in your browser (as well as all those other “invisible” elements).  From a CSS standpoint, there’s nothing special about those elements as compared to others like div or ul.  The fact that they’re traditionally “invisible” is irrelevant—but with that one rule, the tradition is preserved.  You can always override the rule, of course; try style {display: block;} on a test document that contains an embedded style sheet and load it up in Firefox/Mozilla.  It isn’t magic.  It’s just a change from the usual way that documents are presented.  (See this test document for an example.)

There’s also:

/* nested lists have no top/bottom margins */
ul ul,   ul ol,   ul dir,   ul menu,   ul dl,
ol ul,   ol ol,   ol dir,   ol menu,   ol dl,
dir ul,  dir ol,  dir dir,  dir menu,  dir dl,
menu ul, menu ol, menu dir, menu menu, menu dl,
dl ul,   dl ol,   dl dir,   dl menu,   dl dl {
  margin-top: 0;
  margin-bottom: 0;
}

So in order to remove the top and bottom margins from nested lists, which is a traditional behavior of HTML browsers, that rule needs to be in the default style sheet.  Remove it, and nested lists would have top and bottom margins thanks to another rule in the style sheet:

ul, menu, dir {
  display: block;
  list-style-type: disc;
  margin: 1em 0;
  -moz-padding-start: 40px;
  -moz-counter-reset: -html-counter 0;
}

That rule not only sets the usual margins and such, but also includes some Mozilla-proprietary properties that help lists act in accordance with our expectations.  There are certain aspects of traditional presentation that aren’t (yet) fully describable using CSS, so the Mozilla folks have had to add properties.  In accordance with CSS2.1, section 4.1.2, these proprietary extensions are marked with a vendor prefix; here, it’s -moz-.  So any property or value you see starting with that string is a proprietary extension.  (For the record, I have no objection to extensions so long as they’re clearly marked as such; it’s the “silent” extensions that bug me.)

There is more to the presentation story than just html.css.  In the same directory, you can find quirk.css, which is applied instead of html.css when the browser is in “quirks” mode.  Another style sheet, viewsource.css, affects the presentation of any view source window.  All the nifty color-coding happens as a result of that style sheet, which is applied to automatically-generated markup that underlies the actual source you see.

So how do you completely strip out the default styles for an (X)HTML document?  Quit the browser application and rename the file html.css to something like html222.css.  Do the same for quirk.css.  Now re-launch the browser and find out just how much you’ve been taking for granted.  Feel free to browse around the Web and see what happens on various sites, but you’ll have to type blind, because the address bar won’t show any text.  You can still drag HTML documents on your hard drive into the window and see what happens.  If a document has any CSS applied to it, then the browser will use it.  It just won’t have any of the default styles available, so you’ll be applying your styles on top of nothing, instead of the usual foundation of expected presentation.

So what exactly is the point of all this?  As it turns out, I believe there are four:

  1. By studying html.css, beginning CSS users can compare the rules to the “unstyled” presentation of documents, and thus get a much better idea of how CSS works.
  2. By removing the default styles, you can come to a much greater realization of how much presentation is taken for granted, and how much there is to be dealt with when creating a new design.
  3. On a related note, note that the absolute bare minimum presentation of a document is to render all elements with inline boxes, and to show every scrap of content available.  Even something as basic as making a paragraph generate a block box is a style effect.
  4. It helps us to realize that what we often think of as the “special handling” of HTML is anything but: in Firefox/Mozilla, HTML documents are just a case of some markup that happens to have some pre-defined CSS applied to it.  Granted, the proprietary extensions needed to keep things in line with expectations are a case of special handling, and those tell us one of two things:
    • CSS still has a long way to go before it can be called a full-fledged layout tool, since it can’t fully recreate traditional HTML layout.
    • Old-school HTML layout was so totally wack, it’s no surprise that it’s hard to describe even with a tool like CSS at your disposal.
    I’ll leave it to the reader to decide which of those two they prefer.  Or, heck, choose both.  It isn’t as though they’re mutually exclusive.

Have fun fiddling with or completely removing the built-in styles!  Just remember: modifications like those described are made at your own risk, I’m not responsible if you do this and your hard drive vaporizes, no warranty is expressed or implied, not a flying toy, blah blah blah.


  1. […] nfomative when looking at other sites. Then I remembered Eric Meyer’s article “Really Undoing html.css” where he talks about modifing the cor […]

  2. […] e in the news or something. Also, for you CSS people, this article is pretty interesting: Really Undoing html.css […]

  3. I never really thought of it all like that and you are right! It shows how much we just take for granted.

    Your comment on extensions is especially true. I remember I used to sit and search for all styles on the web to make sure they were not just Microsoft. Same goes for javascript :(

  4. Dave: I think simply looking up the tag’s definition in the spec is easier and more reliable than searching for it on the web ^_^.

    ~Grauw

  5. a few months ago, on a hunch, i made a little experiment with css to get a document with visible head elements. works ok in gecko browsers, but others show varying degrees of success…

  6. “Have fun fiddling with or completely removing the built-in styles!”

    Great, there goes a couple of hours, fiddling… ;-]

  7. This occurred to me a while back, and I started experimenting with it in new sites I worked on. I’ve been putting this at the top of my style sheets:

    /* begin standard styles */

    body {
    margin: 0px;
    padding: 8px;
    }

    body, div, ul, li, td, h1, h2, h3, h4, h5, h6 {
    font-size: 100%;
    font-family: Arial, Helvetica, sans-serif;
    }

    div, span, img, form, h1, h2, h3, h4, h5, h6 {
    margin: 0px;
    padding: 0px;
    background-color: transparent;
    }

    /* end standard styles */

    It’s not absolutely complete, of course, but it’s proven a solid foundation for my attempts to write “no assumptions” CSS.

    Nice article. I’ll have to crack open the Mozilla style sheets and expand my “reset” sheet accordingly. :)

  8. What I asked myself many times is: Are the default styles of e.g. firefox different than IE’s?

  9. Undo Default HTML Styles
    The past few months I’ve been working on many, many style sheets, approaching them more and more modular. More often than not, I would start by making (or re-using) a module in which I reset/undo a lot of the styles…

  10. Thanks for pointing me to Gecko’s default stylesheet! It confirmed a hunch of mine about its handling of the center-element, but now I was able to look it up for myself.

    I wrote a quick page about how Mozilla/Opera handle the center element differently:

    center-element discussed

  11. Eric wrote:

    ” (He should probably zero out the margins on headings as well, as those too tend to be inconsistent across browsers.)”

    That’s exactly what the very next rule in undohtml.css already does:

    /* remove the inconsistent (among browsers) default ul,ol padding or margin */
    /* the default spacing on headings does not match nor align with
    normal interline spacing at all, so let’s get rid of it. */
    /* zero out the spacing around pre, form, body, html as well */
    ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html { margin:0; padding:0 }

  12. That is a very interesting article. Sorry for my bad English. Well, considering this technique of reseting the browser defaults. Would that mean more css coding? In this case, we would have to define each ul, li or title margins, colors, everything, right?

    Thanks,
    Andre

  13. I partially use the html.css style sheet to build a xhtml tag reference on my site: http://yansanmo.no-ip.org:8080/xhtml/ .

    Knowing this kind of CSS2 base properties can help to build or debug a Web site layout. By example, the margin-left and margin-right of headers (h1, h2, h3, h4, h5, h6) in konqueror 3.2.3 are set to “auto”. In Mozilla, they are set to “0”. That means that if you put a width to your headers, the blocks will be centered in Konqueror but not in Mozilla.

  14. Eric,

    I couldn’t reply in the post above this, but since your change to WordPress, some of your articles hang/crash IE6 and FeedDemon.

    Not sure what’s causing it.

  15. As I can’t reply to the next post, I reply here. I noticed the title, but I did not check the URI but I agree that it is not the preferred behaviour of WordPress. Though, I found this message sent to the WP CVS commit list very recently: http://wordpress.org/pipermail/cvs_wordpress.org/2004-September/000405.html which seems to solve the problem in the next version of WordPress.

  16. W3C also has a style sheet that describes the typical formatting of all HTML 4.0 elements based on extensive research into current UA practice.
    It’s available in Appendix A of the CSS2 specification.

  17. Thanks for once again some new learnings!

    As the vendor extensions like "-moz-…" seem to follow the spec, is my CSS invalid when using them?
    The Validator says yes it is, though i realized, that there is a slightly different error message as if i had a wrong written property like "widdth" in it.

  18. @Klaus: yes. In the sense that you don’t write CSS as defined by the CSS specs. The use of vendor extensions makes it possible to experiment with new ideas and to use extra properties in internal stylesheets, but it does not make new properties magically part of CSS.

  19. Eric, something’s going odd here with your layout’s margins; see this cap taken from IE6/Win, text size set to medium, window maximized to full screen (1024×768 on this laptop). –Steven

  20. margins/padding fixed now :-)

  21. BTW, I managed to get my post in by posting it via FireFox :)
    Still, I use IE5/5.5/6 for my main browser because 90% of my clients and customers do. I have to see what they see when I develop sites. I also haven’t had the time to try and got the Moz engine running in FeedDemon.

    I also just installed WMP 10.0, but I don’t see any files in its distribution that would affect IE.

  22. Klaus, Laurens

    I think Eric’s point is that the way each browser renders those specs may be different from each other. Referring to that sample stylesheet may not always accurate because of those browser differences. So it may become necessary to zero out all the defaults and rebuild a stylesheet from square one for all the browsers.

    Well, at least I think that’s what he means.

  23. What just sprung to mind was: it would be great if the next version of FireFox’s developer toolbar plugin had a function to switch on/off the deafult stylesheet…

    That would make development a lot easier – you could quickly turn it on/off to make sure you’re not taking anything for granted… and without having to go into the backend as it were…

  24. In addition to being able to turn off the default stylesheet, it would be good if the next version of Firefox allowed you to add other browser css definition sheets and switch to them. You could therefore see what your page would look like in IE without having to actually have both browsers open…

  25. Lucas: thanks for pointing out the default CSS for Safari. I went looking for something like that the other day but couldn’t find it. Now I know where to look ;)

  26. I remember my bemusement the first time I opened the first ever XML file that I created to be met with a solid block of text with no formatting whatsoever. I had grown so used to browsers applying default styles that I expected at least some line breaks.

    After that initial shock, I was interested by the prospect of styling everything on this blank canvas – all the minutiae that would otherwise have been taken for granted.

    Then after that, it just got boring. ;)

  27. Great article Eric :) I used a style sheet to strip default padding/margin annoyances, but thanks to you and tantek i’ve got myself a near complete sheet :)
    I also set the default font size and line spacing so that all my other style sheets can use em values on font sizes (weyhey for accessibility ;) )

    /*
    BASE.CSS
    attempts to set all layout attributes to the absolute basics, so that inbuilt browser formatting won’t produce un-expected results (i.e. incosistant padding values on

    across different browsers wont catch you out, because we set them all here)
    ——————————————————————————–

    /* SET BASE FONT ATTRUBUTES */
    html, body {
    font: Georgia, “Times New Roman”, Times, serif 14px/1.5em;
    color: #000;
    }

    /* REMOVE PADDING AND MARGIN VALUES */
    html, body, h1, h2, h3, h4, h5, h6, p, ul, ol, dl, li, dd, dt, img,
    blockquote, q, table, thead, tbody, tfoot, caption, th, tr, td, a, form,
    input, textarea, fieldset, pre
    {margin: 0; padding: 0;}

    /* SORT OUT HEADER FORMATTING AND SIZES */
    h1, h2, h3, h4, h5 {font-weight: bold;}

    h1 {font-size: 2em;}
    h2 {font-size: 1.75em;}
    h3 {font-size: 1.5em;}
    h4 {font-size: 1.2em;}
    h5 {font-size: 1.1em;}
    h6 {font-size: 1em;}

    /* HARMONIZE LINKS, KILL BORDER ON IMG LINKS */
    a {text-decoration: underline;}
    a:link, a:visited {color: #00f;}
    a:hover {color: #33f;}
    a:active {color: #fff;}
    a img, :link img, :visited img {border: none}

    /* REMOVE BROWSERS DEFAULT TABLE BORDERS */
    table {border-collapse: collapse;}

    /* REMOVE AUTOMATIC TOP/BOTTOM MARGINS ON NESTED LISTS */
    ul ul, ul ol, ul dir, ul menu, ul dl,
    ol ul, ol ol, ol dir, ol menu, ol dl,
    dir ul, dir ol, dir dir, dir menu, dir dl,
    menu ul, menu ol, menu dir, menu menu, menu dl,
    dl ul, dl ol, dl dir, dl menu, dl dl
    {margin-top: 0; margin-bottom: 0;}

    /* HARMONISE LIST-BULLET TYPE */
    ul, ol, dl {list-style-type: disc;}

  28. though i guess it’s easier to cut and paste everytime you start a new style sheet i dunno if a complete “reseting” stylesheet like the above is needed.

    i think the main point to be taken from this is that it’s another reminder that not everyone will have the same browser defaults (i’m sure we were all already aware of the need to set body colour and font-family for example) and so you should probably explicity define all rules for every html element used in a page

  29. I’m probably missing something, but this page http://www.meyerweb.com/eric/css/discuss/examples/all-shown.html
    doesn’t work the same way in IE as it does in Firefox. If that’s the case, I think it’s a very appropriate bug for this article.:)

  30. […] when you have an unstyled document. I did some googling and found a great article over at Eric’s blog. He points out that you can take a look at the default c […]

  31. I think it’s an interesting article, though I don’t see the point behind removing all default styles locally (html.css etc. for Mozilla) when you can save yourself the trouble and try out XML immediately.

    Also, one may be removing too much.  While margins/paddings aren’t defined, most (X)HTML elements are “dictated” a default display value as well as what type of anonymous boxes they need to create (or no anonymous boxes in the case of DIVs and SPANs).

    But it’s nevertheless interesting to read through those in-built CSS files, if only to see “why something is happening” in a particular browser (and not only Mozilla…).

  32. Absolutely magic. I’ve tried to style the html tag in the past with varying degrees of success but never all those normally invisible ones. Who’d have thought it?

  33. Take Back the Web
    Putting Firefox’s html.css to work for you.

  34. I don’t really remember where I saw this but as far as I tried it out it worked:

    * { padding:0; margin:0; }

    This way you restart the padding and margin for every element.

  35. It would be nice if the next version of firefox let you to add other browser css definition sheets and switch to them.

    Edgar

  36. […] 8212; nortypig @ 12:35 pm Meyer’s take on undoing html.css and quirk.css to reveal the underlying browser is i […]

  37. […] article about the beauty of being able to edit F Firefox’s default html.css file, as someone else has already expounded on that idea. Instead, I’ll tal […]

  38. […] taren. Wenn du dich entscheidest, vorgegebene Browsereinstellungen zu entfernen, wie z.B. Erik, dann dokumentiere das. Dies ist eine Übersetzung des Artik […]

  39. […] mments If you choose to wipe out default browser styles and start with a clean slate (see Eric and Tantek), document this somehow. I’ve found this to be […]

  40. […] modules? So far I have an extended version of the global white space reset, better call it undo html, different layouts (Note: When speaking of layout I mean n […]

  41. Here’s a really weird IE6 bug that I haven’t seen documented elsewhere. It caused me a few hours of grief, so I hope I can save someone else the same.

    One of my clients had some very definite ideas about font usage. Rather than the typical two or three choices for fonts, she wanted me to specify six or seven options before falling through to sans-serif. Neat freak that I am, I coded

    body {
    font-family: “Trebuchet MS”,
    Trebuchet,
    Verdana,
    “Helvetica Neue”,
    Helvetica,
    Arial,
    sans-serif;
    /* Other style statements here … */
    }

    Working on my Mac, using FireFox, Netscape, and Safari, I was able to show her how the site would look. When she looked at it on her PC with IE6, though, all she saw was Times!

    After much head-scratching, I realized that my fetish for neatness had been my undoing: IE6 requires the font-family list to appear all on one line!

    Caveat programmer.

  42. Nested lists are causing me problems… Tantek suggests setting ol and li to list-style-type:none. As soon as a list is nested this becomes painful.

    A standard nested ol for example, will switch the default bullet to lower-alpha for the first nesting. Since we’ve previously set the list-style-type to none, we then have to explicitly set nested lists to display a different bullet. eg. ol li ol li { list-style-type: lower-alpha; }.

    Obviously as lists get more and more nested (as in a standard legal document for example), explicitly setting the list-style-type is a hassle.

    Am I overlooking something here?

  43. This actually dates back to at least Netscape 4. Certain versions of Netscape 2 contained portions of the Netscape 4 rendering engine and also used a CSS sheet for at least some default styling (I know the OS/2 version did – not sure about other versions).

    On FireFox and Opera (others?), you can use an alt style sheet and right click to view with the alternative styles. This won’t, obviously, reproduce bugs, but the vast majority of modern rendering engines are using CSS based defaults, and you can copy the CSS sheet in and (within limits) you should see roughly what it looks like on the other engine. I do want to emphasize, within limits – mozilla won’t recognize other vendor’s extensions.

    Also for FireFox, you can see the most important other browser (IE) by installing the IE Tab extension. This lets you use IE in a specific tab, instead of Gecko, to render the page (similar to how Netscape-current operates). The reason I say “most important” in this case is that if the page looks OK in FireFox, there is a good chance it looks OK in Safari, Opera, etc. and so the only other one to be paranoid about is IE.

    Of course, view tab doesn’t help people running non-Windows OS.

  44. Any thoughts on * {} {margin:0; padding:0;}? Faruk Ateş seems to find some quirks from it, but that was about a year ago. Although, I seem to find it hard and annoying when I do styling for ULs, OLs, and LIs.

  45. What I asked myself many times is: Are the default styles of e.g. firefox different than IE”s?

  46. RE: Sherwin
    You need to define defaults back to your lists. So, after overriding the default values with zero padding and zero margin, you can declare your ul, ol, dl, with a margin-left of whatever you would like, and then with specific lists you can override those values if necessary. BUT – these are just re-building the defaults just as the article above states.

  47. Along with this: http://www.brunildo.org/test/, your article has been the most useful thing I’ve come across for helping a beginner get to grips with CSS. Every CSS tutorial website should have something similar.

  48. What are the default styles of elements like table and ul/ol?
    I expect them to be block but they act like “inline-block”
    please point me to the documentation if you know where it is.

    also,I’m certainly a CSS globalist i use;
    *{
    margin:0;
    padding:0;
    }
    all of the time

  49. I always use star element styling, something like this …

    * {margin:0; padding:0; border:0; font-family:Arial, sans; font-size-adjust:0.45; background:#FFF; color:#000; }

    seems to work.

    I don’t use many buttons, but I’ll be looking out for the form issues that Faruk raises at http://kurafire.net/log/archive/2005/07/26/starting-css-revisited !

  50. […] mais qui rendra peut-�tre service � certains d�veloppeurs, dans un article intitul� “Really undoing HTML and CSS“, Eric Meyer propose un fichier CSS qui permet de d�construire les valeurs par d�faut […]

  51. […] and CSS-loving palates. It could be helpful to some CSS developers : in an article titled “Really undoing HTML and CSS“, Eric Meyer offers a CSS file that undo all default values preset by the default […]

  52. Reset Reloades – Eric Meyers CSS & Browser Settings…

    Eric Meyers Artikel diskutiert erneut Vor- und Nachteile des Rücksetzens der Browser-Stylesheets. Bessere und effektivere Projekte stehen Nachteilen der Vorgehensweise gegenüber. Ein CSS-Tipp und lesenswerter Impuls für CSS-Interessiert…

  53. […] http://meyerweb.com/eric/thoughts/2004/09/15/emreallyem-undoing-htmlcss/ “There”s an aspect of document presentation most of us don”t consider: the browser defaults. “Tags: css, html, web, tools, xhtml, browser, design(del.icio.us history) if (typeof window.Delicious == “undefined”) window.Delicious = {}; Delicious.BLOGBADGE_MANUAL_MODE = true; […]

  54. […] There is an interesting article by Tantek Çelik about creating a default scaffolding stylesheet at http://tantek.com/log/2004/09.html#d06t2354. A follow-up by Eric Meyer is located at http://meyerweb.com/eric/thoughts/2004/09/15/emreallyem-undoing-htmlcss. […]

  55. […] – CSS guru Eric Meyer further built on the concept of resetting margins and paddings. In Eric Meyer’s exploration, he discusses Tanek’s work undoing default HTML styles (which he called undohtml.css) which […]

  56. […] – CSS guru Eric Meyer further built on the concept of resetting margins and paddings. In Eric Meyer’s exploration, he discusses Tanek’s work undoing default HTML styles (which he called undohtml.css) which […]

  57. […] этого, CSS-гуру Эрик Мейер (Eric Meyer) производит дальнейшие исследования вышеописанного приёма сброса отступов. В них он […]

  58. […] Obviously these are only simple examples, but this is one technique I will be using in all of my websites from now on… if you are interested in further reading, this is an invaluable link ‘Eric Meyers, CSS Legend‘. […]

  59. […] – CSS guru Eric Meyer further built on the concept of resetting margins and paddings. In Eric Meyer’s exploration, he discusses Tanek’s work undoing default HTML styles (which he called undohtml.css) which not […]

  60. […] Çelik and Eric Meyer started discussing a more targeted way to address user agent style differences in 2004, with the […]

Leave a Comment

Management reserves the right to edit or remove any comment, especially when abusive or irrelevant to the topic at hand. HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <em> <i> <q cite=""> <s> <strong> <pre class=""> <kbd>


Comment Preview

If you're satisfied with what you've written, then go ahead...