htmlcssheightfixedstretching

One 100vh height div containg 3 divs, the 2nd of which should be the only one with variable height


I'm quite new to CSS3. I've read other questions but I'm not sure they cover my case, so please be patient :)

I have this example page:

<html>
 <head>
  <style type="text/css">
   body { background-color: black; margin: 0; }
   #main { background-color: red; width: 60%; height: 100vh; margin: auto; }
   #header { background-color: white; width: 100%; height: 25%; max-height: 100px; }
   #article { background-color: orange; width: 100%; height: 55%; }
   #footer { background-color: blue; width: 100%; height: 20%; max-height: 80px; }
  </style>
 </head>
 <body>
  <div id="main">
   <div id="header"></div>
   <div id="article"></div>
   <div id="footer"></div>
  </div>
 </body>
</html>

There's one additional mandatory behaviour I have to implement, plus an optional one.

The mandatory

As you can see yourself, once the browser window gets quite high, #header and #footer correctly stop to grow, leaving their height to the background red #main div. What I need is that #article gets this space, therefor always "pushing" the #footer to the lower border of the browser screen.

The optional

The layout itself resizes horizontally without any limit, but the #article div has setted a background image that does fade on its left and right sides. To be more precise, it's a 1000x1 image fading in from coords (1,1) to (100,1) and fading out from (901,1) to (1000,1), vertically repeated to cover the height of #article. How can I get the effect that this image stretches only in its non-fading area (so that the faded borders would not get stretched)? Can I get it without any extra div (as in that case, the mandatory behaviour would reapeat it self horizontally)?

Thank you so much :)


Solution

  • Having a percentage height for footer and header along with max-height makes it very difficult to work with (or atleast using the technique I go to for this). I changed the css to be a fixed height which is the max-height value. You could use media queries if the percentage height is for screen size compatibility.

    Below is how I would achieve the layout, along with a gradient background image, which uses CSS only, rather than an image:

    body {
     background-color: black;
     margin: 0;
    
    
    }
     #main {
         background-color: red;
         width: 60%;
         height: 100vh;
         margin: auto;
         position: relative;
     }
     #header {
         background-color: white;
         width: 100%;
         height: 100px;
     }
     #article {
         background-color: orange;
         width: 100%;
         top: 100px;
         bottom: 80px;
         position: absolute;
         background: rgb(179, 220, 237);
         /* Old browsers */
         background: -moz-linear-gradient(left, rgba(179, 220, 237, 1) 17%, rgba(41, 184, 229, 1) 49%, rgba(188, 224, 238, 1) 81%);
         /* FF3.6+ */
         background: -webkit-gradient(linear, left top, right top, color-stop(17%, rgba(179, 220, 237, 1)), color-stop(49%, rgba(41, 184, 229, 1)), color-stop(81%, rgba(188, 224, 238, 1)));
         /* Chrome,Safari4+ */
         background: -webkit-linear-gradient(left, rgba(179, 220, 237, 1) 17%, rgba(41, 184, 229, 1) 49%, rgba(188, 224, 238, 1) 81%);
         /* Chrome10+,Safari5.1+ */
         background: -o-linear-gradient(left, rgba(179, 220, 237, 1) 17%, rgba(41, 184, 229, 1) 49%, rgba(188, 224, 238, 1) 81%);
         /* Opera 11.10+ */
         background: -ms-linear-gradient(left, rgba(179, 220, 237, 1) 17%, rgba(41, 184, 229, 1) 49%, rgba(188, 224, 238, 1) 81%);
         /* IE10+ */
         background: linear-gradient(to right, rgba(179, 220, 237, 1) 17%, rgba(41, 184, 229, 1) 49%, rgba(188, 224, 238, 1) 81%);
         /* W3C */
         filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3dced', endColorstr='#bce0ee', GradientType=1);
         /* IE6-9 */
     }
     #footer {
         background-color: blue;
         width: 100%;
         height: 80px;
         position: absolute;
         bottom: 0;
     }
    

    and the fiddle I created to test it out: Fiddle