Should global css styles be set on the html element or the body element?
Sometimes I see people apply global css styles to html
, sometimes I see them apply them to body
, with both raw css and javascript.
Are there any differences between the two? Which is the standard to make a global css style? Is there anything I should know when picking between them?
Solution 1:
I'm assuming that "global page styling" here refers to things such as fonts, colors and backgrounds.
Personally, I apply global page styling, for the most part, to body
and the simple element selectors (p
, h1, h2, h3...
, input
, img
, etc). These elements are more closely related to the presentation of content of an HTML page to the user.
My rationale for this is simple: the presentational attributes bgcolor
, background
, text
, topmargin
, leftmargin
and others were given to the body
element, not the html
element. These attributes are now converted to their respective CSS rules with extremely low precedence in the cascade:
The UA may choose to honor presentational attributes in an HTML source document. If so, these attributes are translated to the corresponding CSS rules with specificity equal to 0, and are treated as if they were inserted at the start of the author style sheet.
Most if not all implementations I'm aware of will convert these to CSS rules on body
, based on their HTML equivalents. Others such as link
, alink
and vlink
will become a:link
, a:active
and a:visited
rules respectively.
Of course, it should be noted that CSS itself doesn't really have any semantics to it per se, as it's a styling language in itself which is completely separate from the content structure of an HTML document. Although the introduction to CSS2.1 covers the basics of styling an HTML document, note that the section calls itself non-normative (or informative); this means it doesn't set any hard and fast rules for CSS implementers to follow. Instead, it simply provides information for readers.
That said, certain styles may be applied to html
to modify viewport behavior. For example, to hide the page scrollbars use:
html {
overflow: hidden;
}
You can also apply rules to both html
and body
for interesting effects; see the following questions for details and examples:
- What's the difference in applying CSS to html, body, and *?
- Applying a background to <html> and/or <body>
Note that html
is not the viewport; the viewport establishes an initial containing block in which html
is situated. That initial containing block cannot be targeted with CSS, because in HTML, the root element is html
.
Note also that, technically, there is no difference between applying properties to html
and body
that are inherited by default, such as font-family
and color
.
Last but not least, here is an excellent article that details the differences between html
and body
in terms of CSS. In summary (quoted from its first section):
- The
html
andbody
elements are distinct block-level entities, in a parent/child relationship.- The
html
element's height and width are controlled by the browser window.- It is the
html
element which has (by default)overflow:auto
, causing scrollbars to appear when needed.- The body element is (by default)
position:static
, which means that positioned children of it are positioned relative to thehtml
element's coordinate system.- In almost all modern browsers, the built-in offset from the edge of the page is applied through a
margin
on thebody
element, notpadding
on thehtml
element.
As the root element, html
is more closely associated with the browser viewport than body
(which is why it says html
has overflow: auto
for scrollbars). Note however that the scrollbars are not necessarily generated by the html
element itself. By default, it's the viewport that generates these scrollbars; the values of overflow
are simply transferred (or propagated) between body
, html
, and the viewport, depending on which values you set. The details of all this are covered in the CSS2.1 spec, which says:
UAs must apply the 'overflow' property set on the root element to the viewport. When the root element is an HTML "HTML" element or an XHTML "html" element, and that element has an HTML "BODY" element or an XHTML "body" element as a child, user agents must instead apply the 'overflow' property from the first such child element to the viewport, if the value on the root element is 'visible'. The 'visible' value when used for the viewport must be interpreted as 'auto'. The element from which the value is propagated must have a used value for 'overflow' of 'visible'.
The last bullet point probably has its roots in the aforementioned topmargin
and leftmargin
attributes of the body
element.
Solution 2:
If you want to style only the content that'll be displayed, targeting the <body>
element saves the style rules an unnecessary level of cascading.
Is there a reason you'd want to apply styles to the <title>
, <meta>
, <script>
etc... tags? That would happen by targeting <html>
.