CSS margins add up or are combined? - css

Let's assume that we have the following code:
<div style="margin-bottom:100px;">test</div>
<div style="margin-top:100px;">test</div>
I noticed that sometimes it creates 100px of margin between elements and sometimes it's 200px (when we use certain settings that I'm not familiar with). I can't find any information about that in the specification. What does this depend on?
If we have h1 and p in a blank document then the margin of h1 will be combined with the margin of p. They will not add up. Whichever is larger will be used.

This is happening because your margins are allowed to collapse. Certain margins may overlap (mostly block elements) and form a combined margin defined by the larger of the two values defined in the computed element style rules - that's what is happening here. This section from the CSS Box Model document explains it in detail.
Edit: As a point of interest, you can get around this (ie. break the collapsible margins) without breaking things (much?)in a couple of ways
Making the elements width: 100%; display: inline-block
Putting a height: 0; width: 0; overflow: hidden block in between the elements and putting a dot or something in it.
I forked ashley's fiddle to demonstrate. There are probably other methods but these are a quick a dirty way to get around collapsible margins if you need to.

Related

Does Bootstrap add horizontal spacing to <img> by default? If so, is there a way to override this setting?

I'm designing a homepage in which I'm trying to display the same image 4 times in a single row (to make a kind of decorative banner). I have set each images' width to take up 25% of the screen. Theoretically, this means each image should take up a quarter and fit perfectly within a single row. However, I suspect Bootstrap is adding some kind of spacing between my images causing the 4th to spill over into the next one.
I have tried setting their margin to 0, setting their padding to 0, and setting their border-style to none. I figured setting the properties this way would override any defaults Bootstrap might place on the <img> tag, but this spacing does not seem to be going away. Additionally, checking the Developer Tools on my browser confirms that there is in fact no margin, padding, or border affecting my images. I'm not sure what else I can target to try and resolve this issue.
Any advice would be greatly appreciated. Thank you for your time in advance.
NOTE: I am not using Grid. I figured what I am attempting to do is simple enough to avoid having to use it.
<img class="back-banner" src="pictures/walyn-homo-erectus.jpg">
<img class="back-banner" src="pictures/walyn-homo-erectus.jpg">
<img class="back-banner" src="pictures/walyn-homo-erectus.jpg">
<img class="back-banner" src="pictures/walyn-homo-erectus.jpg">
.back-banner {
width: 25%;
opacity: .5;
padding: 0;
margin: 0;
}
Image is inline element by default. This causes it to add some white space. You can transform it to block element by using display: block, but then you need to use float: left to make them appear in one row.
Even better is to use modern css like flexbox by adding display: flex on wrapping element.

Float can't be used with display:inline-block issue [duplicate]

Is there a practical difference between whether a left-floated element (say, and image) has display: inline-block; applied to it, as opposed to leaving the default display: block; rule applied?
In other words, what's the difference between:
<div style="float: left; display: inline-block;">text</div>
and
<div style="float: left; display: block;">text</div>
?
An answer by #thirtydot might help you... Question's link
I just found out that floating an
element will also make it a block,
therefore specifying a float property
and display:block is redundant.
Yes, display: block is redundant if you've specified float: left (or right).
(What would happen if you tried to
specify display:inline and float:left?
)
display: inline will not make any difference, because setting float: left forces display: block "no matter what":
http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo
Otherwise, if 'float' has a value
other than 'none', the box is floated
and 'display' is set according to the
table below.
To summarize said table: float = display: block.
However, your specific example of float: left; display: inline is useful in one way - it fixes an IE6 bug.
Are there any other examples of
redundant combinations to watch out
for? block & width ? etc,
Some examples:
If you set position: absolute, then float: none is forced.
The top, right, bottom, left properties will not have any effect unless position has been set to a value other than the default of static.
Is there a tool that can check for
such things?
I don't think so. It's not something that is ever needed, so I can't see why anybody would have written such a tool.
You don't have to specify a float: left and a display: inline-block for the same element, you use one or the other, not both. Float is used to float text around elements, its not the best weapon to choose when doing a layout. Go with display: block, and inline-block.
http://joshnh.com/2012/02/07/why-you-should-use-inline-block-when-positioning-elements/
Block elements — form boxes according to the css box-model. They have width, height, padding, border, and margin and they stack vertically on top of each other.
Inline elements — don’t form boxes. They sit horizontally next to each other.
Inline-block elements — act like block elements on the inside where they form boxes. On the outside they act like inline elements sitting horizontally next to each other instead of stacking on top of each other.
A good resource: http://learnlayout.com/inline-block.html
According to SitePoint:
If you’re new to CSS layouts, you’d be forgiven for thinking that
using CSS floats in imaginative ways is the height of skill. If you
have consumed as many CSS layout tutorials as you can find, you might
suppose that mastering floats is a rite of passage. You’ll be dazzled
by the ingenuity, astounded by the complexity, and you’ll gain a sense
of achievement when you finally understand how floats work.
Don’t be fooled. You’re being brainwashed.
http://www.sitepoint.com/give-floats-the-flick-in-css-layouts/
When you use float: left; almost any elements behave as a block element. So there is no any difference in this particular case.

