Determine Total Margin Between Two Elements - html

On my web development quiz I got this question wrong and was wondering if anyone could explain why 10 is the correct answer?
Margin Question
Wouldn't the distance be 15px because there is a 10px margin-bottom distance on element one, and a 5px margin-top distance for element two.
10px+5px=15px
I don't really get why it's 10px.
I tried answering 15px but that was listed as incorrect.

yes, 10px is the correct answer, as the question already say's both elements' margins will overlap(Collapse) with each other, and when two different size margins collapse the bigger margin will win.
This article has a really good explanation of collapsing margins.
Mozilla doc's

Harvey,
If you reread the question carefully it gives you a hint. It says the margins overlap. when two divs have margins the smaller margin is overlapped by the larger margin. Try it.
notice below how the spacing is the same
.large {
margin-bottom: 30px;
}
#small {
margin-top: 30px;
}
<div class="large">
abc
</div>
<div id='small'>
xyz
</div>
<div class="large">
abc
</div>
<div id='small2'>
xyz
</div>

This is known as margin collapse and only occurs on vertical (top and bottom) margins.
The margins of two elements are equal to their largest and the smaller margins overlap the larger one.

Despite what logic might suggest, CSS actually doesn't add up margins, but instead it overlaps them (picks the bigger one). In your case, the two neighboring elements had margins of 10px and 5px, hence 10px was picked, and this is why the margin between the two elements is 10px, not 15px.

Related

Include margins in flex calculation?

I've this fiddle:
http://codepen.io/FezVrasta/pen/rOvpqL
<div class="r1"></div>
<div class="r2"><button>toggle</button></div>
<div class="r1 target"></div>
Where I have 3 divs inside a flexbox, each div has a margin bottom.
One of these divs can toggle (hide/show).
The problem is that the first div should not change its size theoretically, but in practice it does.
I think the problem is flex not taking in account margins.
Is there a solution using flex?
In this case the flexbox-layout is missing 10px when you're removing the bottom element (corresponding to the element's margin-bottom) .
You can overcome this adding flex-basis: 10px to .r3. that will compensate the missing 10px.
pen

padding within in a div

