Border around 100% body height and width (HTML 4.01 Strict) - html

Okay, this is driving me crazy right now.
I want to have a border around my document. It should be nicely going around the whole window/viewport. So I define:
body {
border: 1px solid red;
}
When my document is in quirks mode, this works fine. At least in IE, which is my primary target here. A red border shows up at the very edges of my page, obviously because by predefined CSS body and html are set to fill the screen.
When going to standards mode by setting a HTML 4.01 strict DOCTYPE, body and html collapse to the real (smaller) size of the content, the border is drawn right through the middle of the screen. So I define:
body, html {
padding: 0px;
margin: 0px;
border: 0px none;
width: 100%;
height: 100%;
}
body {
border: 1px solid red;
}
And I get — scroll bars, scrolling exactly one pixel to show the bottom/right borders. However, I want that border visible right away.
Is there a no-bullshit (like "height: 99.9%;", "overflow: hidden;" or "switch back to quirks mode") method to get a border at 100%, without unnecessary scroll bars? IE-only is fine, cross-browser would be better, of course.

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>

You'll love this one.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<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...

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.

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>

It also a bit ugly, but giving the body
position:relative;
top:-1px;
left:-1px;
worked for me.

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.

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

Related

Unwanted scrollbars when placing two divs below each other

I have two fullscreen divs which are placed relatively below each other. But when I'm visiting the page, the browser always shows me unwanted scrollbars and a width greater than 100vw. When there is only one div, the whole thing works like a charm. Would appreciate any help here :)
<html>
<head>
<link rel="stylesheet" type="text/css" href="normalize.css">
<style>
.section {
position: relative;
width: 100vw;
height: 100vh;
background-color: red;
}
.section.second {
background-color: green;
}
</style>
</head>
<body>
<div class="section">ASD1</div>
<div class="section second">ASD2</div>
</body>
</html>
This is a known issue.
According to https://caniuse.com/#feat=viewport-units,
"Currently all browsers but Firefox incorrectly consider 100vw to be the entire page width, including vertical scroll bar, which can cause a horizontal scroll bar when overflow: auto is set."
You can add following CSS style to fix it,
html, body {margin: 0; padding: 0; overflow-x:hidden;}
Example (JSBin)
Thats because BODY element has its own margins by default. You need to make it zero. You can check it here (jsfiddle example).
body { margin: 0; }
First of all, to remove unwanted margins and paddings, you should always perform a CSS reset (resets all browser specific properties to zero) or a CSS normalization (sets all properties to the same default value for every browser, but not zero). For debugging purposes it is enough to write the following:
* {
margin: 0;
padding: 0;
}
In a real project you should definitely use a better solution like Eric Meyer’s reset or Normalize.css.
Okay, now we managed to solve the spacing issue, but this still leaves us with the scrollbar issue. For a solution look at this post. It says
(...)the horizontal scroll is present because of the vertical scroll.
which you can solve by giving max-width: 100%.
Hence, this is the final solution:
* {
margin: 0;
padding: 0;
}
.section {
position: relative;
width: 100vw;
height: 100vh;
max-width: 100%;
background-color: red;
}
.section.second {
background-color: green;
}
<div class="section">ASD1</div>
<div class="section second">ASD2</div>

Stop two objects overlapping

I am building a website to host an online gameserver list for the game Crysis Wars, and have just found out that it's by far easier just to develop the design in Adobe Fireworks, and add the relevant code after.
The current web page that I am designing has a signin box at the center of the page, and it works beautifully.
That is, until we change the size of the browser window.
This is the web page as it normally looks:
It is displayed correctly, but here's the screenshot of when the browser window was resized:
As can be seen, this is an issue with the page, since visitors will have different screen resolutions, and this problem could easily re-occur.
My question is, how can I force these two CSS objects to maintain their position, and never overlap?
This is troublesome since the signin box centers itself on the web page.
The web page can be viewed at crysis-or.eu (please don't berate me for developing on a live website).
HTML Code:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<html>
<head>
<title>Server Portal | Login</title>
<link href="./css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="navbar">
</div>
<div class="loginui">
</div>
</body>
</html>
CSS:
body {
width:100%;
margin-left:-0px;
background-color:07080A;
}
body > .loginui {
width:400px;
height:400px;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
background:url("http://crysis-or.eu/img/login_b_bg.png") repeat-x;
}
body > .navbar {
width:500px;
height:100px;
position: absolute;
margin-top:50px;
margin-left:100px;
background:url("http://crysis-or.eu/img/navbar.png") repeat-x;
}
I would recommend the following:
Put the nav bar and the login window in separate wrapper-divs that prevent them from overlapping. You can change your HTML to:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<html>
<head>
<title>Server Portal | Login</title>
<link href="./css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<header id="top-bar">
<div class="navbar">
</div>
</header>
<section id="main">
<div class="loginui">
</div>
</section>
</body>
</html>
Header and Section act just like Div, the only difference is their semantic significance.
Because the .top-bar and .loginui are no longer direct children of the body, your selectors won't work anymore. Change the CSS selectors to just .top-bar and .loginui instead of body > .top-bar and body > .loginui.
The header needs a specified height, and needs its position to be either 'relative' or 'absolute'. An absolutely positioned child element will be positioned absolutely to whatever the closest parent is that is also absolute, or explicitly relative. The background color is for illustration purposes only, and would be removed for production.
header {
position: relative;
height: 200px;
background-color: red;
}
You want the section to fill as much as it can, so it will need absolute positioning. The trick here, the thing that will fix your problem, is adding a min-height attribute to prevent the section from becoming smaller than its contents, thus allowing overlap.
section {
position: absolute;
top: 200px;
left: 0;
right: 0;
bottom: 0;
min-height: 400px;
background-color: blue;
}
That should work for you. The one problem with this solution is that the login window will be centered with respect to its container, rather than the whole window. It will be 100 pixels lower (one half of the header height) than it is with your current design. In order to fix that, if that's important to you, you would need to use a different method of vertically centering it. Put the top as 50%, then use a negative top margin to compensate for half the height plus half of the height of the header, too. Because it has a fixed height, that's easy: (400px + 200px) / 2 = 300px.
.loginui {
width: 400px;
height: 400px;
position: absolute;
top: 50%;
left: 0;
right; 0;
margin: -300px auto 0;
background: url('path/to/login_b_bg.png');
}
If you add this, it will create a scrollbar when trying to resize the browser instead of laying the elements on top of eachother
body
{
width:100%;
min-width: 950px; //ADD THIS. It sets the minimum browser width before creating a scroll bar.
min-height: 550px; // This does the same thing for a vertical scroll bar.
margin-left:-0px;
background-color:07080A;
overflow-y: scroll; // vertical scroll bar
overflow-x: scroll; //horizontal scroll bar
}
EDIT: ---------------------------------
After looking at your site and playing around a bit, your min-width is not an important factor, just the min height, if you set the values like this, the menus will never overlap.
body
{
width:100%;
height: 100%;
min-height: 750px; // Stops the menus from touching eachother vertically, but they can still line up in the x-direction.
margin-left:-0px;
background-color:07080A;
overflow-y: scroll; // vertical scroll bar
}

DIV with "position:absolute;bottom:0" doesn't stick to the bottom of the container in Firefox

I have this HTML source:
<!DOCTYPE html>
<html>
<head>
<title>Stylish Web Page</title>
<style type="text/css">
body { padding: 0; margin: 0; }
div.table { display: table;}
div.tableRow { display: table-row;}
div.tableCell { display: table-cell;}
div.contentWrapper { width: 100%; height: 760px; position: relative;
margin: 0 auto; padding: 0; }
div.footerBar { width: inherit; height: 60px; background-image: url("BarBG.png");
background-repeat: repeat-x; position: absolute; bottom: 0; }
</style>
</head>
<body>
<div class="table contentWrapper">
<div class="tableRow"> </div>
<div class="footerBar"> </div>
</div>
</body>
</html>
The footer is supposed to appear at the bottom of the page, and it does so in Opera and Chrome; However, in Firefox, there's a lot of empty room following the footer. What am I doing wrong? How to fix it?
Here's a screenshot: The blue highlight is the footer.
(Please note: "position: fixed" is not what I want; I want the footer to show up at the bottom of the page, not the browser window.)
The issue in Firefox is caused by display:table. Essentially you are telling Firefox to treat this element as a table.
In Firefox position:relative is not supported on table elements. It isn't a bug though, as in the spec the treatment of position:relative table elements is undefined.
This means that in your example the footer is being positioned relative to the window and not the container.
One solution is to use display:block instead or just remove the display rule entirely. You will see the footer will drop down to its rightful place.
A second solution would be to wrap another non-table div around the container and set position:relative to that instead.
A third option is to add position:relative to the body. Live example: http://jsfiddle.net/tw16/NbVTH/
body {
padding: 0;
margin: 0;
position: relative; /* add this */
}
What version of FF do you have? In FF 6 it displays correctly: http://screencast.com/t/zAjuG8FP99nX
Have you cleared the cache? Maybe there's something left from previous versions of the page.
Did you close the Firebug window? That pushes the content up when open.
Later edit: the last line means: "after you close firebug, scrollbars disappear and div is at the bottom"

Need help getting DIV inside DIV to stretch to width of contents in Firefox

I am using a layout similar to the one from Dynamic Drive here:
http://www.dynamicdrive.com/style/layouts/item/css-right-frame-layout/
The main content area (white) has overflow set to auto. I have given the innerTube inside this main content area a border. However if the contents within this innerTube are greater than the width of the main content area, a horizontal scroll bar will appear as expected, but in Firefox these contents will 'overlap' the border and go off screen (can be retrieved by scrolling horizontally). In other words, the right hand border remains in place, and the content just goes over the op of it, and disappears behind the right hand column.
In IE it behaves exactly as I want - the content pushes the border off screen to be visible only once you scroll over there.
I guess the easiest thing is to paste the source code here. If you copy it into a blank file you'll see what I mean. I've just used one really long word to replicate what happens if a wide image is there instead.
Thanks in advance to anyone who can help me out.
<!--Force IE6 into quirks mode with this comment tag-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body{
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
height: 100%;
max-height: 100%;
}
#framecontent{
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 200px; /*Width of frame div*/
height: 100%;
overflow: hidden; /*Disable scrollbars. Set to "scroll" to enable*/
background: #cccccc;
color: white;
}
#maincontent{
position: fixed;
top: 0;
left: 0;
right: 200px; /*Set right value to WidthOfFrameDiv*/
bottom: 0;
overflow: auto;
background: #fff;
}
.innertube{
margin: 15px; /*Margins for inner DIV inside each DIV (to provide padding)*/
}
.innertubeWithBorder {
margin: 15px;
border: solid 1px #666666;
}
* html body{ /*IE6 hack*/
padding: 0 200px 0 0; /*Set value to (0 WidthOfFrameDiv 0 0)*/
}
* html #maincontent{ /*IE6 hack*/
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="framecontent">
<div class="innertube">
<h1>CSS Right Frame Layout</h1>
<h3>Sample text here</h3>
</div>
</div>
<div id="maincontent">
<div class="innertubeWithBorder">
<h1>Dynamic Drive CSS Library</h1>
<p>AReallyLongWordWhichIsSimilarToHavingAnImageWithWidthGreaterThanTheWidthOfThisDivToShowOverFlowProblemWithBorderSoIfYouResizeThisWindowNarrowerYouWillSeeWhatIMeanWorksFineInIEButNotFirefox</p>
<p>So I want that border over there ------> to dissappear behind the right hand column like it does in IE, and be visible once you use the scrollbar below and scroll to the right</p>
<p style="text-align: center">Credits: Dynamic Drive CSS Library</p>
</div>
</div>
</body>
</html>
There are two things you can try.
<wbr> - This tag doesn't make a break in the text, but it will tell the browser that if the text needs to be broken, it should be broken here. You can use Javascript's substr function (http://www.quirksmode.org/js/strings.html#substr) to split the text apart, add the <wbr> tag in, and combine the text back together again.
width: auto This option is less preferable because it may break your layout and leave it looking less that perfect. However, if this is set on your div, it will make sure that the div is always large enough to contain its inner contents.
Hope this helps!
Figured it out. Set the innerTubeWithBorder to be fixed as well, and used the same IE CSS hack to make it 100% height & width, then set IT'S overflow to auto. To get the padding I used padding:5px in mainContent for IE, and set the top, bottom, right & left in by 5px for FF.
Thanks to anyone who put any thought into it.

IE CSS Float Problem

The output of this code looks pretty much identical in FF, Chrome and Safari on Windows. In IE7 it looks weird.
For all other browsers the frame div exactly wraps the canvas div even though there is a 24X24 div in the frame but outside the canvas. IE7 leaves extra space in the frame, above the canvas, for the "blue-box" div. Once floated I thought the space it would otherwise occupy would collapse. That's the behavior I see in the other browsers.
Is there some trick to getting IE7 to collapse the space like the other guys?
Edit: Just to give an idea to what this example is supposed to represent. It's supposed to represented an embedded widget. The "canvas" is where the content belongs. The "frame" is what the hosting site uses to control the appearance and the behavior between the widget and the rest of the page. The red-box and blue-box divs represent controls in the widget. The red-box is a control put there my the widget code. The blue-box represents a control added by the frame (perhaps a handle to allow the widget to be dragged around the page)
Here's the complete sample
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<title>CSS Positioning</title>
<style type="text/css">
#frame {
position: relative; /* so subelements can be positioned */
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#canvas {
position: relative; /* so subelements can be positioned */
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#blue-box{
position: relative; /* so I can position this element */
float: right; /* I want this element all the way to the right */
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
#red-box{
position: relative; /* so I can position this element */
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
</style>
</head>
<body>
<div id="frame">
<div id="blue-box">blue</div>
<div id="canvas">
<div id="red-box">red</div>
</div>
</div>
</body>
</html>
Extra example for Emily ====================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<title>CSS Positioning</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#one {
background-color: red;
float: right;
}
#two {
background-color: blue;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="one">one</div>
<div id="two">two</div>
</body>
</html>
There could be a problem with the sizing on the "frame" and "canvas" divs. It looks like they are both the same size plus the size of border (which gets added to the total size of the element). Try not specifying a size for your "canvas" div, but give it a margin to space it properly with the "blue-box" div.
When in doubt, reset your elements by setting your margin/padding to 0 one questionable elements. Default spacing can occur between browsers if they are not defined.
Also, I don't believe "position:relative" is needed here.
Acorn
I've run into that problem before and I'm struggling to remember what happened with it. I thiiiink you need to take position: relative off of the #blue-box.
#frame contains #canvas which has a width of 400px and #blue-box which has a width of 24px.
#frame must have a width of at least 424px (might need more...depends on what padding is on your elements) but #frame only has width of 400px.
Try changing the width of #frame to 430px to get both boxes on the same line. Depending on what padding the css reset removed, you may be able to make the width of #frame smaller.
Then you need to put #blue-box inside of #canvas
<div id="frame">
<div id="canvas">
<div id="blue-box">blue</div>
<div id="red-box">red</div>
</div>
</div>
Floated divs do not overlap or 'reach down into divs below them'. Here's a good article on CSS Floats
This is one time I will recommend using absolute positioning. position: absolute removes the element from the flow of the document -- just like you want with #blue-box.
#frame {
position: relative; /* so subelements can be positioned */
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#canvas {
width: 400px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
#blue-box{
position: absolute; /* so I can position this element */
right: 0; /* I want this element all the way to the right */
top:0;
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
#red-box{
width: 24px; /* set size of eventual graphic replacement */
height: 24px;
}
<div id="frame">
<div id="blue-box">blue</div>
<div id="canvas">
<div id="red-box">red</div>
</div>
</div>
have you tried removing the spaces in the code. ie7 can be funny about white space.
<div id="frame"><div id="blue-box">blue</div><div id="canvas"><div id="red-box">red</div></div></div>
Josh
IE adds some extra padding and margin. You should use a reset.css file and try again.
In general, IE doesn't behave as a browser should, so you might need to create IE specific stylesheets.
<!--[if IE]><link rel="stylesheet" type="text/css" href="/public/stylesheets/ie.css" /><![endif]-->
<!--[if IE 6]><link rel="stylesheet" type="text/css" href="/public/stylesheets/ie6.css" /><![endif]-->
<!--[if IE 7]><link rel="stylesheet" type="text/css" href="/public/stylesheets/ie7.css" /><![endif]-->
EDIT:
The wrapping canvas is the one messing things up because it's the same size as the frame. If you do :
#frame {
position: relative; /* so subelements can be positioned */
width: 460px; /* an arbitrary width */
border: 1px solid black; /* a border so you can see it */
}
It fixes the issue. You will just have to tweak the width to get the size you wanted.
EDIT2: I saw one of your comments saying that you want IE to behave like other browsers... this is not going to happen, this browser is just terrible. You might want to fully refactor your code to avoid the unnecessary wrappers that lead to issues in IE