Do vertical margins collapse reliably and consistently across all browsers?

I'm trying to understand the effect that margin has on two elements. I have the following HTML, see the dabblet:
<p>some text</p>
<pre>some code</pre>
I have the following CSS:
body { color: white; }
p { background: red; margin-bottom: 50px; padding: 20px; }
pre { background: purple; margin-top: 40px; padding: 20px; }
So I've given the paragraph tag a bottom margin of 50px, and I've given the pre tag a top margin 40px. I was expecting therefore to find 90px vertical distance between them, but only have 50px.
I understand that the margins are collapsing, and that if I want to fix this then I need to add display: inline-block to the pre tag. But that causes the width of the pre tag to collapse.
Again, I know that I can fix the width problem by adding width: 100% to my pre tag, but I've got padding on the pre tag (20px), so this causes my elements to be too wide. I know that I can use box-sizing to deal with that, but what an almightly pain in the crotch it is to have to mess about with width, display and box-sizing just to have the desired amount of vertical space between two elements. So I simply refuse to do any of that.
Instead, I've decided that I'm just going to add margin-top: 90px to my pre tag, which will guarantee that I've got the 90px space that I want.
My question is: Are there any browsers out there that don't collapse margins in the way the others do? Will I inadvertently end up with 140px space (90px from the top-margin of the pre tag + 50px from the bottom margin of the paragraph tag)? In other words, are margins collapsed reliably and consistently across all browsers, or is there a browser out there that does it's own thing?
It's hard to give a definitive answer to this question because it's very broad. "All browsers" is a lot of browsers. There could always be some fringe browsers you never heard of that handle this differently. It all depends on how the browser's CSS rendering engine was written.
That said, any browser that wants to be taken seriously will try to adhere the W3C specs, which have the following to say about margin collapsing:
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, except:
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.
Horizontal margins never collapse.
Source: Box Model (w3.org)
I figured it'd be a nice addition to just put your code to the test in as many browsers as possible. I made a test page page of your html (slightly modified), with an absolutely positioned 50px high block that should fit right in between the collapsed margin, to make it easier to spot a difference:
http://files.litso.com/playground/margin.html
Then I ran this through browsershots.org to get screenshots of how browsers would display this piece of HTML:
http://browsershots.org/http://files.litso.com/playground/margin.html#
(I have no idea how long this will stay cached, but I guess you could always just run it again)
Interestingly, the positioning of the blue block is a few pixels off in a bunch of the screenshots. You can still tell the margins are collapsed correctly, but I do wonder what exactly the problem is with the positioning.
The only browsers that don't seem to collapse the margin correctly are Dillo 3.0.2 and Links 2.7 on Debian 6.0, neither of which seem to listen to padding or margin properties at all (nor to the absolute positioning for that matter). They would mess up your layout no matter what, and you shouldn't worry about it. People use browsers like these for a specific reason, and seeing your page exactly as you intended it to be seen is not one of them.
TL;DR: Yes, it's safe to say that all browsers collapse these elements reliably and consistently.

How can I style a <section> when it is followed by another <section>?

