Closed Bug 151227 Opened 19 years ago Closed 18 years ago

CSS padding in a nested DIV with a fixed width causes overlap

Categories

(Core :: Layout, defect, P3)

x86
Windows 2000
defect

Tracking

()

RESOLVED INVALID
Future

People

(Reporter: lonewolf, Assigned: attinasi)

References

()

Details

Mozilla 1.1a

If you make a nested div, with the outer div a fixed width and the inner div a
width:100% and padding > 0, the inner div will overlap the outer div.  

I have created a test case.
This is not a bug in Mozilla: the padding width is additional to the 100%. Older
versions of IE get this wrong.
Browser, not bugzilla
Assignee: myk → attinasi
Component: User Interface → Layout
Product: Bugzilla → Browser
QA Contact: matty → petersen
Version: unspecified → other
QA Contact: petersen → amar
Priority: -- → P3
This is indeed a bug.  According to the W3C's CSS2 Specification (URL: 
http://www.w3.org/TR/1998/REC-CSS2-19980512/box.html#padding-edge): 
 
The box width is given by the sum of the left and right margins, border, and 
padding, and the content width.  
 
Thus, content that is designated width:100% should fill it's container to 100% 
exactly with no overlap, including any padding/margin/border present. 
Target Milestone: --- → Future
http://www.w3.org/TR/REC-CSS1#block-level-elements

4.1    Block-level elements

The width of an element is the width of the content, i.e., the distance between
left inner edge and right inner edge. The height is the height of the content,
i.e., the distance from inner top to inner bottom. 

4.1.2    Horizontal formatting

The horizontal position and size of a non-floating, block-level element is
determined by seven properties: 'margin-left', 'border-left', 'padding-left',
'width', 'padding-right', 'border-right' and 'margin-right'. The sum of these
seven is always equal to the 'width' of the parent element. 

---

The 'width' attribute relates to the _inner_ space of a given block-level
element. I'm not quite sure if this is only a misconception or if it contradicts
the information in
http://www.w3.org/TR/1998/REC-CSS2-19980512/box.html#padding-edge (Comment #3).
But any element with width + padding/border/margin (>0) will overlap a parent
element with the same width. Anyway, IE is doing it one way, Mozilla the other
(according to REC-CSS1 correct) way now. This has to be solved soon!
4.1 and 4.1.2 seem to contradict each other.  4.1 says that width is just the 
content alone without mentioning border/padding/margin, whereas 4.1.2 says that 
width is the sum of all.  Does 4.1.2 supercede 4.1?

Interpreting it the former way would cause, at worst case, larger than expected 
paddings around elements.  If interpreted the latter way, at worst case, it 
would cause overlap.  Since overlap is by far the less-desireable unintended 
effect, I would say that border/padding/margin should be included in width.  
Additionally, it would seem to me impossible with CSS to make a 
border/padding/margin box fill an arbitrarily-sized containing box to the pixel 
if this were not the case.
CSS2 gives us some answers that were ambiguous in CSS1.  Comment #4 refers to 
the CSS1 specification.  In the CSS2 specification, at http://www.w3.org/TR/REC-
CSS2/box.html, two different widths are referred to: the *content width* and 
the *box width*.  The box width is the sum of content/padding/margin/border, 
while the content width is just the width of the inner content.  Thus, since a 
DIV tag is a box-model container, a width of 100% means a box width of 100%, 
which should fill it's parent container's content width to 100%.

This is supported by the following:

CSS2 defines "containing block":

  10.1§2 "...unless the element is absolutely positioned, the containing block 
is formed by the content edge of the nearest block-level ancestor box."

Also, and here's where it is spelled out precisely, when a contained box is 
specified as a percentage width:

  10.2 Content width: the 'width' property

  ...

  <percentage> 
  Specifies a percentage width. The percentage is calculated with respect to 
the width of the generated box's containing block. 

And,

10.3.3 Block-level, non-replaced elements in normal flow
...The following constraints must hold between the other properties:

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

