CSS3 box-sizing: margin-box; Why not?

CssLayoutPositionW3c

Css Problem Overview


Why don't we have box-sizing: margin-box;? Usually when we put box-sizing: border-box; in our style sheets we really mean the former.


Example:

Let's say I have a 2 column page layout. Both columns have a width of 50%, but they look kind of ugly because there's no gutter (gap in the middle); Below is the CSS:

.col2 {
	width: 50%;
	float: left;
}


To apply a gutter you might think we could just set a right margin on the first of the 2 columns; something like this:

.col2:first-child {
	margin-right: 24px;
}

But this would make the second column wrap onto a new line, because the following is true:

50% + 50% + 24px > 100%

box-sizing: margin-box; would solve this issue by including margin in the calculated width of the element. I would find this very useful if not more useful than box-sizing: border-box;.

Css Solutions


Solution 1 - Css

Couldn't you use width: calc(50% - 24px); for your cols? Then set your margins.

Solution 2 - Css

I think we could have a box-sizing: margin-box. The css box model shows exactly, what are the positions of the margins of the frames.

There are minor problems - for example, the margin boxes can overlap - but they aren't hard to solve.

I think, the situation is the same, as we can see with the overflow-x & overflow-y combinations, with the absolut positionied divs in table-cells, with the combination of min|max-width|height with the box-sizing, and so on.

There are features, really simple features, which the browser developers simply doesn't develop.

IMHO, box-sizing: margin-box were a very useful feature. Another useful feature were the box-sizing: padding-box, it exists at least in the standard, but it wasn't implemented in any of the major browsers. Not even in the newest chrome!


Note: @Oriol 's comment: Firefox did implement box-sizing: padding-box. But others didn't, and it was removed from the spec. Firefox will remove it in version 50. Sad.

Solution 3 - Css

The guy at the top is asking about adding margin to the overall width, including padding and border. The thing is, margin is applied outside the box and padding and border aren't, when using border-box.

I have tried to achieve the border-margin idea. What I have found is that if using margin you can either add a class of .last to the last item (with margin, then apply a margin of zero, or use :last-child/:last-of-type). Or add equal margins all the way around (similar to the padding version above).

See examples here: http://codepen.io/mofeenster/pen/Anidc

border-box calculates the width of the element + its padding + its border as the total width. So if you have 2 divs which are 50% wide, they will be adjacent. If you add 8px padding to them, then you will have a gutter of 16px. Combine that with a wrapping element - which also has padding of 8px - you will have a nicely laid out grid with equal gutters all the way around.

See this example here: http://codepen.io/mofeenster/pen/vGgje

The latter is my favourite method.

Solution 4 - Css

I'm sure all of this is obvious, but I'll type it out anyway because...well, I need the exercise. Would the following outcome not be just as efficient as box-sizing: margin-box;:

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizing is used to control from which point the padding and border are assessed to the overall size of the element. So while it's not kosher to include px margins with a % width (as is usually always the case), it's easier to calculate what the relative percentage amount should be because you don't have to incorporate padding and borders to the defined width.

Solution 5 - Css

This is because the box-sizing attribute refers to the size of an element after computing the given dimension-specific values (padding, borders). "box-sizing: border-box" sets the height/width of an element and takes into consideration the padding as well as the border width. The scope of an element's margin is greater than the element itself, meaning it modifies the flow of the page and its surrounding elements, therefore directly altering the way the element fits within its parent relative to its sibling elements. Ultimately a "margin-box" attribute value would cause major problems and is essentially the same as setting the elements height/width directly.

Solution 6 - Css

Dimensions of block-level, non-replaced elements in normal flow must satisfy

> margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right = width of containing block

When over-constrained, browsers must adjust either the left or right margin. I think that means the width of the margin box must equal the width of the containing block (i.e. 100%).

For your case, transparent borders with box-sizing: border-box can work much like margins.

Solution 7 - Css

On Codrops there are a couple of good articles on the subject of the effect of margins and row's forced to overflow. They suggest using the rem or em unit with a normalizer css setting font size to 100% for all browsers, then when you set widths and margins it is easy to keep track of the effect on the row's width by simply making a note in comments for the total width. A conversion of 16px to 1 em is the way to calculte the targeted viewports total witdh.

Working like that for the dev stage at least and then if you want 'responsive' templates you can convert widths to % including the margin widths.

The other and often simpler way they suggest to handle gutters is to use the pseudo after and the content: ''; on each of your columns which I find works really well. If you set a div class that is the defined last column such as end you can then target that class not to have the pseudo after, or to have a wider one; which ever best suits your layout.

The added bonus of using this pseudo element method is it also gives you a target for shadows that can give a more 3d effect and greater depth to the flat image on the readers monitor as well. I am experimenting with this effect at the moment by scaling up the effects being used on buttons, 'tweaking' the gradients, and the z-index.

Solution 8 - Css

Perhaps set the border to 0% opacity using RGBA and use the border as a margin.

Solution 9 - Css

There interesting situation when using box-sizing inside body content

no content no border box gives no any value on left-right margin % recount of this two box recount algoritms

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

> Firefox versions before 57 also supported the padding-box value for > box-sizing, though this value was been removed from the specification > and later versions of the browser.

So margin-box even not planned...

Solution 10 - Css

There should be a box-sizing: margin-box;

But does the following work: Put a div around it with

      .divX{
         width:  XX%;
         display:flex;
         align-items: center;
        justify-content: center;
      } 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWeb_DesignerView Question on Stackoverflow
Solution 1 - CssSlouchView Answer on Stackoverflow
Solution 2 - CsspeterhView Answer on Stackoverflow
Solution 3 - CssMorgan FeeneyView Answer on Stackoverflow
Solution 4 - CssPlummerView Answer on Stackoverflow
Solution 5 - CssRyanView Answer on Stackoverflow
Solution 6 - CsssamView Answer on Stackoverflow
Solution 7 - CssWeedy101View Answer on Stackoverflow
Solution 8 - Cssuser3236407View Answer on Stackoverflow
Solution 9 - CssDmytro YurchenkoView Answer on Stackoverflow
Solution 10 - CssVincent van RooijenView Answer on Stackoverflow