I'm using section to determine different parts of my page. These sections have a bottom margin of 90px but when a section with the ID of 'clients-full' is created/put in the page, I want whatever section that appears before/above it to have a bottom margin of 0. Can I do this using CSS selectors/pseudo selectors?
Currently, this bit of code styles the section with the ID of 'clients-full' but can it be reversed so I can apply a bottom margin of 0 to the section that is before it?
section + section#clients-full {
margin-top: -90px; // Negative margin to get around this problem...not ideal.
}
In CSS as currently defined an implemented, selectors cannot be used in a manner that selects an element depending on what comes after it, only on what comes before it. Well, selectors linke :nth-last-child(...) are an exception in a sense, but they don’t help in a case like this.
Thus, a better approach is to separate the sections by setting a top margin on them, dealing with the first section as a special case if needed (no top margin on it) and perhaps the last section, using :last-ot-type (setting bottom margin on it if needed). Then you can easily handle the case described, simply with #clients-full { margin-top: 0; }.

Three Variable-Width, Equally-Spaced DIVs? What About Four?

I have some very simple sub-navigation that I'm trying to build across the top of the content area within my web site, but CSS doesn't seem to have any simple solutions for such a common problem: I want either 3 or 4 equally spaced DIVs across the top of the page.
1) e.g. 3 Variable-Width, Equally-Spaced DIVs
[[LEFT] [CENTER] [RIGHT]]
2) e.g. 4 Variable-Width, Equally-Spaced DIVs
[[LEFT] [LEFT CENTER] [RIGHT CENTER] [RIGHT]]
My solution for the first problem with only 3 DIVs was to float the left and right DIVs, and then assign an arbitrary size to the middle DIV and give it "margin: 0 auto". That's not really a solution, but assuming there are no changes to the navigation, it gives a rough approximation of what I want the results to be.
The solution I have for the second problem with 4 DIVs is to simply center a DIV in the same way as before, but then float two DIVs within that, e.g.
[[LEFT] [[LEFT CENTER] [RIGHT CENTER]] [RIGHT]]
But again, this requires applying an arbitrary size to the middle DIV for alignment, and if any language or image changes are made to the site, alignment values will have to be recalculated. As well, it's simply an over-complicated solution that requires merging structure with presentation.
Any help is greatly appreciated.
EDIT 07/20/2012 5:00PM
Alright, I put the "table-cell" solution into place using percents, but I encountered another issue within my slightly more complex implementation: the issue at hand is that each DIV I was referring to is actually a container for two more DIVs which are icon-label pairs, inlined either by float or by display:inline-block.
e.g. http://jsfiddle.net/c3yrm/1/
As you can see, the final element in the list is displayed improperly.
Any help is again greatly appreciated!
EDIT 07/20/2012 7:16PM
Final solution with arttronics' help: http://jsfiddle.net/CuQ7r/4/
Reference: jsFiddle Pure CSS Demo
The solution was to float the individual breadcrumbs while using a simple formula to determine the percentage of breadcrumb width based on the number total breadcrumbs.
You could use percentages, then it just comes down to simple math:
[[LEFT=22%]2% margin><2% margin[LEFT CENTER=22%]2% margin><2% margin[RIGHT CENTER=22%]2% margin><2% marginRIGHT=22%]]=100%/??px
You could then specify a width for its container and use
display:inline;
to keep them inline.
Note: If you use borders to see what the divs are doing that will add space unnaccounted for so you would need to reduce your elements width by 1% or so OR just change their background colors.
ol {
width: 400px;
/*width: 800px;*/
display: table;
table-layout: fixed; /* the magic dust that ensure equal width */
background: #ccc
}
ol > li {
display: table-cell;
border: 1px dashed red;
text-align: center
}
like here: http://jsfiddle.net/QzYAr/
One way I've found to do it is using flex boxes (or inline-flex).
Here is a great explanation and example of how it can be done.
I think in the future, flex boxes will be the superior way of handling this sort of thing, but until other browsers catch up with Mozilla's way of thinking for how to use the flex-basis attribute (with min-content, max-content, fit-content, etc. as values), these flex boxes will continue to be problematic for responsive designs. For example, occasionally the inner content (a_really_really_long_word) can't fit in the allotted space when the window is squished down, and so sometimes some things might not be visible off to the right of the screen if you're not careful.
I think perhaps if you make use of the flex-wrap property, you might be able to ensure everything fits. Here is another example of how this might be done (in Mozilla browsers anyway).
I tend to use flex boxes for letterheads or tables where the width is fairly fixed (not too small) because they usually space themselves nicely; I tend to use nested float and inline-block objects for websites where the content must squish down very small (as suggested in some of the other answers here).

Resources