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 div
s inside of div
s 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:
width
withbox-sizing: content-box
width
withbox-sizing: padding-box
width
withbox-sizing: border-box
width
withbox-sizing: margin-box
(if it ever gets introduced)height
withbox-sizing: content-box
height
withbox-sizing: padding-box
height
withbox-sizing: border-box
height
withbox-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-content
toX
would setwidth
toX
- Setting
width-padding
toX
would setwidth
to:X - (PL + PR)
- Setting
width-border
toX
would setwidth
to:X - (PL + PR + BL + BR)
- Setting
width-margin
toX
would setwidth
to:X - (PL + PR + BL + BR + ML + MR)
- Getting
width-content
would returnwidth
- Getting
width-padding
would returnwidth + (PL + PR)
- Getting
width-border
would returnwidth + (PL + PR + BL + BR)
- Getting
width-margin
would returnwidth + (PL + PR + BL + BR + ML + MR)
How it would work in border-box model terms:
- Setting
width-content
toX
would setwidth
toX + (PL + PR + BL + BR)
- Setting
width-padding
toX
would setwidth
to:X + (BL + BR)
- Setting
width-border
toX
would setwidth
to:X
- Setting
width-margin
toX
would setwidth
to:X - (ML + MR)
- Getting
width-content
would returnwidth - (PL + PR + BL + BR)
- Getting
width-padding
would returnwidth - (BL + BR)
- Getting
width-border
would returnwidth
- Getting
width-margin
would returnwidth + (ML + MR)
From a different point of view the width
and height
could be seen as:
- aliases for
width-content
andheight-content
whenbox-sizing
is set tocontent-box
- aliases for
width-padding
andheight-padding
whenbox-sizing
is set topadding-box
- aliases for
width-border
andheight-border
whenbox-sizing
is set toborder-box
- aliases for
width-margin
andheight-margin
whenbox-sizing
is 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-border
in CSS,widthBorder
in JavaScriptwidth-with-border
in CSS,widthWithBorder
in JavaScriptwidth-including-border
in CSS,widthIncludingBorder
in JavaScriptwidth-border-box
in CSS,widthBorderBox
in JavaScriptwidth-bbox
in CSS,widthBbox
in 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: