The premise is that a better box model would be no box model at all, or rather no dependence on any particular box model that happens to be in use.
This proposal specifies new CSS properties that would make working with issues related to box-sizing easier and less error prone.
The inconsistencies of different box models have always caused problems and the question of which model should be used has resulted in countless arguments in the community.
Earlier versions of the Internet Explorer used a box model different than the standard model recommended by the W3C. In 2001 Internet Explorer 6 introduced the W3C recommended box model in "standards-compliant mode" while still using its old box model in "quirks mode" for backwards compatibility. This made it possible to define layouts that would look the same in all browsers (if a certain doctype was present) but it didn't make defining those layouts easy, or indeed even possible.
The problem is that it is very hard (if not outright impossible) to define certain layouts (especially fluid and responsive layouts) using the standard box model so historically people have used divs inside of divs as a workaround.
But as it turs out many of the layouts so hard to implement in the standard box model would be simple using the original box model used in Internet Explorer so in CSS3 a new box-sizing property was introduced which when set to border-box makes the box model work as in quirks mode of Internet Explorer.
Recently many ways were proposed to set the rendering to border-box by default:
Box model reset #1:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}Box model reset #2:
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}Box model reset #3:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}See:
- http://www.paulirish.com/2012/box-sizing-border-box-ftw/
- http://css-tricks.com/international-box-sizing-awareness-day/
- http://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
All of the solutions listed above have some problems. The first two break the layout of content that expects the standard box model. The last one while not breaking content that expects the standard box model for all elements (provided it is wrapped in an element whose box-sizing property is explicitly set to content-box) it will break the layout of any content that uses any non-default box-sizing for some outer elements while expecting its inner elements to have box-sizing set to content-box (the default value in CSS3 is content-box - not inherit).
Another problem is that it is not easy to write general purpose code to programatically get or set the values of width and height without taking into account which box model is in effect in which context.
The problem is that the semantics of width and height depend on the (possibly inherited) value of box-sizing.
The solution to those problems is not introducing different box models to choose from but to not rely on any box model at all.
Instead of making width and height mean different things depending on which value of box-sizing is in effect, it would be much more straightforward to have a set of properties that always mean the same thing.
This is just one possible set of names with alternatives below:
width-content- just the width of the contentwidth-padding- the width of the content and paddingwidth-border- the width of the content, padding and borderwidth-margin- the width of the content, padding, border and marginheight-content- just the height of the contentheight-padding- the height of the content and paddingheight-border- the height of the content, padding and borderheight-margin- the height of the content, padding, border and margin
This would have the same values as, respectively:
widthwithbox-sizing: content-boxwidthwithbox-sizing: padding-boxwidthwithbox-sizing: border-boxwidthwithbox-sizing: margin-box(if it ever gets introduced)heightwithbox-sizing: content-boxheightwithbox-sizing: padding-boxheightwithbox-sizing: border-boxheightwithbox-sizing: margin-box(if it ever gets introduced)
Note: 4 properties: width-content, height-content, width-border and height-border (corresponding to width and height with box-sizing: content-box and box-sizing: border-box) would be used in most cases in which currently the content-box and border-box box models are used. Properties: width-padding and height-padding would be used for cases where the padding-box box model would be used. The width-margin and height-margin are provided for completeness, to have consistent access to all of the dimensions in the box model.
div.a {
width-border: 200px;
}
div.b {
width-content: 100px;
}
div.c {
width-border: 300px;
width-content: 200px;
}It would be not only possible but trivial to set a width of one element's content to the width of other element's padding etc.
Different parts of code could manipulate the values as if the box model was best suited for the kind of operation that was needed, without interfering with each other.
The meaning of the values of the properties would not depend on values of other properties, unlike with current width and height (the meaning of which depend on the value of the own or inherited box-sizing property that is in use).
Where:
PT = padding-top
BR = padding-right
BB = padding-bottom
BL = padding-left
BT = border-top-width
BR = border-right-width
BB = border-bottom-width
BL = border-left-width
MT = margin-top
MR = margin-right
MB = margin-bottom
ML = margin-left
How it would work in standard box model terms:
- Setting
width-contenttoXwould setwidthtoX - Setting
width-paddingtoXwould setwidthto:X - (PL + PR) - Setting
width-bordertoXwould setwidthto:X - (PL + PR + BL + BR) - Setting
width-margintoXwould setwidthto:X - (PL + PR + BL + BR + ML + MR) - Getting
width-contentwould returnwidth - Getting
width-paddingwould returnwidth + (PL + PR) - Getting
width-borderwould returnwidth + (PL + PR + BL + BR) - Getting
width-marginwould returnwidth + (PL + PR + BL + BR + ML + MR)
How it would work in border-box model terms:
- Setting
width-contenttoXwould setwidthtoX + (PL + PR + BL + BR) - Setting
width-paddingtoXwould setwidthto:X + (BL + BR) - Setting
width-bordertoXwould setwidthto:X - Setting
width-margintoXwould setwidthto:X - (ML + MR) - Getting
width-contentwould returnwidth - (PL + PR + BL + BR) - Getting
width-paddingwould returnwidth - (BL + BR) - Getting
width-borderwould returnwidth - Getting
width-marginwould returnwidth + (ML + MR)
From a different point of view the width and height could be seen as:
- aliases for
width-contentandheight-contentwhenbox-sizingis set tocontent-box - aliases for
width-paddingandheight-paddingwhenbox-sizingis set topadding-box - aliases for
width-borderandheight-borderwhenbox-sizingis set toborder-box - aliases for
width-marginandheight-marginwhenbox-sizingis set tomargin-box(possibly in the futire)
And the same for height and vertical values of padding, border and margin.
Even if implementation was not easy it would make designing layouts and reasoning about content dimensions much easier than it is today, with lower possibility for error and easier maintainability.
With the @supports CSS at-rule and the CSS.supports() method it would be easier to use those new properties with backwards compatible fallbacks.
See:
- https://developer.mozilla.org/en-US/docs/Web/CSS/@supports
- https://developer.mozilla.org/en-US/docs/Web/API/CSS.supports
Some possible naming schemes for the proposed properties - on the example of the width with padding and border:
width-borderin CSS,widthBorderin JavaScriptwidth-with-borderin CSS,widthWithBorderin JavaScriptwidth-including-borderin CSS,widthIncludingBorderin JavaScriptwidth-border-boxin CSS,widthBorderBoxin JavaScriptwidth-bboxin CSS,widthBboxin JavaScript
Number 1 is short, numbers 2-4 are more descriptive. Number 5 is an abbreviation: cbox, pbox, bbox, mbox - possibly not descriptive enough for CSS and the DOM API.
The naming scheme that has the most support of the community should be chosen.
What if someone uses multiple width-properties on one element, which property should take precedence then?
For example, how should this box look like: