Extra scrollbar when body height is 100vh

Here’s what I did to set a background on the web page:

body {
  height: 100vh;
  background: linear-gradient(white, tan);
}

<h1>Heading</h1>
<p>Paragraph</p>

DEMO

Two questions:

  1. Is it the right approach to add a background to your page?
  2. How should I get rid of the unwanted scrollbar?

The extra height is coming from the default margins on the body and h1 elements.
Remember an element’s size is the size you may define, plus any margin. So the height is 100vh + default margins, that makes it taller than the screen.

As Sam said you need to do this:

html,body{margin:0;padding:0;}
h1,p{margin:0 0 1em}

The html/body elements have margin/padding depending on browser so you need to zero both.

The h1 on the page has a default top margin which collapses onto body and makes body 100% + 1em (or whatever the default is) so you get a scrollbar.

If you are just setting a background colour then you don’t need a height as background on the body element propagates automatically to the html element and as long as you haven’t set a height or background there either the background will cover the viewport and the document.

Sorry for the mistake! I meant to use a gradient background. Just updated my question.

If you want a linear gradient just on the viewport then you would need to fix the background otherwise the gradient will repeat or stretch with content.

background-attachment:fixed;

As a lot of mobiles don’t like fixed backgrounds you would be better of using this method which uses :after to place a fixed element instead and then a normal background can be used.

A question: why so much hassle finding all the elements on a page with default margins and zeroing them? Isn’t it much easier to simply change the selector:

DEMO

According to the spec:

It is recommended that authors of HTML documents specify the canvas background for the BODY element rather than the HTML element.

But does it really have any advantages?

P.S. Please let me know if my question is too broad and I need to open a new thread.

I’ve seen various CSS “resets”, ranging from a few, to many, to all elements. I’m not enough of a designer to care about things being “pixel perfect” and as long as the HTML is valid and (to the best of my abilities) semantic, I’m happy.

The logic behind using a CSS reset is because different browsers have different default values. Using a CSS reset is kind of an “equalizer” that can make getting things to be more cross-browser easier.

As far as the W3C “background, root, body” stuff, sorry, but when I read that I have a “I think I might, kind of, sort of, have a very dim idea of what that means”, but overall even after a few reads it’s still a big HUH? to me. Hopefully someone can explain it in layman’s terms.

You are misunderstanding what is happening which is not surprising as CSS is a stickler for details. The issue with the margins on the h1 is a collapsing margin issue and as you changed from body to the root element (html) the margin collapse does not happen because the root element does not allow margin collapse like other block formatting contexts.

If in your if demo you add this css:

body{background:blue}

You will see that the body no longer covers the viewport and only covers the content and has a gap at the side due to margins/padding. Using the html element as a background will cause you more issues than you expect and as I already mentioned earlier backgrounds applied to the body element will automatically propagate to the html element seamlessly. As you pointed out from the specs this is the preferred approach as you never know what root may refer to in the future. (Originally in old IE the root element was the body element and the html element was not the containing block.)

As a general rule you only need to use the html element to reset margins/padding and to set a 100% height if doing things like a sticky footer although for modern browsers we don’t need to do that now that we have vh units. You have to be careful with 100% settings because that effectively is a fixed height and backgrounds may get cut off if content is greater than the 100%.

The best solution for the linear gradient is the one i gave using fixed positions so it always fits the viewport.

It basically means that any background applied to the body element will automatically be propagated to the html (root) element as long as the html element has no background property already set. The body element actually has no height apart from its content so in theory applying a background to the body would only show as tall as the content which normally would not be what was required.

If you apply a background to the html then the body background no longer propagates and no longer fills the viewport. You can see that in a simple demo like this:

Some people use the html and body as two wrappers to get two backgrounds going but generally this is a bad approach due to the special nature of those elements and it is much safer to use the body as the main background and then just add a div for the next background if required. There is no right or wrong but just consequences depending on your approach.

4 Likes

Thanks for the comprehensive answer! :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.