-1

I apply styles to the <html> element and to the <body> element. Is it possible to have the styles on the <html> element apply over the <body's styles?

Applying CSS to <html> doesn't seem to follow the usual rules of CSS specificity. Is this true?

Example: http://jsfiddle.net/59dpy/

Try to make all background colors red.

Don P
  • 60,113
  • 114
  • 300
  • 432
  • 2
    I don't see the problem in your example. You set the body's background color to yellow. It's now yellow. You might not realise it, but the yellow portion _is_ the body element - in browsers like Chrome and Firefox, it has padding, and the red part around it is the HTML element. Additionally, [the default value of the `background-color` css style is `transparent`, not `inherit`](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color). – doppelgreener Jun 24 '13 at 22:38
  • Your example looks to working correctly to me in chrome – Turnip Jun 24 '13 at 22:39
  • @JonathanHobbs - the CSS styling applied to the HTML element is more specific than the body element, and should therefore be applied. You would expect to see only red. There should be no yellow on the page. – Don P Jun 24 '13 at 22:39
  • 1
    Did you expect ``'s style to override styles you gave directly to ``...? CSS doesn't work like that... – jeremy Jun 24 '13 at 22:40
  • If you do html * { ... } you will hit all elements within the html tag (all). In CSS, the last rule also takes precedence. You could set the html tag last if you wish for something uncovered. You may also need to specific inheritance. EG: color: inherit; – h4xnoodle Jun 24 '13 at 22:40
  • 2
    @DonnyP That's not how it works... the more specific rule applies _for the specific element_. Not necessarily for its children: you have _explicitly_ overwritten that style in the body tag. – doppelgreener Jun 24 '13 at 22:42
  • 2
    Setting an elements background color doesn't also set the background of its child elements – Turnip Jun 24 '13 at 22:42

3 Answers3

2

If you want all of the background red, why add a yellow background to the body? In any case, you just need something more specific.

.test2 { background: red; }  

is all you would really need.

Justin King
  • 196
  • 1
  • 5
2

Calculating Specificity

The actual specificity of a group of nested selectors takes some calculating. Basically, you give every ID selector (“#whatever”) a value of 100, every class selector (“.whatever”) a value of 10 and every HTML selector (“whatever”) a value of 1. Then you add them all up and hey presto, you have the specificity value.

p has a specificity of 1 (1 HTML selector)

div p has a specificity of 2 (2 HTML selectors, 1+1)

.tree has a specificity of 10 (1 class selector)

div p.tree has a specificity of 12 (2 HTML selectors + a class selector, 1+1+10)

#baobab has a specificity of 100 (1 id selector)

body #content .alternative p has a specificity of 112 (HTML selector + id selector + class selector + HTML selector, 1+100+10+1)

So if all of these examples were used, div p.tree (with a specificity of 12) would win out over div p (with a specificity of 2) and body #content .alternative p would win out over all of them, regardless of the order.

Specificity - CSS | MDN

lloan
  • 1,383
  • 8
  • 23
  • From the asker's example, `html.test` has a specificity of 11, and `body` a specificity of 1, so by that alone, HTML would win out (as the asker thought). It's probably worth addressing that confusion whilst you're explaining this. – doppelgreener Jun 24 '13 at 22:58
  • My point is that HTML _doesn't_ win out, because the style targeting the body tag doesn't really care what styles were competing on its parent. :) The asker's confused about that. Specificity isn't the only factor at play here. – doppelgreener Jun 24 '13 at 23:01
  • 1
    Your explanation is the complete opposite of what the OPs example shows to be the case. – Turnip Jun 24 '13 at 23:07
1

I apply styles to the <html> element and to the <body> element. Is it possible to have the styles on the <html> element apply over the <body>'s styles?

Apply over the body's styles? Not really. In your question, you appear to be confused about CSS's specificity: this defines how different styles compete over the same element when they clash, with the more specific and last defined style winning out.

If html tries to set the background to blue, and html.test tries to set the background to red, the background will be red as that's more specific.

This doesn't apply to child elements

It does not mean those rules then override the childrens' styles. You seem to think that because html.test is more specific a selector than body, the html.test style should also override the body style. That's not the case!

Cascading style sheets don't work that way. Styles only cascade down wherever inheritance applies until a child element overrides that style. The child's style will always win out over its parent's style, and then that will cascade down to its child elements if it's an inherited style (until, again, one of those children overrides it).

Specificity says that out of any competing styles, the most specific one that could apply to the html element wins out. In your provided jsFiddle, there aren't any competing styles, and the html element is now red.

That's it; specificity has no more role to play here. Your body element is then given a background color of yellow. Background colors are not inherited by default, but even if they were, body would not ever inherit its parent's background because you assigned one to it specifically.

You need to apply your styles to the body specifically

In this scenario, you need to either make the body just inherit the html element's style:

body { background-color: inherit; }

Or not give the body a style in the first place.

Or you need to set a specific rule for when the html element has the test class applied:

html.test {
    background-color: red;
}
body {
    background-color: yellow;
}
html.test > body {
    /* Don't have a background color when the HTML should have one
    so that the HTML's background can show through. */
    background-color: transparent;
}
doppelgreener
  • 4,809
  • 10
  • 46
  • 63