I simply can't figure this out: I have a div that is centered on screen with a width of 60%. Inside this div I have 3 more divs that float left with the width of 33% and have a gray bg color. The divs are filled with text and one image per div. Each div should now take 1/3 space inside the "maindiv". This works fine but as soon as I give my 3 "contentdivs" a padding so the text gets seperated a bit the third div wanders below the others. I also want a margin around my 3 divs so there is a gap between all the divs. But this only works if I give the divs a width of like 31%. As soon as I shrink my browser though, the third one pops up below the others again.
How it looks now:
How it looks with a width of 33.33%
How can fix this? I mean I set the divs to a relative width by setting the size in %. So the divs should just shrink as soon as I shrink my browser window. I tried to surround all the divs by other divs and messed around with margins and paddings but it just won't work.
Most likely it’s box model’s fault. Paddings, margins and borders can be added together in different ways. Add box-sizing:border-box to the container and its elements. Most certainly this brings about what you intended to do, and width:33.3333% wil work out as expected.
Adding margin still breaks the item? There’s another great thing called calc(). Assumed you have a margin of 8px, that’s just a few pixels too much. With calc(), you can subtract the additional margin like this:
.item{ width:calc(33.3333vw - 8px); }
Note that there must be whitespace around the minus. Try it and include your margin.
Apply box-sizing: border-box to all related elements (or the entire document, as Bootstrap does). http://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
Then, rather than margin, use padding for the outer spacing. This eliminates the need to do mental math altogether.
div {
box-sizing: border-box;
}
.one-third, .inner, .full-width {
padding: 8px;
}
.one-third {
float: left;
width: 33.333%;
}
.inner {
background-color: pink;
}
<div class="full-width">
<div class="inner">Full-width div</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
Fiddle demo
Your best bet would be to get the three columns and margins to equal 100%. This is fairly easy if you know you are only having three columns:
.item {
width:32%;
margin-left:2%;
}
.item:first-child {
margin-left:0;
}
As long as there is only three it will always add up to 100% as you are overriding the first .item. If you don't override the first item then you will have a space before your columns and the last column won't fit. Mixing pixels and percentages will give you issues in a grid (unless they're paddings and you are using box-sizing). Margin is not included in the box-sizing as it is not part of the main box model.

Always show greater margin

I have given one block a bottom margin of 25px and a top margin of 10px. The total margin should then be 35px but it is showing 25px. If I give 35px margin, then it shows the total of 35px. Why is it showing greater margin always?
Here are the code lines:
<p style="margin-bottom:25px; outline:1px dashed #000000;">aaaaaaaaaaaa</P>
<p style="margin-top:10px; outline:1px dashed #000000;">bbbbbbbbbbbbbbbb</p>
It's called "collapsing margins". This is normal, and is in accordance with the W3 standards. It says:
Margins of the root element's box do not collapse.
If the top and bottom margins of an element with clearance are
adjoining, its margins collapse with the adjoining margins of
following siblings but that resulting margin does not collapse with
the bottom margin of the parent block.
More info: http://www.w3.org/TR/CSS21/box.html#collapsing-margins
Therefore your two <p> tags:
<p style="margin-bottom:25px; outline:1px dashed #000000;">aaaaaaaaaaaa</p>
<p style="margin-top:10px; outline:1px dashed #000000;">bbbbbbbbbbbbbbbb</p>
would then collapse.
The specifications also mention cases where margins are not collapsed. For example, floated elements have non-collapsed margins:
Margins between a floated box and any other box do not collapse
And a fiddle demonstrating collapsed and non-collapsed margins:
Fiddle:http://jsfiddle.net/k8tFy/3/
(Note: you can even see the floated <p> tag is even interacting with the margin-bottom of the <h2> tag)
If short, that is how margins should work. Top and bottom margins may collapse and in that case final distance between two blocks will be equal to the width of largest margin.
For more details take a look at this part of CSS standart:
http://www.w3.org/TR/CSS2/box.html#collapsing-margins
When two or more margins collapse, the resulting margin width is the
maximum of the collapsing margins' widths.
Possible solutions:
You may simply put margin-bottom of top element to 35px, just like you described.
Another way is to make one of elements to be float:
<p style="margin-bottom:25px; outline:1px dashed #000000;clear:both;">aaaaaaaaaaaa</P>
<p style="margin-top:10px; outline:1px dashed #000000;clear:both;float:left;width:100%">bbbbbbbbbbbbbbbb</p>
Demo
Above solution based on next exception you may find on page linked above:
Margins between a floated box and any other box do not collapse (not
even between a float and its in-flow children).

Why does a negative bottom margin on an element decrease the height of parent of that element?

This might be due to margin collapsing and I know about margin collapsing, at least how it affects adjacent elements, but I don't understand how it works on nested elements when negative margins are involved.
For example, in this markup and accompanying CSS:
Markup
<div class="parent">
<div class="child">
Child 1
</div>
</div>
<div class="parent">
<div class="child negative">
Child 1
</div>
</div>
CSS
body {
background: white;
padding: 45px;
}
.parent {
border: 1px solid black;
margin-bottom: 10px;
}
.negative {
margin-bottom: -1px;
}
Live example here.
When I inspect the height of the second .parent div, I notice it is 1 pixel less than the first one. This has happened because of the negative margin on the .negative element inside it. I had a quick look at W3C and couldn't find an explanation for this behavior.
Could someone please explain what's happening here and also provide me with a link to the W3C spec section about it?
This might be due to margin collapsing and I know about margin collapsing, at least how it affects adjacent elements, but I don't understand how it works on nested elements when negative margins are involved.
Section 8.3.1 has all the details. It also covers the behavior of adjoining margins between nested boxes, as well as negative margins.
However, what you're seeing here is not the effect of margin collapse because you have negated it with a border: 1px solid black declaration in your .parent rule. That means having a border there prevents your .parent margin from collapsing with your .child.negative margin altogether.
Rather, this is simply how negative margins work. This is covered in various sections of the visual formatting model, but it's most succinctly and directly addressed in the beginning of Section 11, which summarizes it thus:
Generally, the content of a block box is confined to the content edges of the box. In certain cases, a box may overflow, meaning its content lies partly or entirely outside of the box, e.g.:
...
A descendant box has negative margins, causing it to be positioned partly outside the box.
So what's happening here, instead, is:
The absolute value of the .child.negative element's negative margin is subtracted from the .parent element's actual height (by 1px).
As a result, the .child.negative element itself overflows .parent (because its own height is not changed and the default overflow for any div is visible).
Since margin collapse does not take effect here, the margin-bottom: 10px in your .parent is unaffected. Note that while any subsequent elements in normal flow will be shifted up by 1px, this is mainly due to the negative margin of your .child.negative element; in other words, a side effect of step 1.
And that's all there is to it.
when you are using .negative { margin-bottom: -1px; } then it will moved at the top. see this example.
please refer the following link you understand easily.
http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/
body {
background: white;
padding: 45px;
}
.parent {
border: 1px solid black;
margin-bottom: 10px;
min-height: 30px;
}
.negative {
margin-bottom: 20px;
}
conclusion:
For e.g. In your case i have to added min-height:30px to parent class so that it remains fix. if moved only if you add positive margins to negative class. It just because you can see results in above figure that tells all what you need is.
see the cssdesk link click here cssdesk
Hope, it will helps you. Cheers. !!
Margins of first and last elements will apply to outer element when the outer element doesn't have border, padding and content, instead of it self.
In your case, parent node has border, so margin collapsing won't apply in this case. As you have margin-bottom = -1px for the child node inside, when calculate the outer height of the child node will be the height of its content + padding + border-width + margin. So it will be 1px less when measuring from outside. That's why the height of parent node will be 1px less than the upper example. To see it more clearly, you may apply a background to the child node, say yellow, you will find that the child node will overlap the border of the parent node.
But if you remove the border of the parent node, it will be a total different situation.
For instance to explain margin collapsing, say you have
<div style="background-color:black">
<div style="height:10px; background-color:white; margin-top: 10px"></div>
</div>
You will not see a black box of 10px height, as the outer node will be considered to have a 10px margin on top, and the inner one's margin is ignored. And for negative situation, the outer margin will decrease.
Quote from spec:
When two or more margins collapse, the resulting margin width is the maximum of the collapsing margins' widths. In the case of negative margins, the maximum of the absolute values of the negative adjoining margins is deducted from the maximum of the positive adjoining margins. If there are no positive margins, the maximum of the absolute values of the adjoining margins is deducted from zero.
For more info:
https://developer.mozilla.org/en-US/docs/CSS/margin_collapsing

Displaying elements in multiple rows using CSS

I have a fixed width container <div> that displays one or more widget <div>s. I want it to look like this:
<- grey blocks are widgets, red border is the container
Simplified, my structure in HTML looks like this:
<div id="container">
<div id="widget1">1</div>
<div id="widget2">2</div>
<div id="widget3">3</div>
<div id="widget4">4</div>
<div id="widget5">5</div>
<div id="widget6">6</div>
<div id="widget7">7</div>
</div>
Considerations
Widgets will have a fixed height e.g. 100px
Widgets will have a fixed width e.g. 100px but they may also be a multiple of that width (plus any margins crossed - see widget 1)
Widgets should be spaced nicely with a margin (or similar) e.g. 10px
I don't know how many widgets there will be (the user can assign as many or few as they like to the container).
The container is a fixed width but doesn't have any "visual" styling (the red border is there for demonstration)
Solution has to work in modern browsers (and MSIE7) and would ideally be pure CSS.
Because of consideration 4. I can't assign additional markup e.g. row div, classes (.first-child, .last-child) and because of 2. :nth-child wouldn't work AFAIK.
Things I've tried
margin-left on widgets with :first-child setting margin-left: 0 won't display a new row properly.
margin-right on widgets with :last-child setting margin-right: 0 the first row forces the container div wider and last-child isn't supported until MSIE9.
equal left and right margins (e.g. margin: 0 5px 10px) forces the container wide again.
overflow - works great in my head! Not so much with either margins or padding.
Is there a way to do this in CSS?
http://jsfiddle.net/agtb/VHXGT/
I believe you are thinking too complicated :-)
If I understand you correctly you don't need any special handling of the separate widgets. Just give the widgets an all around margin of half the spacing, and the container the same margin but negative.
#container {
width: 440px;
margin: -5px;
}
#container div {
background-color: gray;
height: 100px;
width: 100px;
float: left;
margin: 5px;
}
See http://jsfiddle.net/SGdG3/1/
set container width 400 and the first div width 200 float left, rest width 100 float left