How to prevent a div from stretching the viewport?

I’ve looked everywhere, but I can’t find an answer to my question - TBH I’m not really sure what I should look for.

I have a problem with a fixed width design. The design has a width of 900px but has a background of 1100px, where the 900px is centered in the 1100px (so margins of 100px on either side).
Now, I don’t want to make the wrapper div 1100px wide, because that causes vertical scrollbars on smaller viewports - and vertical scrollbars are ugly.
So I thought I’d make a div of 900px, center that using margin: 0 auto and then put a div inside that with position: absolute; left: -100px; width: 1100px; and put the background in there.

This is a minimal example to show what I mean:


<!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>Center test</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<style type="text/css">
	body,html {
		margin: 0;
		padding: 0;
		height: 100%;
	}
	body {
		background: #fff;
		color: #888;
	}
	#content {
		position: relative;
		width: 900px;
		margin: 0 auto;
		min-height: 200px;
		background: #888;
		color: #fff;
	}
	#content_bg {
		position: absolute;
		background: #eee;
		left: -100px;
		width: 1100px;
		height: 200px;
		z-index: -1;
	}
	</style>
</head>
<body>
	<div id="content">
		<div id="content_bg"></div>
		content here
	</div>
</body>
</html>

Now, when you view that in a viewport > 1100px all looks fine and when you make the viewport smaller the 100px on the left of main 900px div starts to disappear out of the viewport without any consequences, but the right 100px causes the browser to draw vertical scrollbars to scroll to the 100px background on the right side, whereas I’d like it to behave like the left side: just disappear out of the viewport and don’t create scrollbars.

I found that overflow-x:hidden or overflow:hidden on the body works, but then people with a viewport smaller than 900px can’t see the whole width 900px content, and that is definitely not what I want …

As another alternative I’ve also been thinking to put overflow: hidden on the body using javascript, but only if the viewport is wider than 900px but smaller than 1000px. That should work -haven’t tested it yet- but I’d rather have a pure CSS solution.

So my question is this: is what I want possible using CSS only?

If anything isn’t clear, feel free to ask :slight_smile:

Can you put overflow:visible on the inner div so that that will be shown, but any surplus outer div will be clipped if necessary?

If it’s a background image then I would go with the extra 100% wide wrapper and use a centred background image as you mention above.

If you wanted real elements on either side of the layout then we already had a quiz for that :slight_smile:


<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<style type="text/css">
html, body {
    margin:0;
    padding:0;
}
h1, p {
    margin:0 0 1em
}
#page {
    width:760px;
    margin: auto;
    text-align:left;
    background:red;
    position:relative;
    z-index:2;
}
#adholder {
    width: 100%;
    overflow: hidden;
    position: absolute;
    top: 0;
    left: 0;
}
#adinner {
    width:760px;
    margin:auto;
}
.adright, .adleft {
    width:160px;
    position: relative;
    margin:0;
    float:left;
    height:600px;
    overflow: hidden;
    background:#52b502;/* for testing */
    z-index:99;
    display:inline;
}
.adright {
    float:right;
    left:170px;
}
.adleft {
    left:-170px
}
</style>
</head>
<body>
<div id="adholder">
    <div id="adinner">
        <div class="adright">Advert goes here</div>
        <div class="adleft">Advert goes here</div>
    </div>
</div>
<div id="page">
    <h1><a href="#">Centred page content goes here</a></h1>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
    <p>test</p>
</div>
</body>
</html>


The body bg is already used for something else, plus I need to it two times below each other. Otherwise, the body bg would have been a good idea :slight_smile:

Why wouldn’t you set the background on the body and leave the 900px div centered as it is? Then you don’t need #content_bg at all. Unless you are trying to do something that isn’t obvious to me…

body {
color: #888;
background: url(…/images/bg.gif) #fff top center y-repeat; /* or whatever settings you need here */
}

The background contains some decorative elements that look nice on a wider screen, but if a screen isn’t that wide it’s not that bad if the viewer can’t see them, and of course they would never even know that they are there in the first place :slight_smile:

Yep, wrapping a div around Content with the background image and background-position: 50% 0 works!

Problem solved :slight_smile:

question: if the layout is fixed, why the image is bigger?

my guess: overflow: hidden; on Content

#content {
    position: relative;
    width: 900px;
    margin: 0 auto;
    min-height: 200px;
    background: #888;
    color: #fff;
overflow: hidden;
}

Sadly that doesn’t work. It cuts off the background anyway, no matter how wide the viewport is …

Oh, btw, I’m actually using a background image and not a solid color, so I’ll also try wrapping the content in a div that has the background and set background-position to 50% 0

Yup

Indeed, that’s what solved it :slight_smile:

I was looking for that several months ago, but couldn’t figure it out and gave up (it only broke on resolutions lower than 1024x768 so I didn’t really care anyway). Good to know it is possible after all!

Nope, that doesn’t work.

Thanks for all help you guys, I really appreciate it :slight_smile:

You know, now that I think about it, that could actually be ok in IE6 if you are using a centered bg image instead of background color. Since you just need it to hold the image the extra width shouldn’t be an issue as long as it keeps it centered.

Now my question is, did you get it all to work how you wanted it to? :slight_smile:

Ah yes, max-width does the trick for the solid background colors, nice catch :slight_smile:
Thanks!

As for max-width in IE6, one of Paul’s CSS quizes is actually on that http://www.sitepoint.com/forums/showthread.php?p=4386148#post4386148
Seems it can be solved :slight_smile:

Try using max-width on #content_bg? I know it doesn’t work in IE6, but it will work in everything else. (Can’t remember off the top of my head if there is a fix for that in IE…)

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
body {text-align:center; background-color:#CCCCCC; margin:0; padding:0;}
#wrap {max-width:1100px; background-color:#006699; height:500px; position:relative; margin-left:auto; margin-right:auto;}
</style>
</head>
<body>
<div id="wrap">
</div>
</body>
</html>