Initial values vs browser defaults
Every property in CSS has an initial value.
That initial value is the same
for all elements across the entire web.
The initial value of display
is inline
,
and the initial value of every margin
property
is 0
.
Initial values are used
when no other value is specified by the Cascade,
or inherited from elsewhere.
We can also revert our styles explicitly
to their initial value
using the initial
keyword.
But if we stop there, initial values donât provide a great reading experience. When all the properties are the same on all the elements, thereâs no visual differentiation between a link, a paragraph, a heading, or a list. We can see that by using the Ultimate CSS Reset:
/* you can't get any more 'reset' than this */
* { all: initial !important; }
This is why we need browser styles,
which provide different defaults
from one element to the next.
Some elements should be display: block
(divs, paragraphs, lists, headings, etc),
and some of those elements
should have margins on them
to improve readability.
We can revert any property on a given element
to the browser default style
by using the revert
keyword.
Technically this removes any styles from the author origin,
but since user-origin styles are rare,
it often results in styles from the browser.
Standardizing browser defaults
Browser styles are essential, but we often only notice them when they seem âwrongâ or unexpected â and think of them as a problem to be solved with âresetsâ and ânormalizationâ.
- Resets remove defaults to achieve a more âblank canvasâ
- Normalizers attempt to make the defaults more consistent across browsers
The CSS Working Group and browser vendors also understand that default styles work best when they are more consistent across different browsers. While browsers are free to provide whatever styles they want, most browser defaults can be traced back to the (non-normative) default style sheet provided in the CSS specifications.
Iâm not sure if thereâs a more recent version somewhere,
but I couldnât find it?
Update: The recommended default styles are now part of the HTML Living Standard, rather than the CSS specification.
CSS 2.2 default style sheet
html, address,
blockquote,
body, dd, div,
dl, dt, fieldset, form,
frame, frameset,
h1, h2, h3, h4,
h5, h6, noframes,
ol, p, ul, center,
dir, hr, menu, pre { display: block; unicode-bidi: embed }
li { display: list-item }
head { display: none }
table { display: table }
tr { display: table-row }
thead { display: table-header-group }
tbody { display: table-row-group }
tfoot { display: table-footer-group }
col { display: table-column }
colgroup { display: table-column-group }
td, th { display: table-cell }
caption { display: table-caption }
th { font-weight: bolder; text-align: center }
caption { text-align: center }
body { margin: 8px }
h1 { font-size: 2em; margin: .67em 0 }
h2 { font-size: 1.5em; margin: .75em 0 }
h3 { font-size: 1.17em; margin: .83em 0 }
h4, p,
blockquote, ul,
fieldset, form,
ol, dl, dir,
menu { margin: 1.12em 0 }
h5 { font-size: .83em; margin: 1.5em 0 }
h6 { font-size: .75em; margin: 1.67em 0 }
h1, h2, h3, h4,
h5, h6, b,
strong { font-weight: bolder }
blockquote { margin-left: 40px; margin-right: 40px }
i, cite, em,
var, address { font-style: italic }
pre, tt, code,
kbd, samp { font-family: monospace }
pre { white-space: pre }
button, textarea,
input, select { display: inline-block }
big { font-size: 1.17em }
small, sub, sup { font-size: .83em }
sub { vertical-align: sub }
sup { vertical-align: super }
table { border-spacing: 2px; }
thead, tbody,
tfoot { vertical-align: middle }
td, th, tr { vertical-align: inherit }
s, strike, del { text-decoration: line-through }
hr { border: 1px inset }
ol, ul, dir,
menu, dd { margin-left: 40px }
ol { list-style-type: decimal }
ol ul, ul ol,
ul ul, ol ol { margin-top: 0; margin-bottom: 0 }
u, ins { text-decoration: underline }
br:before { content: "\A"; white-space: pre-line }
center { text-align: center }
:link, :visited { text-decoration: underline }
:focus { outline: thin dotted invert }
/* Begin bidirectionality settings (do not change) */
BDO[DIR="ltr"] { direction: ltr; unicode-bidi: bidi-override }
BDO[DIR="rtl"] { direction: rtl; unicode-bidi: bidi-override }
*[DIR="ltr"] { direction: ltr; unicode-bidi: embed }
*[DIR="rtl"] { direction: rtl; unicode-bidi: embed }
@media print {
h1 { page-break-before: always }
h1, h2, h3,
h4, h5, h6 { page-break-after: avoid }
ul, ol, dl { page-break-before: avoid }
}
Some of those default styles seem obvious â block elements should have block display, table elements need table displays, and list elements need list displays. Headings get larger, bolder text. But other default styles seem pretty arbitrary. About a third of the way down, we find this one:
body { margin: 8px; }
It makes some sense to me
that we would want some default spacing
around the edges of our document,
but why 8px
?
Where did that come from?
Nothing ever goes away completely
The default style sheet isnât only there to ensure consistency between browsers, but also to ensure consistency across time. The entire web is designed to be forwards-and-backwards compatible. That doesnât mean the web is static â weâre getting new features all the time â but it means those new features should never break existing websites.
On rare occasions
a browser will decide to break existing sites
if there are privacy or security issues.
But we do everything we can
to avoid those situations.
And often,
browsers will choose to âdeprecateâ
a feature (like the old marquee
element)
without actually removing support.
Browser default styles follow a similar pattern. Since CSS was first implemented in browsers, there have been default browser styles. And, while browsers add new defaults on occasion, itâs very uncommon to remove an old default. Thereâs too much potential to break sites that relied on the default when they were made.
Many of the default styles we have in browsers today are the same defaults that existed back when an HTML element was first introduced.
Purity vs reality in specification
Thereâs another rule that impacts the development of standards â even non-normative standards (not officially ârequiredâ for conformance) like the default style sheet:
A standard is meaningless unless it describes reality.
To be successful, a standard has to be both prescriptive (telling browsers what to implement), and also retroactively descriptive (describing what browsers actually implemented). Itâs not helpful to have a specification that is theoretically perfect, if it doesnât accurately describe the web.
While we often write new standards to explain how a new feature should work, and then expect browsers to implement the feature as specified, thatâs only the first step in a more complicated back-and-forth process. We also regularly revisit and revise existing standards to reflect how features actually work, after they have been implemented.
Ideally, when an implementation doesnât match the spec, we want to consider that a browser issue, and fix the browser. But sometimes â depending how big the change, how many browsers would need to change, and how many sites would be impacted â weâll update the specification instead.
Thatâs not the only way we end up with mistakes in the design of CSS, but it makes mistakes harder to fix when they do show up.
Again, weâre prioritizing consistency across browsers and time, over theoretical purity of the standards themselves.
A margin on all our bodies
Last month I decided to track down the origins of this style:
body { margin: 8px }
I knew it was part of the default style sheet, and I assumed it would be a legacy style â initially provided by one of the early browsers, and eventually standardized for the sake of web-and-browser consistency.
But where did it come from originally? I decided to ask twitter, and eventually we were able to (mostly) track it down.
Step 1: The specification
Alan Stearns
(one of the current CSSWG chairs)
pointed me to
the first specification with 8px
margin
in the default style sheet:
Spec-wise, it first showed up in 2003 https://w3.org/TR/2003/WD-CSS21-20030128/sample.html. The version from the previous year had padding: 8px
â@alanstearns, June 17 @ 8:34pm
Whoops, off by one. The 2003 had padding. 2004 changed to margin https://w3.org/TR/2004/CR-CSS21-20040225/sample.html
â@alanstearns, June 17 @ 9:26pm
The change from padding to margin is interesting. But I figure these spec style sheets were likely describing some prior browser reality â not inventing the style from scratch?
Step 2: The original browsers
There are several links that I revisit on occasion, when Iâm curious about the early history of CSS. My favorite are the source documents themselves:
- Cascading HTML style sheets â a proposal by HĂ„kon Lie (the proposal that became CSS)
- Historical Style Sheet proposals
But there are also great articles that tell the story of how CSS came to be:
- A brief history of CSS until 2016 by Bert Bos (co-author of the original CSS spec)
- A Look Back at the History of CSS by Jay Hoffmann on CSS-Tricks
- The Languages Which Almost Became CSS by Zack Bloom
All of these are excellent, and I highly recommend reading through them to understand why this language works the way it does.
That got me a list of the first browsers with CSS, but it didnât give me any more detail on the body margin question:
For context, IE3 was the first commercial browser with CSS. Thatâs 1996. Then Netscape 4 added some support. Before either of those, CSS was being tested in Argo & Arena⊠How far back does it go???
https://www.w3.org/Style/CSS20/history.html
â@TerribleMia, June 17 @ 9:52pm
Step 3: The www-talk & www-style archives
Of course,
most of those âhistoric style proposalsâ
were originally written as emails
to the
www-talk@w3.org
mailing list,
or (later) the more focussed
www-style@w3.org
list â
both of which are well-archived,
and searchable.
(One advantage of having a medium created by a bunch of information-science nerds.)
Searching the archives lead me to an email from Todd Fahrner in March of 1998 â Re: IE, NN and background-position: thpppt!
My most recent revision to the âBase Stylesheetâ[1] has the body margin set to 0 and the padding set at 8 pixels. Previously I had the margin at 8 pixels, 0 padding, and the background-position set to -8px.
âŠ
[1] http://www.verso.com/agitprop/corestyle/base.html
Itâs an email thread about the proper handling of background-images, so not exactly on topic, but thereâs our 8px padding-or-margin on the body.
Step 4: The wayback machine
That reference link is broken, so I jumped over to The WayBack Machine to see if there was an archived copy â and there are several!
First, I landed on The Base Stylesheet - February 22, 1999, which claims it was last modified 7 November 1998. Then I clicked through to the earliest archive of the page â The Base Stylesheet - January 30, 1998 â which says it was last modified 07/04/2022 16:39:51 GMT (the exact moment I loaded the page).
Wait, what? Inspecting the source code, I found this:
<p>
This is a work in progress, last modified
<script>document.write(document.lastModified);</script>
<noscript>quite recently</noscript> GMT...
</p>
I assume the document.lastModified
is getting updated
by The WayBack Machine
every time we load the page?
Final answer: the base stylesheet
This is what weâve been looking for: the original default style sheet, still under development. There are a few quotes that stand out:
The Base Stylesheet describes the âconsensus defaultâ rendering of all HTML 4.0 elements in Mosaic-derivative Web browsers (Netscape Navigator and Microsoft Internet Explorer). It ⊠captures the status quo in order to move beyond it.
Those are the major browser-engines at the time, and they both trace their roots back to the previous Mosaic browser.
The Mosaic browserâs allegedly âneutralâ default stylesheet is a simple adaptation of the normative style for (printed) scientific writings in Europe (cf. Wanning, Frank; Internationaler Typographie und wissenschaftliche Textverarbeitung; Haag + Herchen, 1996). This is appropriate enough considering the Webâs origins at CERN. In view of the Webâs far more common applications in commerce, entertainment, journalism, and the humanities, however, and the deeply entrenched market dominance of Mosaic-based browsers, it is fair to say that âcorrectâ HTML has been infected with a reliably inappropriate style, like a cancer or virus.
The escape of the Mosaic Browser Default Stylesheet (MBDS) virus from the scientific community at CERN has produced Web generations of mutant tools and authors who misapply markup solely to invoke certain MBDS effects. The use of
<p>
to produce vertical whitespace and table structures for nontabular information are signature examples. The high reliability of such manipulation accounts for HTMLâs grotesque cannibalization beyond academia, and the market success of architecturally incongruous HTML extensions for symptomatic relief. To reverse this epidemic, it is necessary first to isolate the virus, and expose its genes to precise and comprehensive manipulation. The Base Stylesheet is a CSS1 model of the MBDS virus, and the first step toward the development of âstyle antibodiesâ - comprehensive alternative stylesheets for HTML.
Lol, the snark.
So there you have it.
This style sheet is meant to capture
what was already happening before CSS existed
in Mosaic-based browsers,
and recreate those styles in CSS.
The 8px
spacing on the body predates CSS!
The style likely comes directly from Mosaicâs internal rules,
before CSS was invented,
so the only remaining question is
how to represent it â
as either padding
or eventually a margin
.
Todd Fahrner’s (early draft) Base Stylesheet
A, ABBR, ACRONYM, ADDRESS, BDO, BLOCKQUOTE, BODY, BUTTON, CITE, CODE, DD, DEL,
DFN, DIV, DL, DT, EM, FIELDSET, FORM, H1, H2, H3, H4, H5, H6, HTML, IFRAME, IMG, INS,
KBD, LABEL, LI, OBJECT, OL, P, Q, SAMP, SPAN, STRONG, SUB, SUP, UL, VAR,
APPLET, B, BIG, CENTER, DIR, FONT, HR, I, MENU, PRE, S, SMALL, STRIKE, TT, U {
background: transparent;
width: auto;
height: auto;
text-decoration: none;
margin: 0;
padding: 0;
border: 0;
float: none;
clear: none;
vertical-align: baseline;
list-style-image: none;
list-style-type: disc;
list-style-position: outside;
}
ADDRESS, BLOCKQUOTE, BODY, DD, DIV, DL, DT, FIELDSET, FORM, H1, H2, H3, H4, H5,
H6, OL, P, UL, CENTER, DIR, HR, MENU, PRE {
display: block;
}
A, ABBR, ACRONYM, APPLET, BDO, BUTTON, CITE, CODE, DEL, DFN, EM, IFRAME, IMG,
INS, KBD, LABEL, OBJECT, Q,
SAMP, SPAN, STRONG, SUB, SUP, VAR, B, BIG, FONT, I, S, SMALL, STRIKE, TT, U {
display: inline;
}
LI {
display: list-item;
}
/* Begin tree of inherited properties and cascades. */
/* Describes the default type, color, and link decoration specs of
Mosaic-derivative browsers to the extent and degree of granularity that users
may typically override. Uncomment for "factory settings."
HTML {
font-family: "Times New Roman", Times;
font-size: medium;
color: black;
background-color: #BFBFBF;
}
PRE, TT, CODE, KBD, SAMP {
font-family: "Courier New", Courier;
}
A:link, A:visited, A:active {
text-decoration: underline;
}
A:link {
color: #0000FF;
}
A:visited {
color: #7F007F;
}
A:active {
color: #0000FF;
}
end pre-CSS user settings */
HTML {
line-height: 1.12;
word-spacing: normal;
letter-spacing: normal;
text-transform: none;
text-align: left;
text-indent: 0;
white-space: normal;
}
BODY {
padding: 8px;
}
H1 {
font-size: xx-large;
margin: .67em 0;
}
H2 {
font-size: x-large;
margin: .75em 0;
}
H3 {
font-size: large;
margin: .83em 0;
}
H4, P, BLOCKQUOTE, FIELDSET, FORM, UL, OL, DL, DIR, MENU {
margin: 1.12em 0;
}
H5 {
font-size: small;
margin: 1.5em 0;
}
H6 {
font-size: x-small;
margin: 1.67em 0;
}
H1, H2, H3, H4, H5, H6, B, STRONG {
font-weight: bolder;
}
BLOCKQUOTE {
margin-left: 40px;
margin-right: 40px;
}
I, CITE, EM, VAR, ADDRESS {
font-style: italic;
}
PRE, TT, CODE, KBD, SAMP {
font-family: monospace;
}
PRE {
white-space: pre;
}
BIG {
font-size: larger;
}
SMALL, SUB, SUP {
font-size: smaller;
}
SUB {
vertical-align: sub;
}
SUP {
vertical-align: super;
}
S, STRIKE, DEL {
text-decoration: line-through;
}
HR {
border: 1px inset; /* questionable */
}
OL, UL, DIR, MENU, DD {
padding-left: 40px;
}
OL LI {
list-style-type: decimal;
}
UL LI {
list-style-type: disc;
}
UL UL, UL OL, UL MENU, UL DIR, MENU UL, MENU OL, MENU MENU, MENU DIR, DIR UL,
DIR OL, DIR MENU, DIR DIR, OL UL, OL OL, OL MENU, OL DIR {
margin-top: 0;
margin-bottom: 0;
}
OL UL, UL UL, MENU UL, DIR UL, OL MENU, UL MENU, MENU MENU, DIR MENU, OL DIR, UL
DIR, MENU DIR, DIR DIR {
list-style-type: circle;
}
OL OL UL, OL UL UL, OL MENU UL, OL DIR UL, OL OL MENU, OL UL MENU, OL MENU MENU,
OL DIR MENU, OL OL DIR, OL UL DIR, OL MENU DIR, OL DIR DIR, UL OL UL, UL UL UL,
UL MENU UL, UL DIR UL, UL OL MENU, UL UL MENU, UL MENU MENU, UL DIR MENU, UL OL
DIR, UL UL DIR, UL MENU DIR, UL DIR DIR, MENU OL UL, MENU UL UL, MENU MENU UL,
MENU DIR UL, MENU OL MENU, MENU UL MENU, MENU MENU MENU, MENU DIR MENU, MENU OL
DIR, MENU UL DIR, MENU MENU DIR, MENU DIR DIR, DIR OL UL, DIR UL UL, DIR MENU
UL, DIR DIR UL, DIR OL MENU, DIR UL MENU, DIR MENU MENU, DIR DIR MENU, DIR OL
DIR, DIR UL DIR, DIR MENU DIR, DIR DIR DIR {
list-style-type: square;
}
U, INS {
text-decoration: underline;
}
CENTER {
text-align: center;
}
CAPTION, COL, COLGROUP, LEGEND, TABLE, TBODY, TD, TFOOT, TH, THEAD, TR {
background: transparent;
text-decoration: none;
margin: 1px;
padding: 1px;
border: none;
float: none;
clear: none;
}
TABLE, TBODY, TFOOT, THEAD, TR {
display: block;
background-position: top left;
width: auto;
height: auto;
}
CAPTION, LEGEND, TD, TH {
display: inline;
vertical-align: baseline;
font-size: 1em;
line-height: 1.33em;
color: black;
word-spacing: normal;
letter-spacing: normal;
text-transform: none;
text-align: left;
text-indent: 0;
white-space: normal;
}
TH {
font-weight: bolder;
text-align: center;
}
CAPTION {
text-align: center;
}
/* not part of the legacy browser default sheet, but an obvious enhancement */
OL OL LI {
list-style-type: lower-alpha;
}
OL OL OL LI {
list-style-type: lower-roman
}
A remedy for the MBDS virus?
The plan didnât work out exactly the way Todd Fahrner imagined. That base style sheet lives on, with a number of Mosaic-based styles intact. There are no comprehensive alternative stylesheets for HTML â at least not from the w3c or the browser vendors. Both are too invested in backwards-compatibility to make any radical changes to the default styles of the web.
If itâs going to happen, it will have to come from web authors who can choose to opt-in to a new stylesheet, without worrying about backwards compatibility. To some extent, you can think of various resets and normalizers as attempts at a new comprehensive stylesheet â tho resets generally remove too much (relying on authors to put it all back), and normalizers often worry more about browser-consistency more than improved styles.
This is what lead Jen Simmons to create CSS Remedy. (Iâm one of the core contributors, though there hasnât been much work on it recently). The goal is to re-imagine a âdefaultâ stylesheet for the modern web. What would we come up with now, if we werenât constrained by what Mosaic did almost 30 years ago? Thereâs still a lot of discussion, but one thing is clear on line 47 of the main remedy stylesheet:
body { margin: 0; }
For the most part, CSS Remedy isnât trying to make things pretty â just trying to provide a better default. There are also projects that take a more opinionated approach, providing fully-designed styles for basic HTML elements.
Last month, Robin Rendle posted some thoughts on The Smallest CSS â Whatâs the smallest amount of CSS that you can write to make HTML look halfway decent? Itâs a great little exploration, landing on about 15 lines of CSS.
I also appreciate the âno-class frameworksâ â based entirely on writing semantic html, without any need for special selectors. Here are some more classless CSS libraries to look at.
Iâm tempted to try something like that myself. Weâll see. Maybe this site is almost due for a refresh.