Given the following HTML. It display two columns: #left, #right. Both are fixed width and have 1px borders. Width and borders equal the size of upper container: #wrap.
When I zoom out Firefox 3.5.2 by pressing Ctrl+- columns get wrapped (demo).
How to prevent this?
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<style type="text/css">
div {float:left}
#wrap {width:960px}
#left, #right {width:478px;border:1px solid}
</style>
</head>
<body>
<div id="wrap">
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
</body>
</html>
Try switching to a different box model as follows:
#left, #right
{
width:480px;
border:1px solid;
box-sizing: border-box;
/* and for older/other browsers: */
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-webkit-box-sizing: border-box
}
Dmitri,
When the browser caluclates the new width of your divs after you zoom, it doesn't have reduce the two 478px+4px of border elements in proportion to the single 960px. So you end up with this:
Your original styles:
#wrap equals 960px wide
#left & #right, plus border equals 960px wide
Everything fits nicely.
Zoom reduced (ctrl-)
#wrap equals (approx.) 872px wide.
#left, #right, plus border eqauls 876px wide.
(left and right reduce to approx 436px each, plus 4 px of border)
Contents are too wide for #wrap. To see & measure this just apply a background color to #wrap.
To fix, remove width from #wrap. Because it is floated, it will shink to fit the contents. However, you should apply a width to floated elements and your div {float:left} applies it to #wrap.
Remove the style div {float:left} and add float:left to #left, #right.
#left, #right {float:left;width:478px;border:1px solid}
If you want #wrap to be centered, then you'll need to declare a width for it again and add margin:0 auto;, in which case you'll have this problem again [edit: or you can, as chris indicated, set the width to 100%]. So simply recalculate the width of #left, #right so that they will fit.
It's my understanding that leaving a little breathing room between the width of parent and child elements is good to avoid this sort of problem anyway.
I had similar problem. Setting #right to a negative margin worked. For example:
#right{
margin-right:-400px;
}
I encountered the same issue described above. After, hopelessly wandering around the internet for a few minutes, I found out that apparently it's a bug in Firefox 3.5.x and IE 7/8. The bug is still present as of this writing.
To see more about the bug go here: http://markasunread.com/?p=61 (formerly http://markasunread.com/2009/06/zoom-bug-in-ie78-and-firefox-caused-by-border/)
I'm not sure I fully understand your situation. Reducing the zoom should in effect zoom out. Are you saying that when you zoom out the columns wrap around?
You should float those divs using this code in your CSS:
#container {width: 960px}
#left {float: left}
#right {float: right}
If this does not work you can try leaving a small space between the columns by adjusting the width to compensate for some small browser discrepancies.
EDITED (ignore above):
Seeing as you have provided me with more information, I need to tell you that the browser incorporates rounding when resizing and having these exact pixel-perfect sizing isn't the smartest thing to do.
Instead, you can have one div have an absolute width and the other to have an automatic width like so:
#container {width: 960px;}
#left {width: 478px;}
#right {width: auto;}
This will have the browser take as much space for #right as can be possibly taken inside the #wrap div. Be sure to set a width for the wrap, otherwise it will take 100% of the window.
I hope this helps!
EDITED:
Right IS very close to your fixed width, because you defined the width of your container already, so it is simply the container width subtracted by the width of the left side. This is merely to ensure that there is no discrepancy when resizing the window.
I understand it will not take up the entire area of space, however, as content is added, the maximum it will go is container - left width. Are you trying to apply a background? In that case set the right side background as the container background and then the left side as the left side background (make sure it covers half of it).
I hope I've helped.
I was wrestling with this bug too. I had a tab navigation with fixed widths on each tab and a right margin all totaling the width of the container div.
I actually discovered a new solution, which seems to work great. The tab navigation is of course wrapped in a ul tag. I set a width on this ul tag of about 6px greater than the container div. So for example, container div is 952px wide, then ul tag is 958px wide. Since the li tags in the navigation are floated to the left and have fixed widths, they will not go beyond 952px, however the ul element has some breathing room, which appears to be necessary to squash this bug. I've tried zooming out in Firefox and IE7/8 and the tabs stay in place.
Hope this helps someone save a few minutes/hours!
Ok guys, when you have a div with fixed height, to prevent zoom from breaking up everything, add overflow:hidden to it's css. That did the trick for me and now every browser can go zoom crazy. :)
The problem is caused by the width of your #wrap.
I've set the width to 100% and it doesn't break anymore in Firefox while zooming out with CTRL -.
Best Solution to fix floating bug in every case is use table layout using tds.
That will never loose floating.
Related
I've been trying to get a handle on fluid layouts in CSS with percentages and thought I was getting somewhere until I ran into this problem while testing out some things. With the code below I have two divs that should be placed right outside of view, so that if you scroll at all you should see them right away.
The one aligned with the left margin works perfectly, but the div aligned with the top margin has results that fumble me. To get the desired result I had to set the top margin to 42%, and I'm not sure where this number is coming from. I figured it would be 90% (100% - topbar's height), and at first I thought it might have something to do with the browser interface being included but there's no way my interface is 48% and putting the browser in fullscreen didn't fix it. What really gets me is that setting navigation's height to 90% plus topbar's height to 10% perfectly fits in view as expected, so why is the height-wise margin different?
Help is greatly appreciated, and I'd love it if you could try to explain anything as much as possible since I'm still trying to understand these attributes and how they work.
<!DOCTYPE html>
<html>
<head>
<style>
body, html {
background-color:#988557;
width:100%;
height:100%;
margin:0%;
}
#topbar {
margin-left:100%;
background-color:#3F4A66;
width:100%;
height:10%;
}
#navigation {
margin-top:42%;
background-color:#3F4A66;
width:10%;
height:90%;
}
</style>
</head>
<body>
<div id="topbar">
</div>
<div id="navigation">
</div>
</body>
</html>
Your magic 42% comes from the fact that margins in percentages are calculated based on the containing block's width. So the top margin that you have specified is 42% of the width of the block that is containing your #navigation div, in this case the body.
Have a look at the w3c specification for margin in percentages.
I think what you mean with margin-top: 90% is: Add as much space to the top of #navigate equal to 90% of the viewport height.
What the browser does is: Add space as much space to the top op #navigate equal to 90% of the viewport width.
If you make your browser viewport exactly square you will see that the 90% does exactly what you want. However, if you make the viewport rectangular, which is more common, you will see that the positioning is off, conforming to "percentage of width" instead of "percentage of height".
It is consider a good practice to use a Pixel for margins instead of using percent..
I am trying to work towards a responsive design for a web app we are building.
The image below shows a prototype of what I am working on, taken from the jsfiddle below it.
Rather than the grey blocks folding under each other I want them to continue on horizontally causing a scroll if it goes out of view.
I used Erskine's gridpak to generate the responsive grid for me. Is there any way of achieving the effect using the current grid? I am at a bit of a stand still with it.
http://jsfiddle.net/brendan_rice/wT8MG/
Thanks in advance...
You can achieve it with white-space:nowrap and display:inline-block.
http://jsfiddle.net/wT8MG/7/
I removed the white space between the blocks to eliminate the extra margin caused by a space being rendered, one of the few drawbacks of inline-block.
If you want just the row to scroll and not the whole page then add overflow-x:scroll to the main or row class.
EDIT:
For IE7 support add <!--[if lt IE 8]> <style>.col{display:inline}</style> <![endif]--> below the CSS.
Ok, IE tricked me by keeping the document mode in IE8 standards when I switched the browser mode to IE7.
The CSS so far that will work in IE8+. Edited for brevity.
.side-panel {height: 300px}
.side-panel .container{background-color: blue;}
.main {
width: 100%;
white-space:nowrap
}
.container {background-color: #ddd;height: 30px;margin-top: 10px;}
.col {
display:inline-block;
vertical-align:top;
white-space:normal;
border:0;
box-sizing:border-box;
background-clip:padding-box !important;
}
#media screen{
.col {
margin-left:1%;
padding:0 0%;
}
.row .col:first-child {margin-left:0;}
.span_1 {width:19.2%;}
.span_2 {width:39.4%;}
.span_3 {width:59.6%;}
.span_4 {width:79.8%;}
.span_5 {margin-left:0;width:100%;}
}
The whole point of a responsive grid is that you shouldn't ever have to horizontally scroll.
Percentages are relative to their parents. So no matter what width you set for <div class="main row">, each of your columns will always be a percentage of the total.
So if we add up all your columns, we get (8 cols x (19.2% width + 1% margin)) - 1% remove first margin = 160.6%. Floated elements always fold to the next line when they are larger than their parents, and as it will always be larger than its parent, it cannot help but fold. The only way to have them all on one line would be to have the total width of the columns add up to 100% or less of its parent container.
I'm having a problem with the page elements moving when I add a border in a HTML 5 document.
I expected the containing header element (grey) to appear at the top of the screen, but it seems to take the margin from the inner div (red). However if I add a border to the header it appears where I expect and the red inner div only moves slightly!
(1st image: without border; 2nd image: with border)
I have tried setting relative or absolute positioning, using a div instead of the header element, setting margins & padding to 0, using a HTML4 doctype etc. The HTML validates. This is the HTML stripped of everything and still doesn't work. Its happening in latest Chrome & FF.
HELP!! What have I missed?? Or any workarounds (other than keeping the border)?
HTML:
<!DOCTYPE HTML>
<html>
<head>
<title>Test</title>
</head>
<body>
<header><div id="mydiv"></div></header>
<div id="content"><p>hello</p></div>
</body>
</html>
CSS:
header {background-color:#CCCCCC; width:960px; height:430px;}
#mydiv {width:960px; height:320px; margin:80px 0px 0px 0px; background-color:#CC0000; }
The issue comes from something called "margin collapsing". It's simple: 2 adjoining margins collapse to the highest of the two (I say two, but it could be more).
In your case, '#mydivs' margin-top - 80px - is touching the 'header's margin-top - 0px. They're adjoining - there's no element between them, nor padding, nor border.
The margins collapse, therefore, to the highest of the two (80px), and it is then applied on the highest of the elements in the parent-child hierarchy - that's the header in this case.
One solution to this problem is to put something between the margins; either of some padding, or a border on the header works fine.
header {
border-top: 0.1em solid rgba(0,0,0,0);
}
A second solution (my preferred one), is to make the parent element create a new block formatting context. That way, its margins simply won't collapse with that of its child.
How do you create a block formatting context?
There are four possible ways.
by floating it.
"position absoluting it".
adding one of these displays: “table-cell”, “table-caption”, or “inline-block".
adding an overflow other than visible.
To prevent the margins from collapsing you could do any of these 4. I usually go for number 4) - set overflow to auto, as it's only side affect... well it's improbably likely to become a problem.
header {
overflow: auto;
}
That's basically it for parent-child margin collapsing. There's also margin collapsing between siblings and the rule is pretty much the same: 2 adjoining margins collapse to the highest of the two. It's the solutions that are not.
Here's a great explanation of margin-collapsing - http://www.howtocreate.co.uk/tutorials/css/margincollapsing
This is known as collapsing margins. They can be overcome by adding padding to the parent element (in this case, the <header>).
Code (with padding, without padding):
Notice the padding:0.001em;. This makes the margins no longer collapse, but doesn't add any space to the <header>.
header {padding:0.001em; background-color:#CCCCCC; width:960px; height:430px;}
#mydiv {width:960px; height:320px; margin:80px 0px 0px 0px; background-color:#CC0000; }
The link to collapsing margins in bfrohs answer helped me find a solution that will work for me, and it may help anyone else who gets this problem.
Absolutely positioned divs don't collaspe so making the header element relative and the inner div absolute gives the correct positioning without adding space with padding or margins.
Working example:
http://jsfiddle.net/8QPGJ/
(Without the positioning: http://jsfiddle.net/8QPGJ/1/)
So most of this site so far uses auto centering (the container and nav have margin-left/right:auto) and things seem to go all well and dandy except for the footer.
When I resize the size of the window everything is filled nicely except when I scroll horizontally the footer seems to be cut off on the right side.I've read that this may be a browser bug. Though it occurs in IE and chrome and firefox so it could just be sloppy coding (I am a big newb).
Here is the css:
#footer {
background-image:url(../Images/footer_bg.jpg);
color: white;
height:300px;
padding-top:20px;
}
/*I have 4 headings with Ps that I want to display horizontally side by side*/
#footerContent{
min-width:1000px;
}
/*So I tried floating <li> inside <ul> and limiting its width, which worked fine */
#footerContent ul{
width:1000px;
margin-left:auto;
margin-right:auto;
}
#footerContent li {float:left; width:250px; }
Just to reiterate it works fine when the browser is full screened or resized. But after you resize and you use the horizantal scrollbar to scroll all the way right then the background image is cut off.
I've tried width:100%, min-width, width:1000px; but none of those seemed to work.
http://postimage.org/image/3so264fnb/
Regarding your comment about Stackoverflow being similar
(at least as of 4-29-2012)
The issue on stackoverflow seems to be that the footer contains another div element, footerwrap, that has a width: 960px set to it, but footer itself has no width setting. A div is basically designed to simply "group" block level content. It is a common misconception that a div expands with it's content. Actually, a div expands to its parent if an explicit width is set on a parent. If there is none, then it fits the browser window. This is what you (and stackoverflow) is experiencing.
To get the div to relate to the content width, you must either:
Explicitly set the width or min-width of the container. So, if stackoverflow set a min-width: 990px (the 960px of the footerwrap + the padding of 15px on each side) on the footer that wraps footerwrap, then its problem is solved.
Set the container div to float, as a floated element wraps its content.
Take a look at this example fiddle. Note the first two div's experience the same issue you are seeing. If you shrink or expand the size of the iframe window in the fiddle, the first two div's will contract or enlarge with it, but still leave blank space on the horizontal scroll. The third and fourth div's have had my fixes above applied. The fifth div is to show the fact that the inner div, if not defined in width, will expand to the width of a container that has an explicit width set.
As a side note, it may work (I have not tested in many browsers, but FF 11 worked) to actually just add a float: left to the body element in those cases where the body does not have a set width. As this example shows, it seems to be effective in causing the first two div's to behave just like the 3rd and 4th divs.
I hope this helps.
Original Answer
It is a little unclear what can be done because there is some information lacking. Here are some things to look for:
Is your background-image wide enough (or can it / should it have a background-repeat: repeat-x applied to make it wider if needed)?
Does your footer width (1000px) match your upper content width? If footer is constrained narrower than what the upper content area (or header, etc.) is allowed to be, then it's background will not align.
That's the best I can do without seeing more of your html and css for the page, and not knowing the size of the image and your intention for how it is to function.
Here's a question that's been haunting me for a year now. The root question is how do I set the size of an element relative to its parent so that it is inset by N pixels from every edge? Setting the width would be nice, but you don't know the width of the parent, and you want the elements to resize with the window. (You don't want to use percents because you need a specific number of pixels.)
Edit
I also need to prevent the content (or lack of content) from stretching or shrinking both elements. First answer I got was to use padding on the parent, which would work great. I want the parent to be exactly 25% wide, and exactly the same height as the browser client area, without the child being able to push it and get a scroll bar.
/Edit
I tried solving this problem using {top:Npx;left:Npx;bottom:Npx;right:Npx;} but it only works in certain browsers.
I could potentially write some javascript with jquery to fix all elements with every page resize, but I'm not real happy with that solution. (What if I want the top offset by 10px but the bottom only 5px? It gets complicated.)
What I'd like to know is either how to solve this in a cross-browser way, or some list of browsers which allow the easy CSS solution. Maybe someone out there has a trick that makes this easy.
The The CSS Box model might provide insight for you, but my guess is that you're not going to achieve pixel-perfect layout with CSS alone.
If I understand correctly, you want the parent to be 25% wide and exactly the height of the browser display area. Then you want the child to be 25% - 2n pixels wide and 100%-2n pixels in height with n pixels surrounding the child. No current CSS specification includes support these types of calculations (although IE5, IE6, and IE7 have non-standard support for CSS expressions and IE8 is dropping support for CSS expressions in IE8-standards mode).
You can force the parent to 100% of the browser area and 25% wide, but you cannot stretch the child's height to pixel perfection with this...
<style type="text/css">
html { height: 100%; }
body { font: normal 11px verdana; height: 100%; }
#one { background-color:gray; float:left; height:100%; padding:5px; width:25%; }
#two { height: 100%; background-color:pink;}
</style>
</head>
<body>
<div id="one">
<div id="two">
<p>content ... content ... content</p>
</div>
</div>
...but a horizontal scrollbar will appear. Also, if the content is squeezed, the parent background will not extend past 100%. This is perhaps the padding example you presented in the question itself.
You can achieve the illusion that you're seeking through images and additional divs, but CSS alone, I don't believe, can achieve pixel perfection with that height requirement in place.
If you are only concerned with horizontal spacing, then you can make all child block elements within a parent block element "inset" by a certain amount by giving the parent element padding. You can make a single child block element within a parent block element "inset" by giving the element margins. If you use the latter approach, you may need to set a border or slight padding on the parent element to prevent margin collapsing.
If you are concerned with vertical spacing as well, then you need to use positioning. The parent element needs to be positioned; if you don't want to move it anywhere, then use position: relative and don't bother setting top or left; it will remain where it is. Then you use absolute positioning on the child element, and set top, right, bottom and left relative to the edges of the parent element.
For example:
#outer {
width: 10em;
height: 10em;
background: red;
position: relative;
}
#inner {
background: white;
position: absolute;
top: 1em;
left: 1em;
right: 1em;
bottom: 1em;
}
If you want to avoid content from expanding the width of an element, then you should use the overflow property, for example, overflow: auto.
Simply apply some padding to the parent element, and no width on the child element. Assuming they're both display:block, that should work fine.
Or go the other way around: set the margin of the child-element.
Floatutorial is a great resource for stuff like this.
Try this:
.parent {padding:Npx; display:block;}
.child {width:100%; display:block;}
It should have an Npx space on all sides, stretching to fill the parent element.
EDIT:
Of course, on the parent, you could also use
{padding-top:Mpx; padding-bottom:Npx; padding-right:Xpx; padding-left:Ypx;}