+2  A: 

Until CSS3 gives us inside borders and box-model switching you need two divs. The first to give the 100% height and the second to provide the border. Otherwise the border goes on the outside of the 100% height (ie, 1px+100%+1px)

BTW. You should collect some stats before going "IE only". IE does not have the marketshare it once did. Anywhere between 10 - 30% of your users may be on other browsers.

SpliFF
It's an Intranet application. It's quite safe to say that it is IE only. ;-)
Tomalak
A: 

Try setting borders for the html element. The body element is only as high as it needs to but, as far as I remember, the html element takes the whole space (it's where you should set your background, too).

I'm not sure how borders look, I usually only set backgrounds.

Xr
Not working, same problem. The HTML element is also only as high/wide as in needs to be when the document is in standards mode.
Tomalak
A: 

border is out of 100% size. Try padding: -1px or margin: -1px.

Sergey Kovalenko
negative margin pulled the border out of the document, padding must be positive in the CSS specification.
SpliFF
+1  A: 

Here's a simple solution using only the html and body elements (no need for nested divs). It takes advantage of the special behaviour of the HTML element (it can't have an outer border so it must shrink to display it).

<html>
<head>
<style>
html {padding:0; margin:0; border:5px solid red;}
body {height:100%; padding:0; margin:0; border:0;}
</style>
</head>

<body>

</body>
</html>
SpliFF
Nice. I didn't know about the "special properties" of the HTML element in this regard. Good to know.
Tomalak
It does not seem to work in standards mode, though. The html height collapses again, and setting it to 100% results in a vertical scroll bar.
Tomalak
You must be using Internet Exploiter. It works with 4.01 Strict on FF so you're probably seeing a browser bug.
SpliFF
hmm. you're right. I mustn't have reloaded the page.
SpliFF
+2  A: 

You'll love this one.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html>
<head>

<style>
html {
    height: 100%;
    width: 100%;
    display: table;
}
body {
    display: table-row;
}
#wrapper {
    display: table-cell;
    border: 5px solid red;
}
</style>
</head>

<body>
    <div id="wrapper"></div>
</body>
</html>

http://www.test.dev.arc.net.au/100-percent-border.html

I figured since tables keep a lot of "quirky" behavior even under standards mode they might be the solution. Turning the HTML element into a table is pretty funny though.

Before marking this down for not working in IE6 consider that's a very trivial issue to fix. The point is that using the table drawing algorithm is the solution, and a pure CSS solution is also possible:

<table class="outer"><tr><td class="inner"> ...page content...
SpliFF
The only solution on the page that actually works and it gets marked down?? WTF?
SpliFF
Hmm.. guess because it doesn't work in IE6? but then that's what IE7-js is for.
SpliFF
+3  A: 

As SpliFF already mentioned, the problem is because the default (W3C) box model is 'content-box', which results in borders being outside of the width and height. But you want those to be within the 100% width and height you specified. One workaround is to select the border-box box model, but you can't do that in IE 6 and 7 without reverting to quirks mode.

Another solution works in IE 7, too. Just set html and body to 100% height and overflow to hidden to get rid of the window's scrollbars. Then you need to insert an absolutely positioned wrapper div that gets the red border and all content, setting all four box offset properties to 0 (so the border sticks to the edges of the viewport) and overflow to auto (to put the scrollbars inside the wrapper div).

There's only one drawback: IE 6 doesn't support setting both left and right and both top and bottom. The only workaround for this is to use CSS expressions (within a conditional comment) to explicitly set the width and height of the wrapper to the viewport's sizes, minus the width of the border.

To make it easier to see the effect, in the following example I enlarged the border width to 5 pixels:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Border around content</title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }

    html, body {
      height: 100%;
      overflow: hidden;
    }

    #wrapper {
      position: absolute;
      overflow: auto;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      border: 5px solid red;
    }
  </style>
  <!--[if IE 6]>
  <style type="text/css">
    #wrapper {
      width: expression((m=document.documentElement.clientWidth-10)+'px');
      height: expression((m=document.documentElement.clientHeight-10)+'px');
    }
  </style>
  <![endif]-->
</head>
<body>
  <div id="wrapper">
    <!-- just a large div to get scrollbars -->
    <div style="width: 9999px; height: 9999px; background: #ddd"></div>
  </div>
</body>
</html>

P.S.: I just saw you don't like overflow: hidden, hmmm...


Update: I managed to get around using overflow: hidden by faking a border using four divs that stick to the edges of the viewport (you can't just overlay the whole viewport with a full-sized div, as all elements below it wouldn't be accessible any more). It's not a nice solution, but at least the normal scrollbars remain in their original position. I couldn't manage to let IE 6 simulate the fixed positioning using CSS expressions (got problems with the right and bottom divs), but it looked horribly anyway as those expressions are very expensive and rendering got tediously slow.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>Border around content</title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }

    #border-t, #border-b, #border-l, #border-r {
      position: fixed;
      background: red;
      z-index: 9999;
    }

    #border-t {
      left: 0;
      right: 0;
      top: 0;
      height: 5px;
    }

    #border-b {
      left: 0;
      right: 0;
      bottom: 0;
      height: 5px;
    }

    #border-l {
      left: 0;
      top: 0;
      bottom: 0;
      width: 5px;
    }

    #border-r {
      right: 0;
      top: 0;
      bottom: 0;
      width: 5px;
    }
  </style>
</head>
<body>
  <!-- just a large div to get scrollbars -->
  <div style="width: 9999px; height: 9999px; background: #ddd"></div>
  <div id="border-t"></div><div id="border-b"></div>
  <div id="border-l"></div><div id="border-r"></div>
</body>
</html>
Marcel Korpel
+1, at least that's a decent explanation. Yeah, the `overflow: hidden` is a bit hacky, but I guess there's no way around it. Looks like my original request is impossible to fulfill, but that's an answer, too.
Tomalak
PS: Nice work-around in your update! I'd give a second +1 if I could. :)
Tomalak
@Tomalak: I did it for you. ;-)
Chris
+1  A: 

It also a bit ugly, but giving the body

position:relative;
top:-1px;
left:-1px;

worked for me.

acme
That's worth a try as well. And it's just *a bit* ugly, not serious.
Tomalak