It actually works, but there is a tricky place in css. html gets background of body if it is unset on html itself and viewport is filled by background of html (that's the only inheritance from child in css).
This behavior is specified in CSS Backgrounds and Borders Module Level 3:
The document canvas is the infinite surface over which the document is rendered. [CSS2] Since no element corresponds to the canvas, in order to allow styling of the canvas CSS propagates the background of the root element
For documents whose root element is an HTML HTML element or an XHTML html element [HTML]: if the computed value of background-image on the root element is none and its background-color is transparent, user agents must instead propagate the computed values of the background properties from that element’s first HTML BODY or XHTML body child element.
I've added background to html into your example and you can see, it's fine:
html, body {
font-size: 16px;
width: 70vw;
height: 40vh;
background-color: yellow;
}
html {
background: white;
}
h1 {
background-color: red;
}
<h1>My First Heading</h1>
The other thing I can do is outline - it'll show where elements actually end:
html, body {
font-size: 16px;
width: 70vw;
height: 40vh;
background-color: yellow;
outline: 1px dotted blue;
outline-offset: -1px;
}
h1 {
background-color: red;
}
<h1>My First Heading</h1>
One more interesting case:
html {
width: 50vw;
height: 50vh;
}
body {
margin: 40vh 0 0 40vw;
width: 30vw;
height: 30vh;
background: linear-gradient(45deg, red, blue);
}
html, body {
border: 8px solid;
}