Extend background gradient across body without background-attachment: fixed

background-image, css, html, linear-gradients

Solution

This happens because of the way gradient backgrounds are sized according to their containers (this includes both `html` and `body`), as well as the calculations used in determining the dimensions of `html` and `body` respective to the viewport.

I've actually written about something similar before in an answer to another question. Yours is a little different, so I'll quote the relevant portion first:

Backgrounds have special behavior when applied to `body` and/or `html`. When you apply a background to `body` without touching `html`, what happens is that the body background gets propagated to the viewport, and that background acts as if it were declared on `html`:

For documents whose root element is an HTML `HTML` element or an XHTML `html` element: 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. The used values of that `BODY` element's background properties are their initial values, and the propagated values are treated as if they were specified on the root element.

In your case, if the template that you're using doesn't specify any backgrounds for `html` or `body`, then this background propagating behavior is what causes the gradient to take the height of `html` instead of `body`.

To fix this you need to reset the `height` value for the `html` element only, and assign `min-height` instead:

  html {
     height: auto;
     min-height: 100%;
  }

This removes the height constraint on the `html` element, allowing the gradient to stretch along with the contents of your page, while keeping it at least as tall as the viewport if the page doesn't have enough content (if that's not important, you don't need to set `min-height`).

Problem

I want to have a background gradient, e.g. ``` background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(2, 126, 174, 0.9)) ``` on the body of my document which extends across the entire height of the body - and scrolls with the body. Using ``` background-attachment: fixed; ``` I get the entire height (of the viewport), but it, well, stays fixed. ``` background-attachment: scroll; ``` gets me the scrolling, but then it just extends across the viewport height. Any way to get both? Edit: As Boltclock pointed out, I do get the expected behavior with 'background-attachment: scroll' on a basic test page. With ``` <body> <div id="stretch">Content</div> </body> ``` and ``` body { background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(2, 126, 174, 0.9)); } #stretch { height: 2000px; } ``` everything works fine: The gradient extends across the entire body (and the body is 2000px tall), and scrolls with the content. Then I add ``` html, body { height: 100%; } ``` This is something which the basic template the page is based on does. In order to get the body to expand again, I add ``` height: auto; ``` and the body is back to 2000px height. However, the gradient remains at the HTML height - and repeats then. What am I missing here?

Original source

Related problems