This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Margin on child element moves parent element
I'm having trouble with the margin applied to a children elment inside a <div/>. The child's margin affects the parent's:
<style type="text/css">
html{width:100%}
html body div{margin-left:auto;margin-right:auto;width:800px;}
div#desc{margin-top:100px;background-color:white;width:500px;font-size:24px;}
#photo{width:10px;height:10px}
</style>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<div style="background-color: silver">
<div id="desc">
CSS<br/>
IS<br/>
THE<br/>
HARDEST<br/>
LANGUAGE<br/>
EVER<br/>
</div>
</div>
</div>
</body>
</html>
Why div#desc instead of moving itself down by 100px moves whole construction by this value!?
Here is the working demo.
Because of collapsing margins.
See another answer I wrote for various ways to "fix" it.
For example, in your case, you could add float: left to the parent of #desc.
http://jsfiddle.net/jsK4y/10/
Or padding:
http://jsfiddle.net/jsK4y/16/
Or overflow not set to visible:
http://jsfiddle.net/jsK4y/17/
Collapsing Margins..
add 1px padding to <div style="background-color: silver"> padding stops margins "adjoining" if they can't adjoin, they can't collapse.
I would also suggest a change of Doctype to:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
the one you have is triggering quirks mode in IE7 and below and will lead to more heartache ;)
Welcome to Margin Collapsing:
population: #oneat
This is a common question for people new to CSS. Read the w3c docs, or search for margin-collapsing tutorials.
You're seeing collapsing margins in effect. The standard linked above lists a variety of conditions for that. By the way, <style> elements should go into the <head>.
This has to do with margin collapsing (ref to W3C spec)
Answers to this question of mine will help you.
overflow:auto seems best
That's because the outer div has no content, hence it looks like it does not work.
Using position:absolute; in css or putting something outside the #desc div will show you.
Since you didn't provide much of what you really want to do, I'll do my best to understand. I'm going to assume you want the description div 100px below ay content in the parent (wrap) div.
Your main problem is that your html body div{margin-left:auto;margin-right:auto;width:800px;} css declaration is being inherited by all of your divs on the page. I went ahead and chopped up some of your code to give you a better idea of how things are being placed. Another recommendation for your CSS and HTML code, is to try to not be general about your declarations. Be explicit, as you can see, I added an id to the parent. This way you can avoid inheritance issues as you did. Anyhow, here's the link:
http://jsfiddle.net/jsK4y/15/
There are plenty of ways to do what you want with floats or positioning or even as you did, by margins. But keep in mind that any one of those ways will have their kinks that you'll run into.
If you are talking about, why the text is moved down too, this is because the text is into desc div.If not, explain little better what you mean and, thanks.
Related
Consider the following HTML code:
<style>
td {
padding: 5px;
}
</style>
<p>
1233
</p>
<table>
<tr>
<td>
<h3>Some text</h3>
</td>
</tr>
</table>
If I use <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">, the margin of <p> and <h3> does not work, but if I use <!DOCTYPE HTML>, the margin works.
What's more, when I add
h3 {
margin: 25px 0;
}
to the style, the margin of them suddenly works even using HTML 4.0 doctype!
Why does this strange behavior happen? IE and Chrome behave the same on this issue, is this by design or something, it really confuse me.
I have a lot of pages written depend on this strange behavior, when I brought some CSS from other new components they defined margin then suddenly all these old pages broke. So I want to know what really happened.
The issue is the suppression of default top margins in some contexts in Quirks Mode. Thus, if you use Quirks Mode for some reason (and working with legacy pages is often a very good reason), you should explicitly set any vertical margins you want to have for elements. The other solution is to move away from Quirks Mode, slapping <!doctype html> at the very start, but this may completely ruin (or maybe just disturb a little) your pages, if they have been created so that their rendering relies on buggy behavior and oddities in browsers.
The issue can be demonstrated with a simple standalone document (with no CSS):
<!doctype html>
<p>
1233
</p>
<table border>
<tr>
<td>
<h3>Some text</h3>
</td>
</tr>
</table>
There is empty space, about one empty line, at the beginning before “123” as well as inside the cell before “Some text”. If <!doctype html> is removed, that spacing disappears (but other margins are retained).
The issue is well described in section 10.3.10 Margin collapsing quirks in HTML5 CR: “In quirks mode, any element with default margins [such as p or h3] that is the child of a body, td, or th element and has no substantial previous siblings is expected to have a user-agent level style sheet rule that sets its 'margin-top' property to zero.”
This feature relates to the browser tradition of suppressing top margins in contexts where they are normally useless or even disturbing. For example, if a heading element or a p element is the very first element in document body, or in a table cell, there is no need to separate it from the preceding content. The practice predates general availability of CSS.
I'm don't really know what hapening but, thats what you see in chrome at HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" is not real margins it's a some browser initial styles you can see them in chrome dev tools: -webkit-margin-before, and -webkit-margin-after; this styles ovverides by margin.
For more information you better read specs on W3C, and use doctype html, or maybe html 4.0 strict.
I have a web page like the following one:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<header>
<span>Logo</span>
<nav>Navigation</nav>
</header>
<main>
<h1>Page heading</h1>
<div>
Page content
</div>
</main>
<footer>
Content information
</footer>
</body>
</html>
The page structure is similar to one example in the current HTML5 draft: http://www.w3.org/html/wg/drafts/html/master/grouping-content.html#the-main-element and I think it is semantically correct.
Now I would like to style this document using CSS. I would like to be the header at the top and footer at the bottom, which is, of course, easily doable. Inside the header I would like to put the logo to the right and the navigation in the center, which is also okay (e.g by using the flexible box layout model, which is in one or the other way supported by modern browsers, or by using floats).
My problems begin when I want to put the main's content heading (the h1 element) visually in the left of the header. I could do with position: absolute but such a layout is not very flexible and would break as soon as the header's or the heading's sizes change. The proposed CSS grid layout http://www.w3.org/TR/css3-grid-layout/ may be able to do exactly what I want but it is, as far as I know, only supported (somehow) in IE 10.
One simple and working solution would be to simply restructure my page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<div>
<h1 id="heading">Page heading</h1>
<header>
<span>Logo</span>
<nav>Navigation</nav>
</header>
</div>
<main aria-labelledby="heading">
<div>
Page content
</div>
</main>
<footer>
Content information
</footer>
</body>
</html>
This solution, while easily layoutable, however, has its full semantics only expressed via aria-* attributes and seems to go against the spirit of the HTML5 semantics (especially the main element).
While my example page may be simple, you can easily imagine a more complicated one where the visual position of many more elements are not in the same order as the flow order of the HTML5 markup (and nested so that the flexible box layout order property won't suffice). How would you solve the problem? Rewrite the HTML5 markup with non-semantic elements (e.g. divs) so that it corresponds more to the visual layout and then exchange the non-semantic elements by semantic ones (e.g. footer or main) wherever possible with the new structure?
I am running into the same conundrum as you, and I appreciate the frustration. I will attempt a negative answer, because I feel both of these positive ones (which say you can achieve both your ends) are missing the point.
Firstly, the way I see it, your principle difficulty is that CSS cannot move an element to a new container. The two answers fall into two categories:
Some are ultra-specific hacks (subjectively speaking) involving floats, negative margins, and/or absolute positioning which can move an item presentationally out of its container. These can be effective, but only in very specific cases. As your needs grow, it becomes difficult to maintain and it requires putting a rather large thinking cap on to address each new need or edge case that you had missed earlier. The answer by #jennifit attempts to move you in this direction. It is, I believe, the normal route taken by those trying hard to follow the spirit of semantic HTML5, which is admirable. But it can be a quagmire that makes you begin to ask exactly who you're maintaining your semantic purity for? Is it for the search engines, the screen readers, or ease of maintenance? I'll get back to this after the next classification.
Some are pragmatic rationalizations that claim to be equivalent semantically but are, in truth, a different semantic meaning. These are really semantic hacking in my opinion. #volker-e 's answer is an instance of this. He's right, this is an alternative markup that could work -- but, it doesn't equal the same semantic meaning. The h2 belongs in main as an h1 -- it makes no sense to move it within the page's header. In fact, you're saying that your heading is unrelated to your main content. This, in some ways, is worse than using that div you wanted to use, because you're making a false semantic relationship by grouping the page-header and site-header into the same semantically-significant header. A semantically meaningless container, such as div, for both header and main, is actually less perverse in my opinion.
So, getting back to what I said about who you're maintaining semantic purity for, this is the real philosophical question at play. There is often an obvious, effective, and maintainable solution without rationalized mis-uses of existing semantic elements or css 'tricks'. In your case, of having an item which is semantically a child but presentionally not a child, the answer is the one you've already put forth as a question:
Rewrite the HTML5 markup with non-semantic elements (e.g. divs) so
that it corresponds more to the visual layout and then exchange the
non-semantic elements by[sic] semantic ones (e.g. footer or main) wherever
possible with the new structure.
This is the right thing to do whether you're semantic-purity was intended for
accessibility: in this case you can achieve that in a non-hierarchical way with ARIA roles.
search engines: search engines still understand the old way to do things, so you're not going to get into SEO trouble if you follow older approaches to semantics.
maintenance: this is the reason most people are lured in by -- but the problem is, what's the point of maintainable HTML but unmaintainable CSS, or the other way around? you have no choice but to see your maintenance as a combination of both CSS and HTML, and you have to find the middle ground where they are both deranged equally when you run into a difficult presentational problem.
The only other possible answer, if you feel that HTML semantics are all that matter, is to accept the limitations that hierarchical HTML semantics places on your layout. The problem is, there is no way in CSS to re-create the layout hierarchy. Until that happens, you'll have to accept that HTML is both a presentational and a semantic language, and, therefore, semantics will always be a matter of "better" and "worse". Truly beautiful or rich or perfect semantics will be unachievable in many, if not most, layouts.
My approach would be the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a class="aural" href="#content">Jump to content</a>
<header role="banner">
<h1 class="site-logo">Logo</h1>
<nav role="navigation" aria-labelledby="nav-heading">
<h6 id="nav-heading">Navigation</h6>
<ul>…</ul>
</nav>
<h2 id="heading">Page heading</h2>
</header>
<main id="content" role="main" aria-labelledby="heading">
Page content
</main>
<footer role="contentinfo">
Content information
</footer>
</body>
</html>
and then go for a CSS ruleset like:
header h1,
header h2,
header nav {
float: right;
}
Diff:
You have appropriate accessible headings for page's content
You save otherwise seemingly useless div in header & main
You've got a nice HTML5 structure outline, which helps SEO.
I've included (was not part of the question) the navigational landmark roles as of WAI-ARIA 1.0 draft specification
I've included a skip link, which is still recommended best practice
Minor change: I know, charset value case is insensitive, but as you also write DOCTYPE uppercase, UTF-8 is the more correct value, see http://en.wikipedia.org/wiki/UTF-8#Official_name_and_variants
The first structure may still work if there is position:relative in < main > and using position:absolute on h1 with a z-index and a -ve margin. That way, the heading will always float on top in the same position in relation to the main content. While it may not be the best solution, I think it will not break the layout (?)
I was building a mockup with 960 Grid System and ran into an issue with .clearfix. I'm not a fan of having extra divs in my code to trigger clear and in ALL the documentation around .clearfix seems to presented as the solution. 960gs also comes with its own clearfix class so my expectation is that it should work. However when I apply the tag nothing happens. The clear class in an empty div works. While the clearfix class on the element I want to force a clear after fails. Given how much is out there about clearfix it must be something I'm overlooking.
Here is the source:
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<link rel="stylesheet" type="text/css" media="all" href="css/960.css" />
<link rel="stylesheet" type="text/css" media="all" href="css/text.css" />
<style type="text/css">
div > div
{
height:3em;
background-color:Lime;
}
</style>
</head>
<body>
<div class="container_12">
<div class="grid_4 clearfix"></div>
<div class="grid_4"></div>
</div>
</body>
</html>
You'll have to apply the clearfix class to the parent container for this to work.
<div class="container_12 clearfix">
<div class="grid_4"></div>
<div class="grid_4"></div>
</div>
I came back to this and want to explain what I found was the solution and what I learned from it.
So Clear fix will stop elements after the container that they are in from continuing to float. This is an interesting issue that arises from using float. However it is easy to confuse the symptom with the cause in this situation.
What you see are elements, divs, that are "floating" into one another when they should not because they are in separate containers. The assumption is that this is because you have not cleared the float. Furthermore there are many solutions to this problem that involve adding an element to the markup to "clear the float". This element usually has "clear:both" as a style and a period or " "; as it's content. This looks like it fixes the problem, but ends up being a hack to solve another issue.
The real problem is that a container that has only elements that float, ends up not having any volume. If you have two containers, one after the other, with floats it looks like the float is not being cleared because both containers collapse and the layout is broke. The solution is, however, to add an overflow property to the containers. In my case it was "overflow:auto".
The "classic" clear fix solution dose this by adding an element that does not have float and a volume so that the container that holds everything does not collapse and maintains some form of volume. However it's a hack to address the real issue of setting an overflow property.
IE8 has a known bug (per connect.microsoft.com) where typing or pasting text into a TEXTAREA element will cause the textarea to scroll by itself. This is hugely annoying and shows up in many community sites, including Wikipedia. The repro is this:
open the HTML below with IE8 (or use any long page on wikipedia which will exhibit the same problem until they fix it)
size the browser full-screen
paste a few pages of text into the TEXTAREA
move the scrollbar to the middle position
now type one character into the textarea
Expected: nothing happens
Actual: scrolling happens on its own, and the insertion point ends up near the bottom of the textarea!
Below is repro HTML (can also see this live on the web here: http://en.wikipedia.org/w/index.php?title=Text_box&action=edit)
<!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" ><body>
<div style="width: 80%">
<textarea rows="20" cols="80" style="width:100%;" ></textarea>
</div>
</body></html>
I know I can avoid this by forcing the website into IE7 compatibility mode, but what's the best other way to work around this bug while causing as few side-effects as possible?
I ended up wasting a lot of time trying to figure out the answer myself, so I figured I'd save others the trouble of answering. The trick is to use a very large value for the COLS attribute on the TEXTAREA element. Like this
<!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" >
<body>
<div style="width: 80%">
<textarea rows="20" cols="5000" style="width:100%;" ></textarea>
</div>
</body>
</html>
I also saw a workaround online to use a non-percentage width and then a percentage max-width and min-width, but that was much less impactful than the other workaround above (courtesy of Ross) which seems to work on all browsers including IE6.
more details: After an hour investigating this, the problem seems to be caused by IE8's handling of a conflict between "COLS" attribute and "width" style on a textarea element. If the width CSS is wider than the default width (font width x cols), IE8 gets confused when you add text and scrolls the textarea. If, instead, the width CSS is smaller than the default width derived from the cols attribute, then all works OK.
The subtle dependence between cols and width is perhaps what makes the problem so tricky to repro, because the same exact page would break or not break depending on the ratio of cols to width. The HTML in the quesiton actually reproes the bug on a large browser window and doesn't repro on a small one!
I think the best way to describe this bug is that if you set a width for the textarea using CSS, and this width is too different from what the COLS field would render, IE8 shows the weird problem, with the skipping scroll bar.
So, if you have cols="10" and textarea { width: 600px; }, the problem will show up because IE8 will use the width calculated by the COLS attribute for the scrolling, instead of the CSS one that's overriding the dimensions.
I just wanted to say thank you because my reputation is not 50 yet, but I had to say something I have spent 4 days on this issue. Please note this also works for an asp.net textbox with multiline enabled. I am not kidding I spent 4 LONG 8 hour days on this and now with your post you really helped resolve this MEGA BUG...
<asp:TextBox runat="server" TextMode="MultiLine" ID="tbxMyTextBox" ClientIDMode="static" Width="100%" Rows="4" Height="75px" MaxLength="5000" Columns="5000" TabIndex="3"></asp:TextBox>
Thank you so much.
I have a container div#content, which contains three divs inside. Now, how could I make sure that three divs inside have the same height? Of course, I hope each div's height could be expanded according to its content. For example:
here is what I tried
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title></title>
<style type="text/css">
#content{background-color:#DDDDD;width:100%;overflow:auto;clear:both;height:100%;}
#col1{background-color:yellow;width:10%;float:left;height:100%;}
#col2{background-color:red;width:30%;float:left;height:100%;}
#col3{background-color:#AAAAAA;width:10%;float:left;;height:100%;}
</style>
</head>
<body>
<div id="content">
<div id="col1">
<script language="javascript">
for(i=0;i<1000;i++){
document.write(i+"<br />");
}
</script>
</div>
<div id="col2">
<script language="javascript">
for(i=0;i<100;i++){
document.write(i+"<br />");
}
</script>
</div>
<div id="col3">
<script language="javascript">
for(i=0;i<10;i++){
document.write(i+"<br />");
}
</script>
</div>
I regularly get bashed by the CSS purists for this suggestion, but whenever I run into a problem like this for which – to the best of my knowledge – CSS simply doesn't offer a solution (no, "change your design" doesn't count!)...
I recommend using a table for that part of your layout.
Tables do equal vertical sizing easily and correctly across all major browsers. I'll continue to recommend them until CSS offers workable solutions for those problems.
A very useful technique for creating divs of equal height is to emulate it with a technique called "Faux Columns". This was an idea first suggested by Dan Cederholm (You can read his original article here), and has since evolved. You can see a good tutorial here. If you need it in a liquid layout environment, you might want to read this article.
Basically, the idea builds on NOT trying to force the divs to be of equal height, but have a wrapper of the three divs with a background-image that simulates the background of the columns. This approach works consistently among all modern browsers (ie6 even counts as modern in this context). The negative part is that you'll need a background image that is at least as wide as the page is allowed to expand. i.e. X pixels wide and 1px high.
First of all: if you have an equal attribute on different elements, please adhere to the DRY principle (Don't Repeat Yourself) and write it like so:
.content div{
border:1px solid #404040
}
That way you'll only have to change it in one place.
Now about your question. For a dynamic height, I'd specify that the div's should have a height of 100%, so they fill all the vertical space. This doesn't work nicely cross-browser so look for a hack that does this. If you don't want the div's to fill up the content div, put another div inside the content div and put that around the 3 divs.
So:
<div id="content">
<div class="innerContent">
<div class="1">Lorem Ipsum</div>
<div class="2">Lorem Ipsum</div>
<div class="3">Lorem Ipsum</div>
</div>
</div>
I may be wrong, but I think you either put the same values for the heights in the divs (either in percent or px) or you'll have to do some script (for example in JavaScript) that will check on the content height and set the other heights. I don't think it's doable with CSS. If I'm wrong I'd like to know the answer though:P
You could try it using css for modern browsers (display:table-cell, etc.), however, that will not work in IE6 and IE7.
If IE6 and IE7 are a requirement (I suppose it is...), you can include some javascript just for them using conditional statements and have that javascript set the height of all columns to the tallest. Not really pretty, but the percentages of IE6 and 7 should be going down fast anyway.
By the way, Machine's solution (faux columns) is another solution that works for a lot of designs.