Thus, border/padding/margin must fall within the constraints of the content 
width of the parent.
As a DIV, it follows the rules of
http://www.w3.org/TR/REC-CSS2/visudet.html#Computing_widths_and_margins - 
Section 10.3.3 Block-level, non-replaced elements in normal flow

The margins are 0 (default for auto), the paddings are set at 2px, and the width
at 100%.  This is an overconstrained situation, and to resolve it you follow
this rule:

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

If all of the above have a specified value other than 'auto', the values are
said to be "over-constrained" and one of the computed values will have to be
different from its specified value. If the 'direction' property has the value
'ltr', the specified value of 'margin-right' is ignored and the value is
computed so as to make the equality true.

You start with:

auto + 0 + 2px + 100% + 2px + 0 + auto = 100%

Auto by default becomes 0, so:

0 + 0 + 2px + 100% + 2px + 0 + 0 = 100%

Since that's overconstrained, and this is an ltr document, this becomes

0 + 0 + 2px + 100% + 2px + 0 - 4px = 100%

Since the padding is drawn while the margin is transparent, the div overflows
its container.


10.2 Explicitly states that width "... specifies the _content width_ of boxes
generated by block-level and replaced elements."


Further, the draft proposal of the CSS3 box model specifically includes new
properties for the specification of box-width and box-height (width/height +
padding + borders) [currently with three different proposed mechanisms]
separately from content-width and content-height.  As such, I believe Mozilla's
behavior is correct (if occasionally frustrating), and this bug is INVALID.
Comment #7 Cites CSS2 - 10.3.3:

-begin quote-

10.3.3 Block-level, non-replaced elements in normal flow

If 'left' or 'right' are given as 'auto', their computed value is 0. The
following constraints must hold between the other properties:

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

-end quote-

This constrain MUST hold!  In essence, the CSS authors are saying that for this
type of box, the content CANNOT overflow!  This is not a constraint held upon an
HTML author, but rather a constraint held on a user agent that the generated
values of margin+padding+content cannot exceed that of the containing block. 
Thus, it would appear that the user agent must correct for "overconstrained"
formatting.  This document details HOW TO RENDER css documents, not how to write
them.

There is also a line about width = containing content width in section 10.2. 
The line is vague, and the exact implementation of it is laid out in section
10.3, so we cannot hold that the vague language of 10.2 holds precedence over
the specific language of 10.3.

The exact wording in 10.2 is "'width' - This property specifies the content
width of boxes generated by block-level and replaced elements. "

Clearly, this is intended to be a vague general description of the purpose of
the width property, not a specific rule of implementation as purported in
Comment #7,
It is all about Quirk and Standard Modes. In Standard Mode both Mozilla (1.0)
and IE 6.0 render it the same way. That is, the width attribute denotes only the
innermost elements width. Padding, border, etc. has to be added for the overall
width of the block. That way this behavior is in conformance with the CSS1 and
CSS2 standard (at least as I understand it). (It should be noted that not all
standard references describe this circumstance clear enough.)

I didn't regard this as a bug in Mozilla in the first place, but as a big
problem for web designers, if Mozilla would render content that different from
the mainstream browsers. But I didn't know that IE 6.0 runs in Quirk Mode, when
there is a XML declaration at a documents beginning. That way IE was running in
Quirk Mode (despite the correct XHTML DOCTYPE declaration), while Mozilla was in
 Standard Mode with my test pages. (Well, I didn't know about different render
modes at all then.) With both browsers in the same mode the results are correct
now. (For both, standard and quirk mode.)

If correct, bug resolution should be changed to INVALID.

I found the following links to be very helpful:

CSS Enhancements in Internet Explorer 6
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp

Doctype switching and standards compliance: An overview
http://gutfeldt.ch/matthias/articles/doctypeswitch.html
> This constrain MUST hold!

It does.  margin-right is negative in this case.  This bug is invalid.  The
description of "width" is not "vague" -- it is the definition of what the
"width" property actually means in the box model.
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.