I'm having a very frustrating situation with margins.. I have a div in the top of my markup that is floated to the right.
.grey{
float:right;
width:200px;
}
I need to apply some styles (background and margin) to the first paragraph after.
.blue{
background-color: blue;
margin: 10px;
overflow:hidden;
}
Now I have to make the paragraph "overflow: hidden" so the background doesn't extend under the floated div, but I have 2 strange problems.
the margin doesn't seem to apply to the side of the paragraph that touches the float;
the margin seems to apply to the floated element beside it..
Here's a fiddle.
http://jsfiddle.net/whiteatom/Nkfzg/6/
Could anyone tell me how to get the margin space between the "Blue" element and the floated one? and could anyone tell me how to make my floated element not have these phantom margins?
Cheers,
whiteatom
You need to apply a left margin to the floating element in order to space it away from the paragraph:
.grey {
float: right;
width: 200px;
margin-left: 10px;
}
As mentioned, margin collapse causes the top margin of your paragraph to affect the page body instead. This causes it to push both the paragraph and the floating element down.
To remove the top margin from the floating element, you have two options (choose only one):
Cancel margin collapse by floating the body:
body {
float: left;
}
This causes the margin to affect only the paragraph. Updated fiddle
Apply a negative top margin to your floating element:
.grey {
float: right;
width: 200px;
margin-left: 10px;
margin-top: -10px;
}
Here, you're shifting the floating element up to counter the margin collapse, which remains in effect. Updated fiddle
If the .grey div is always going to be 200px wide, just change the margin of the .blue div to be width + 10px. Like so:
.blue {
border: 1px solid red;
background-color: blue;
margin: 10px 210px 10px 10px;
};
Here's an updated fiddle.
Related
I try to add margin values on a div inside another div. All works fine except the top value, it seems to be ignored. But why?
What I expected:
What I get:
Code:
#outer {
width: 500px;
height: 200px;
background: #FFCCCC;
margin: 50px auto 0 auto;
display: block;
}
#inner {
background: #FFCC33;
margin: 50px 50px 50px 50px;
padding: 10px;
display: block;
}
<div id="outer">
<div id="inner">
Hello world!
</div>
</div>
W3Schools have no explanation to why margin behaves this way.
You're actually seeing the top margin of the #inner element collapse into the top edge of the #outer element, leaving only the #outer margin intact (albeit not shown in your images). The top edges of both boxes are flush against each other because their margins are equal.
Here are the relevant points from the W3C spec:
8.3.1 Collapsing margins
In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.
Adjoining vertical margins collapse [...]
Two margins are adjoining if and only if:
both belong to in-flow block-level boxes that participate in the same block formatting context
no line boxes, no clearance, no padding and no border separate them
both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
top margin of a box and top margin of its first in-flow child
You can do any of the following to prevent the margin from collapsing:
Float either of your div elements
Make either of your div elements inline blocks
Set overflow of #outer to auto (or any value other than visible)
The reason the above options prevent the margin from collapsing is because:
Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
Margins of inline-block boxes do not collapse (not even with their in-flow children).
The left and right margins behave as you expect because:
Horizontal margins never collapse.
Try using display: inline-block; on the inner div. Like so:
#outer {
width:500px;
height:200px;
background:#FFCCCC;
margin:50px auto 0 auto;
display:block;
}
#inner {
background:#FFCC33;
margin:50px 50px 50px 50px;
padding:10px;
display:inline-block;
}
What #BoltClock mentioned are pretty solid.
And Here I just want to add several more solutions for this problem.
check this w3c_collapsing margin. The green parts are the potential thought how this problem can be solved.
Solution 1
Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
that means I can add float:left to either #outer or #inner demo1.
also notice that float would invalidate the auto in margin.
Solution 2
Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
other than visible, let's put overflow: hidden into #outer. And this way seems pretty simple and decent. I like it.
#outer{
width: 500px;
height: 200px;
background: #FFCCCC;
margin: 50px auto;
overflow: hidden;
}
#inner {
background: #FFCC33;
height: 50px;
margin: 50px;
}
Solution 3
Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).
#outer{
width: 500px;
height: 200px;
background: #FFCCCC;
margin: 50px auto;
position: absolute;
}
#inner{
background: #FFCC33;
height: 50px;
margin: 50px;
}
or
#outer{
width: 500px;
height: 200px;
background: #FFCCCC;
margin: 50px auto;
position: relative;
}
#inner {
background: #FFCC33;
height: 50px;
margin: 50px;
position: absolute;
}
these two methods will break the normal flow of div
Solution 4
Margins of inline-block boxes do not collapse (not even with their in-flow children).
is the same as #enderskill
Solution 5
The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.
This has not much work to do with the question since it is the collapsing margin between siblings. it generally means if a top-box has margin-bottom: 30px and a sibling-box has margin-top: 10px. The total margin between them is 30px instead of 40px.
Solution 6
The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.
This is very interesting and I can just add one top border line
#outer{
width: 500px;
height: 200px;
background: #FFCCCC;
margin: 50px auto;
border-top: 1px solid red;
}
#inner {
background: #FFCC33;
height: 50px;
margin: 50px;
}
And Also <div> is block-level in default, so you don't have to declare it on purpose. Sorry for not being able to post more than 2 links and images due to my novice reputation. At least you know where the problem comes from next time you see something similar.
Not sure why what you have doesn't work, but you can add overflow: auto; to the outer div.
Not exactly sure why, but changing the inner CSS to
display: inline-block;
seems to work.
If you add any padding to #outer, it works. Demo here:
#outer {
width:500px;
height:200px;
background:#FFCCCC;
margin:50px auto 0 auto;
display:block;
padding-top:1px;
}
#inner {
background:#FFCC33;
margin:50px 50px 50px 50px;
padding:10px;
display:block;
}
<div id="outer">
<div id="inner">
Hello world!
</div>
</div>
Doesn't answer the "why" (has to be something w/ collapsing margin), but seems like the easiest/most logical way to do what you're trying to do would be to just add padding-top to the outer div:
#outer {
width:500px;
height:200px;
background:#FFCCCC;
margin:50px auto 0 auto;
padding-top: 50px;
}
#inner {
background:#FFCC33;
margin:0px 50px 50px 50px;
padding:10px;
}
<div id="outer">
<div id="inner">
Hello world!
</div>
</div>
Minor note - it shouldn't be necessary to set a div to display:block; unless there's something else in your code telling it not to be block.
Create new block formatting context
You can use display: flow-root on the parent element to prevent margin collapsing through the containing element as it creates new Block Formatting Context.
Changing the value of the overflow property to auto or using flexbox will have the same effect.
https://codepen.io/rachelandrew/pen/VJXjEp
Try this:
#outer {
width:500px;
height:200px;
background:#FFCCCC;
margin:50px auto 0 auto;
display:table;
}
#inner {
background:#FFCC33;
margin:50px 50px 50px 50px;
padding:10px;
display:block;
}
<div id="outer">
<div id="inner">
Hello world!
</div>
</div>
Good luck!
I guess setting the position property of the #inner div to relative may also help achieve the effect. But anyways I tried the original code pasted in the Question on IE9 and latest Google Chrome and they already give the desirable effect without any modifications.
Use padding-top:50pxfor outer div. Something like this:
#outer {
width:500px;
height:200px;
background:#FFCCCC;
margin:50px auto 0 auto;
display:table;}
Note: padding will increase the size of your div. In this case if the size of your div is important, I mean if it must have a specific height. decrease the height by 50px.:
#outer {
width:500px;
height:150px;
background:#FFCCCC;
margin:50px auto 0 auto;
display:table;}
Have you tried !important before all, it will force everything:
margin:50px 50px 50px 50px !important;
If you have a margin collapse issue, then to resolve this you can add
display: flow-root; to the parent container.
Aside from that, if margin-top is being ignored, try margin-top with a negative value, for instance: margin-top: -2px;
Just for a quick fix, try wrapping your child elements into a div element like this -
<div id="outer">
<div class="divadjust" style="padding-top: 1px">
<div id="inner">
Hello world!
</div>
</div>
</div>
Margin of inner div won't collapse due to the padding of 1px in-between outer and inner div. So logically you will have 1px extra space along with existing margin of inner div.
I have a content div, which has a paragraph_content div inside with paragraphs in it.
The content div is 1000px wide. Now the paragraph_content automatically applies the 1000px width of the content. So I can never center it with margin: 0 auto, so the text in the paragraphs get centered. Now I could do text-align: center, but then the lines doesn't show under eachother since some lines are shorter and all is centered.
I want it centered, and all text lines placed right under eachother instead of some jumping in later.
And I want it centered so that if the text get adjusted it doesn't just expand it on the right side, but that the left and the right side auto expand so all stays centered.
what I have:
#content{
width: 1000px;
float: left;
overflow: hidden;
}
#paragraph_content{
display: block;
padding: 0;
margin:0 auto;
overflow: hidden;
}
#paragraph_content p{
float: left;
font-family: Lucida Console;
font-size: 12px;
padding: 5px;
}
http://jsfiddle.net/cUx2k/
I have put borders to show the space of the content and child div. the paragraphs are taking all of the space on the right for example as is the child div. So I cant never center it in the content div.
I fixed it by:
#paragraph_content{
display: table;
margin: 0 auto;
}
Try setting display:inline-block; to #paragraph_content, along with width:100%;.
It wasn't very clear to me what is the problem with text-align:center; in your case. You can maybe help adjusting the line-height of the element if you worry about the space between lines (if I understood you correctly).
For various reasons, I have a nested ol inside of a div, where the contents of the list exceeds the size of the container.
Because the container has a fixed width, the list element's background does not exceed the viewable area of the container, yet the contents scroll properly.
I have created a jsFiddle showing a simplified example of what I'm trying to explain.
I would like the width of the contained element to match that of the overflowed content. In the jsFiddle, that would mean the red background doesn't get cut off midway.
Thanks.
div
{
border: 1px solid black;
margin: 33% auto;
overflow: scroll;
white-space: nowrap;
width: 100px;
}
div > ol
{
background: red;
width: 100%;
}
Just use display: inline-block. You can read more in the W3C specs.
Replace width:100% with display:inline-block in those two element styles.
I have a parent div inside which I have multiple divs which are children of parent div, But I don't get that why those child divs are overflowing outside the parent div,
I want parent div to adjust it's height according to the number of child divs inside it.
Heres the fiddle
Just make overflow:hidden instead of overflow:visible
Demo
Float #downloads left.
http://jsfiddle.net/CvMNH/1/
Either float #downloads left, or use overflow:hidden:
#downloads
{
background-color: #EEEEEE;
border: 1px solid #CCCDCF;
padding: 5px;
line-height: 25px;
overflow:hidden;
}
or:
#downloads
{
background-color: #EEEEEE;
border: 1px solid #CCCDCF;
padding: 5px;
line-height: 25px;
float: left;
}
overflow: hidden will make the overflowing child content simply hidden, which, I believe, is not what you are trying to achieve.
To expand the parent div to show all child content, either specify overflow: auto on the parent (may have side effects in some browsers), or put
<div style="clear: both"></div>
as the last child in your parent div.
I imagine there is a simple solution, but it eludes me. If you look at this page you will see that only the header has a grey background. The grey background is set by the #container DIV which I would like to stretch down the entire height of the page:
#container {
padding: 0;
margin: 0;
background-color: #292929;
width: 1200px;
margin: 0 auto;
}
At the moment it is only stretching over the header section of the page, and the content below is not contained within it. I imagine that is because the main content in the #content DIV has absolute positioning, which I need in order to be able to do some animations on the positioning of this div (you can see this when you hover over the nav bar image):
#content {
font-family: Lucida sans unicode !important;
color: #CECBBB;
text-align: justify;
position: absolute;
top: 210px;
padding: 20px 40px;
}
From some research it would seem that DIVs with absolute positioning are not included in the height of parent DIVs, but I am not sure how to fix this.
I'd be grateful for some help.
Thanks,
Nick
Yes, you're right. Elements with absolute positioning are not considered anymore in layout of their parent container. To understand it better, I recommend you read CSS Positioning from A List Apart.
IMHO, you have many solutions:
Use floated layout, instead of absolute positioned layout
Hardcode the height of container element
Use JavaScript to always update the height of the container element.
If you need to have #content absolutely positioned (as you state in your question) then the best way to get the background you desire is to either put the background-color: #292929 on the #content itself (you will probably need to adjust some positioning and padding to eliminate any black).
However, if the animation is the submenu at the top that opens on hover, then I suggest setting both the menu and the content divs to position: relative, and instead of animating the top position of the #content (as your script appears to be doing), animate the height of the menu (have it zero as default and animate to something like 45px high [that's what firebug showed the height to be open]).
#content {
color: #CECBBB;
font-family: Lucida sans unicode !important;
margin-top: 40px;
padding: 20px 40px;
text-align: justify;
}
add a margin-top and remove the position absolute will do this.
Expanding a bit on Cecil's answer here.
One can position divs with margins instead, in order to make sure parent grows with child.
Se this fiddle
https://jsfiddle.net/944oahmy/10/
Where the following css is used
#parent {
border: 1px solid blue;
margin-top: -5px;
margin-left: 10px;
display: inline-block;
}
#child {
border: 1px solid red;
margin-top: 75px;
margin-left: 150px;
width: 500px;
}