Every HTML page has a stacking context at the root element (html
tag).
In the following example the html
tag is the (only) stacking context
html {
background-color: gray;
}
body {
background: #222;
color: white;
box-sizing: border-box;
}
.box {
width: 200px;
height: 200px;
background-color: blue;
position: relative;
}
.box:before {
content: "";
background-color: tomato;
position: absolute;
z-index: -1;
inset: 0;
margin: -5px;
}
<h1>Header</h1>
<div ></div>
The pseudo element (tomato color) is drawn behind the body background (#222) because it has a z-index
< 0
If we remove the html
tag background color:
body {
background: #222;
color: white;
box-sizing: border-box;
}
.box {
width: 200px;
height: 200px;
background-color: blue;
position: relative;
}
.box:before {
content: "";
background-color: tomato;
position: absolute;
z-index: -1;
inset: 0;
margin: -5px;
}
<h1>Header</h1>
<div ></div>
Now the pseudo element (tomato color) is drawn after the body background (#222). That means that the body
tag now creates a stacking context.
There are a few rules that determine if an element creates a stacking context. None of the rules explain why the body
tag is now the root of a stacking context.
A similar question on SO explains, from the specs, that the canvas uses the body
background color/image if the html
tag has none. This is possibly to match the early days of HTML when this info was set with the bgcolor
and background
attributes of the body
tag.
The question is: which part of the CSS specification is the reason of the body
tag creating a stacking context depended on the html background color?
CodePudding user response:
First time answering a question here, but I think this has something to do with how the background color of the body is set. The first image is with the HTML tag stylized with a background color, the body has opacity reduced to 80% for better context. the second image is with the HTML background color removed, I was looking at it using dev tools. It looks like when you apply a background color to the body without applying a background color to the HTML tag that it just sets the specified color to root. I was unable to select the .box:before (tomato-colored div) by mousing over the portion inside the body while using dev tools. I've attached some pictures for reference. Sorry if I seem a bit all over the place! Hope I helped.
The comment left by Alohci cleared up what I had only attempted to get at! Reference the W3 link for info on the canvas' relation to special elements.
https://www.w3.org/TR/css-backgrounds-3/#special-backgrounds
HTML bg color set HTML no bg color
CodePudding user response:
If we add a border to the body element, we can see that it is not in fact creating a stacking context. If the body element did create a stacking context, then the box would be painted over the border. But that doesn't happen: the border is painted over the box.
body {
background: #222;
color: white;
box-sizing: border-box;
border:3px solid yellow;
}
.box {
width: 200px;
height: 200px;
background-color: blue;
position: relative;
}
.box:before {
content: "";
background-color: tomato;
position: absolute;
z-index: -1;
inset: 0;
margin: -5px;
}
<h1>Header</h1>
<div ></div>
In contrast, if we force the body to create a stacking context - in the example below I've used scale: 1
to do that - we can see that now the box is indeed painted over the body's border.
body {
background: #222;
color: white;
box-sizing: border-box;
border:3px solid yellow;
scale: 1;
}
.box {
width: 200px;
height: 200px;
background-color: blue;
position: relative;
}
.box:before {
content: "";
background-color: tomato;
position: absolute;
z-index: -1;
inset: 0;
margin: -5px;
}
<h1>Header</h1>
<div ></div>
So we can be sure that the propagation of the body background to the canvas is not causing the body to create a stacking context - it's merely having a similar outcome when the body has no border.