451
votes

ok say the content inside the <body> totals 300px high.

If I set the background of my <body> using -webkit-gradient or -moz-linear-gradient

Then I maximize my window (or just make it taller than 300px) the gradient will be exactly 300px tall (the height of the content) and just repeat to fill the rest of the window.

I am assuming this is not a bug since it is the same in both webkit and gecko.

But is there a way to make the gradient stretch to fill the window instead of repeat?

13

13 Answers

757
votes

Apply the following CSS:

html {
    height: 100%;
}
body {
    height: 100%;
    margin: 0;
    background-repeat: no-repeat;
    background-attachment: fixed;
}

Edit: Added margin: 0; to body declaration per comments (Martin).

Edit: Added background-attachment: fixed; to body declaration per comments (Johe Green).

171
votes

Regarding a previous answer, setting html and body to height: 100% doesn't seem to work if the content needs to scroll. Adding fixed to the background seems to fix that - no need for height: 100%;

E.g.:

body {
  background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#cbccc8)) fixed;
}
26
votes

I know I'm late to the party, but here's a more solid answer.

All you need to do is use min-height: 100%; rather than height: 100%; and your gradient background will extend the entire height of the viewport without repeating, even if the content is scrollable.

Like this:

html {
    min-height: 100%;
}

body {
    background: linear-gradient(#ff7241, #ff4a1f);
}
15
votes

Here's what I did to solve this problem... it will show the gradient for the full length of the content, then simply fallback to the background color (normally the last color in the gradient).

   html {
     background: #cbccc8;
   }
   body {
     background-repeat: no-repeat;
     background: #cbccc8;
     background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#cbccc8));
     background: -moz-linear-gradient(top, #fff, #cbccc8);
     filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#cbccc8');
   }
<body>
  <h1>Hello world!</h1>
</body>

I've tested this in FireFox 3.6, Safari 4, and Chrome, I keep the background-color in the body for any browsers that for some reason don't support styling the HTML tag.

14
votes

Setting html { height: 100%} can wreak havoc with IE. Here's an example (png). But you know what works great? Just set your background on the <html> tag.

html {
  -moz-linear-gradient(top, #fff, #000);
  /* etc. */
}

Background extends to the bottom and no weird scrolling behavior occurs. You can skip all of the other fixes. And this is broadly supported. I haven't found a browser that doesn't let you apply a background to the html tag. It's perfectly valid CSS and has been for a while. :)

12
votes

There is a lot of partial information on this page, but not a complete one. Here is what I do:

  1. Create a gradient here: http://www.colorzilla.com/gradient-editor/
  2. Set gradient on HTML instead of BODY.
  3. Fix the background on HTML with "background-attachment: fixed;"
  4. Turn off the top and bottom margins on BODY
  5. (optional) I usually create a <DIV id='container'> that I put all of my content in

Here is an example:

html {  
  background: #a9e4f7; /* Old browsers */
  background: -moz-linear-gradient(-45deg,  #a9e4f7 0%, #0fb4e7 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,#a9e4f7), color-stop(100%,#0fb4e7)); /* Chrome,Safari4+ */ 
  background: -webkit-linear-gradient(-45deg,  #a9e4f7 0%,#0fb4e7 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(-45deg,  #a9e4f7 0%,#0fb4e7 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(-45deg,  #a9e4f7 0%,#0fb4e7 100%); /* IE10+ */
  background: linear-gradient(135deg,  #a9e4f7 0%,#0fb4e7 100%); /* W3C */ 
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a9e4f7', endColorstr='#0fb4e7',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */

  background-attachment: fixed;
}

body {
  margin-top: 0px;
  margin-bottom: 0px;
}

/* OPTIONAL: div to store content.  Many of these attributes should be changed to suit your needs */
#container
{
  width: 800px;
  margin: auto;
  background-color: white;
  border: 1px solid gray;
  border-top: none;
  border-bottom: none;
  box-shadow: 3px 0px 20px #333;
  padding: 10px;
}

This has been tested with IE, Chrome, and Firefox on pages of various sizes and scrolling needs.

4
votes

Dirty; maybe could you just add a min-height: 100%; to the html, and body tags? That or at least set a default background color that is the end gradient color as well.

2
votes

I had trouble getting the answers in here to work.
I found it worked better to fix a full-size div in the body, give it a negative z-index, and attach the gradient to it.

<style>

  .fixed-background {
    position:fixed;
    margin-left: auto;
    margin-right: auto;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: -1000;
    background-position: top center;
    background-size: cover;
    background-repeat: no-repeat;
  }

  .blue-gradient-bg {
    background: #134659; /* For browsers that do not support gradients */
    background: -webkit-linear-gradient(top, #134659 , #2b7692); /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(bottom, #134659, #2b7692); /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(top, #134659, #2b7692); /* For Firefox 3.6 to 15 */
    background: linear-gradient(to bottom, #134659 , #2b7692); /* Standard syntax */
  }

  body{
    margin: 0;
  }

</style>

<body >
 <div class="fixed-background blue-gradient-bg"></div>
</body>

Here's a full sample https://gist.github.com/morefromalan/8a4f6db5ce43b5240a6ddab611afdc55

0
votes

I have used this CSS code and it worked for me:

html {
  height: 100%;
}
body {
  background: #f6cb4a; /* Old browsers */
  background: -moz-linear-gradient(top, #f2b600 0%, #f6cb4a 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2b600), color-stop(100%,#f6cb4a)); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* IE10+ */
  background: linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2b600', endColorstr='#f6cb4a',GradientType=0 ); /* IE6-9 */
  height: 100%;
  background-repeat: no-repeat;
  background-attachment: fixed;
  width: 100%;
  background-position: 0px 0px;
}

A related information is that you can create your own great gradients at http://www.colorzilla.com/gradient-editor/

/Sten

0
votes

Adding a space and the word fixed to the end should be sufficient. No need to set heights.

body{
    background: linear-gradient(#e4efe9,#93a5cf) fixed;
}
-1
votes
background: #13486d; /* for non-css3 browsers */
background-image: -webkit-gradient(linear, left top, left bottom, from(#9dc3c3),   to(#13486d));  background: -moz-linear-gradient(top,  #9dc3c3,  #13486d);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#9dc3c3', endColorstr='#13486d');
background-repeat:no-repeat;
-1
votes

this is what I did:

html, body {
height:100%;
background: #014298 ;
}
body {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#5c9cf2), color-stop(100%,#014298));
background: -moz-linear-gradient(top, rgba(92,156,242,1) 0%, rgba(1,66,152,1) 100%);
background: -o-linear-gradient(top, #5c9cf2 0%,#014298 100%);

/*I added these codes*/
margin:0;
float:left;
position:relative;
width:100%;
}

before I floated the body, there was a gap on top, and it was showing the background color of html. if I remove the bgcolor of html, when I scroll down, the gradient is cut. so I floated the body and set it's position to relative and the width to 100%. it worked on safari, chrome, firefox, opera, internet expl.. oh wait. :P

what do you guys think?

-4
votes

instead of 100% i just add some pixxel got this now and it works for whole page without gap:

html {     
height: 1420px; } 
body {     
height: 1400px;     
margin: 0;     
background-repeat: no-repeat; }