Copyright © 2007 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
CSS (Cascading Style Sheets) describes the rendering of documents on various media. When textual documents (e.g., HTML) are laid out on visual media (e.g., screen or print), CSS models the document as a hierarchy of boxes containing words, lines, paragraphs, tables, etc. each with properties such as size, color and font.
This module describes the basic types of boxes, with their padding and margin, and the normal “flow” (i.e., the sequence of blocks of text with margins in-between). It also defines “floating” boxes, but other kinds of layout, such as tables, absolute positioning, ruby annotations, grid layouts, columns and numbered pages, are described by other modules. Also, the layout of text inside each line (including the handling of left-to-right and right-to-left scripts) is defined elsewhere.
Boxes may contain either horizontal or vertical lines of text. Boxes of different orientations may be mixed in one flow. (This is a level 3 feature.)
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
The (archived) public mailing list www-style@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “css3-box” in the subject, preferably like this: “[css3-box] …summary of comment…”
This document was produced by the CSS Working Group (part of the Style Activity).
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This module should eventually replace corresponding parts of the revised CSS level 2 specification [CSS21]. But this is an early draft and any differences to level 2 are most likely unintentional, unless they concern new features, such as vertical text or the marquee effect. Please help us improve the next draft by pointing out such differences.
visible
’
Auto
’ heights for flow roots
This CSS module depends on the following other CSS modules:
Note: The model in this specification differs from the model described in the CSS level 2 specification [CSS21], because (1) it is generalized to apply also to vertical text and (2) it adds properties to control the marquee effect, (speed, direction, etc.). The marquee effect is allowed, but UA-dependent in level 2.
CSS assumes that the document to lay out is modeled as a tree of elements. Each element has an ordered list of zero or more child elements, with an optional string of text before the list, in-between the children and after the list. The unique element that has no parent is called the root element.
CSS describes how each element and each string of text is laid out by transforming the document tree into a tree of rectangular boxes, whose size and position depends on their properties. There are block-level boxes, line boxes and inline-level boxes. A block-level box is like a paragraph. A line box is like a line of text. And inline-level boxes are like words inside a line.
The precise rules are below and in other modules, but in summary, a block-level box contains either other block-level boxes (e.g., a section containing paragraphs, or a table containing rows), or it contains line boxes (e.g., a paragraph containing lines of text). A line box contains inline-level boxes (e.g., a line with words in different styles). An inline-level box may contain either text interspersed with more inline-level boxes, or it may contain a block-level box (e.g., a small table that is rendered inline).
The tree of boxes closely mirrors the tree of elements. Each element is transformed into zero or more boxes. If the element is not the root element, then each of its boxes is either a child of a box of the parent element, or it is a child of a box of the element itself. In other words, there may be more or fewer boxes than there are elements, but each box belongs to exactly one element.
For example, a fragment of HTML such as
<ul> <li>The first item in the list. <li>The second item. </ul>
may result in one block-level box for the ul
element,
containing two block-level boxes for the two li
elements,
each of which has one line box (i.e., one line of text). Both line boxes
contain two inline-level boxes: one that contains the list bullet and one
that contains the text.
Note how the li
is transformed into multiple boxes,
including one that contains “generated content,” viz., the
list bullet, which is not present in the source document.
If the document is rendered in a narrow window, it may be that the
li
elements get transformed into even more boxes, because
the text requires multiple lines. And if the document is rendered on
paper, it may be that a page break falls in the middle of the
ul
element, so that it is not transformed into a single
block-level box, but into two smaller ones, each on a different page.
Properties are set on elements and influence how the element is turned into boxes, but in this specification we refer interchangeably to “the P property of an element” and “the P property of a box” (both of which actually mean “the value of property P of…”), unless it is important to distinguish the box and the element, e.g., because the element has several boxes and they don't all have the same value for the property.
Boxes have padding, a border and margins (see the figure). Different properties determine the thickness of each of these (which may be zero).
Each box has a content area. The rectangle that bounds this area is the content edge. Around the content area is the padding area and its outside bounds are called the padding edge. Outside the padding is the border area and the outside boundary of that area is the border edge. Finally, outside the border is the margin area and its outer edge is the margin edge.
When the specification says that the padding or border is “absent” on some side of the box, that actually means that its thickness is zero.
Note that the margin, unlike the border and padding, may have a negative thickness. That is one way to make adjacent boxes overlap each other.
A box is horizontal if its ‘block-progression’
property is ‘tb
’, otherwise it is vertical.
All sections are normative, unless stated otherwise.
Examples look like this and normally start with the word “Example.” Examples are not normative.
Notes look like this and normally start with the word “Note.” Notes are not normative.
Editorial notes look like this. They will be removed before the document becomes Candidate Recommendation.
Each property is defined in part in the text and in part by a table that groups together a number of facts about the property, including a regular expression to restrict its syntax. See [where?] for the meaning. The “Inherited” and “Initial” rows in the table are used by the Cascading and Inheritance module [CSS3CASCADE] and “Media” by the Media Queries specification [MEDIAQ].
The specification may refer to the used value and the computed value of a property. Unless stated explicitly, the short form “value” means the computed value.
Name: | display |
Value: | inline | block | inline-block | list-item | run-in | compact | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | ruby | ruby-base | ruby-text | ruby-base-group | ruby-text-group | <template>| none |
Initial: | inline |
Applies to: | all elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual (‘none ’ applies to all media)
|
Computed value: | specified value, except for floats, root elements and positioned elements; see text |
This property, in combination with ‘float’ and ‘position’, determines the type of box or boxes that are generated for an element. The values are as follows:
Note that ‘none
’ does not create an invisible box; it
creates no box at all. See ‘visibility’ for a mechanisms that enables an
element to generate boxes that affect formatting but are not visible
themselves.
The computed value is the same as the specified value, except when
‘float’ is not
‘none
’ or when the
element is the root element. In those cases,
the computed value is as follows:
Specified value | Computed value |
---|---|
inline-table | table |
inline, run-in, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block | block |
others | same as specified |
The value of ‘position’ may also influence the computed value. See [CSS3TBL].
none
’, then
‘float’ and ‘position’ do not apply.
static
’ nor ‘relative
’, then ‘display’ is set according to the table above.
(And float does not apply.)
none
’, then ‘display’ is set according to the table above.
A block-level box is a box that has a used value for ‘display’ of ‘block
’, ‘list-item
’, ‘table
’, ‘table-*
’ (i.e., all table boxes) or <template>. A block-level element is
an element all of whose top-level non-anonymous boxes are block-level.
An inline-level box is a box that has a used value for ‘display’ of ‘inline
’, ‘inline-block
’, ‘inline-table
’ or
‘ruby
’. [What about the other ruby values?]
An anonymous box, informally, is a box that cannot be addressed with CSS selectors. All its properties, except for ‘display’, have their default values (either the initial value or inherited). Anonymous boxes are created when the CSS box model requires a child box with a certain value for ‘display’, but the child actually has a different value. In that case an anonymous box of the right kind is created and wraps the child (or children). Other modules (e.g., [CSS3TBL], [CSS3TEXT]) may also define anonymous boxes. The anonymous boxes defined by this module are the following:
block
’.
An example of the last point above is this document fragment:
<p>Somebody whose name I have forgotten, said, long ago: <q>a box is a box,</q> and he probably meant it.</p>
with these style rules:
p { display: block } q { display: block; margin: 1em }
The p
element has both line boxes and a child box for the
q
element, which is a block-level element. The line boxes
before the q
are wrapped in an anonymous block-level box and
so are the line boxes after the q
. The resulting tree of
boxes might be as follows (refer to the figure):
Note that the anonymous boxes defined in this module are all block-level, but anonymous boxes defined in other modules may be different.
The containing block of a box is a rectangle that is associated with the box and that is used in various definitions in this specification. Apart from a size and a position, the rectangle also has ‘direction’ and ‘block-progression’ properties. The containing block of a box is defined as follows:
Note that the above is modified by the Absolute Positioning
module [CSS3POS]:
in particular, if a box's ‘position’ property is neither ‘static
’ nor ‘relative
’, its containing block is established
differently.
A flow root is a box that satisfies at least one of the following:
none
’.
visible
’.
table-cell
’, ‘table-caption
’ (see
[CSS3TBL]),
‘inline-block
’ or ‘inline-table
’.
static
’ nor ‘relative
’ (see [CSS3POS]).
lr
’ or ‘rl
’ and
the value of ‘block-progression’ of its parent box
is ‘tb
’
tb
’ and the value of ‘block-progression’ of its parent box
is ‘lr
’ or ‘rl
’.
Note that an element with ‘display:
inline
’ therefore cannot be a flow root: it doesn't float
(otherwise its ‘display’
would be ‘block
’),
and neither ‘overflow’
nor ‘block-progression’ apply to inlines.
The terminology in the CSS level 2 specification is different. A flow root is called “an element that establishes a new formatting context.”
Other modules may define additional flow roots. [Can
we thus remove ‘table-caption
’, ‘table-cell
’, and
‘position’ from the
list above?]
The flow (a.k.a. normal flow) of a given flow root is a set of boxes. A box belongs to the flow if:
block
’, ‘list-item
’, ‘table
’ or <template>.
none
’.
static
’ or ‘relative
’.
For example, the fragment
<div class=sidebar> <p>Text in a sidebar. <p>Here is quote: <blockquote lang=ja> <p>... </blockquote> <p>Etc. etc. </div>
with the style
div.sidebar { block-progression: tb; float: left } blockquote[lang|=ja] { block-progression: rl; height: 10em }
defines two flows:
div
is a flow root, because it floats. Its flow
consist of the 1st, 2nd and 4th p
and the
blockquote
.
blockquote
is vertical, while its parent is
horizontal and it is thus a flow root. Its flow is formed by the 3rd
p
.
(The div
itself belongs to a third flow, but its flow root
is not shown in the fragment.)
Note that a flow root is not necessarily block-level, it may
be an ‘inline-block
’, e.g.
The boxes of a flow are laid out inside their flow root one after the
other in the direction of the ‘block-progression’ property of the
flow root and in the same order as in the source document. Their position
is given by how much their margins overlap (see “Collapsing margins”) and by the fact
that their side margin edges coincide with content edges of their
containing blocks. More precisely: Each box's left and right margin edges
coincide with the left and right content edges of its containing block (if
the flow root is ‘tb
’), or its top and
bottom margin edges coincide with the top and bottom content edges of its
containing block (if the flow root is ‘rl
’ or ‘lr
’).
[Define viewport and canvas]
A run-in box behaves as follows:
A ‘run-in
’ box
is useful for run-in headers, as in this example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HTML> <HEAD> <TITLE>A run-in box example</TITLE> <STYLE type="text/css"> H3 { display: run-in } </STYLE> </HEAD> <BODY> <H3>A run-in heading.</H3> <P>And a paragraph of text that follows it. </BODY> </HTML>
This example might be formatted as:
A run-in heading. And a paragraph of text that follows it.
Despite appearing visually as part of the following block box, a run-in element still inherits properties from its parent in the source tree. Please consult the section on generated content for information about how run-in boxes interact with generated content. [where?]
Define here or in extended box module?
Name: | padding |
Value: | [ <length> | <percentage> ]{1,4} |
Initial: | (see individual properties) |
Applies to: | all elements |
Inherited: | no |
Percentages: | width* of containing block |
Media: | visual |
Computed value: | see individual properties |
*) if the containing block is horizontal, otherwise the height |
Name: | padding-top , padding-right, padding-bottom, padding-left |
Value: | [ <length> | <percentage> ] |
Initial: | 0 |
Applies to: | all elements |
Inherited: | no |
Percentages: | width* of containing block |
Media: | visual |
Computed value: | <length> |
*) if the containing block is horizontal, otherwise the height |
Sets the thickness of the padding area. The value may not be negative.
‘Padding’ is a shorthand for the other four properties. If ‘padding’ has four values, they are for top, right, bottom and left in that order. If left is omitted, it is the same as right. If bottom is omitted it is the same as top, if right is omitted it is the same as top.
Note that percentages on ‘padding-top’ and ‘padding-bottom’ are relative to the width of the containing block, not the height (at least in a horizontal flow; in a vertical flow they are relative to the height).
Note that percentages are not required for CSS level 2.
For example, the following two ways to set the padding of
h1
are equivalent:
h1 { padding: 0.5em } h1 { padding-top: 0.5em; padding-right: 0.5em; padding-bottom: 0.5em; padding-left: 0.5em }
Name: | margin-top , margin-right, margin-bottom, margin-left |
Value: | <length> | <percentage> | auto |
Initial: | 0 |
Applies to: | see text |
Inherited: | no |
Percentages: | width* of containing block |
Media: | visual |
Computed value: | the percentage as specified or the absolute length or ‘auto ’
|
*) if the containing block is horizontal, otherwise the height |
Name: | margin |
Value: | [ <length> | <percentage> | auto ]{1,4} |
Initial: | (see individual properties) |
Applies to: | see text |
Inherited: | no |
Percentages: | width* of containing block |
Media: | visual |
Computed value: | see individual properties |
*) if the containing block is horizontal, otherwise the height |
These properties set the thickness of the margin area. The value may be negative.
‘Margin’ is a shorthand for the other four. If ‘margin’ has four values, they set top, right, bottom and left in that order. If left is omitted, it is the same as right. If bottom is omitted, it is the same as top. If right is omitted it is the same as top.
The properties apply to all boxes except certain table-* boxes (see [CSS3TBL]) and certain inline-level boxes (see [CSS3TEXT]).
Margins must satisfy certain constraints, which means that the used value may be different from the computed value. See “Calculating widths, heights and margins.”
Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).
For example, the following two ways of setting the margins of
p
are equivalent:
p { margin: 1em 2em } p { margin-top: 1em; margin-right: 2em; margin-bottom: 1em; margin-left: 2em }
Certain adjoining margins combine to form a single margin. Those margins are said to “collapse.” Margins are adjoining if there are no nonempty content, padding or border areas or clearance to separate them.
For example, in the following fragment with the given style rules:
p { display: block; margin: 2em 0 1em 0 } div { display: block; margin: 2.5em 0 } ... <p>First paragraph</p> <div> <p>Second paragraph</p> </div>
the bottom margin of the first p
(=1em), the top margin of
the div
(=2.5em) and the top margin of the second
p
(=2em) collapse. The result is a single margin of 2.5em
(the maximum of the three) between the bottom of the first p
and the top of the second.
[add image]
In the following fragment,
p { display: block; margin: 2em 0 1em 0 } div { display: block; margin: 2.5em 0; border: thin solid } ... <p>First paragraph</p> <div> <p>Second paragraph</p> </div>
the bottom margin of the first p
and the top margin of the
div
collapse, but the top margin of the second
p
does not collapse with them, because it is not adjoining;
the border of the div
separates them.
[add image]
If a set of adjoining margins collapses, then the width of the resulting margin is M - N, where M is the maximum of the adjoining margins that are positive, or zero if there are none; and N is the minimum of the adjoining margins that are negative, or zero if there are none.
We call an element or box collapsed through if two of its margins collapse with each other.
The most common use of collapsing through elements is that empty paragraphs don't cause extra white space:
<p>First paragraph <p>Second paragraph <p> <p>Last paragraph
There is equal space between the first and second paragraphs as between the second and last.
The following two sets of rules determine which margins collapse.
visible
’ do not collapse
with its children's margins.
inline-block
’ box do not collapse
(not even with its in-flow children). Assuming the
first rule above (“only block-level”) is correct, this rule seems
redundant, because an inline block is not block-level.
Except when forbidden by the list above, the following margins collapse:
If a margin P collapses with a margin Q and margin Q with a margin R, then P, Q and R collapse together. (“Collapsing is transitive”)
The top margin of a box A collapses with the top margin of its parent
box B if the margins are adjoining and B is ‘tb
’.
Note that A itself may be vertical box.
The bottom margin of a box A collapses with the bottom margin of its
parent box B if the margins are adjoining and B is ‘tb
’.
The left margin of a box A collapses with the left margin of its
parent box B if the margins are adjoining and B is ‘rl
’ or ‘lr
’.
The right margin of a box A collapses with the right margin of its
parent box B if the margins are adjoining and B is ‘rl
’ or ‘lr
’.
The top margin of a box A collapses with the bottom margin of a
sibling box B if the margins are adjoining and their parent is
‘tb
’.
A right margin of a box A collapses with the left margin of a sibling
box B if the margins are adjoining and their parent is ‘rl
’ or ‘lr
’.
The top and bottom margins of a box A collapse if the margins are
adjoining and the box is ‘tb
’. (The
box is “collapsed through.”)
In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.
Note that the positions of elements that have been collapsed through have no effect on the positions of the other elements with whose margins they are being collapsed; the top border edge position is only required for laying out descendants of these elements.
The left and right margins of a box A collapse (“collapse
through”) if the margins are adjoining and the box is ‘rl
’ or ‘lr
’.
In this case, the position of the element depends on its relationship with the other elements whose margins are being collapsed.
rl
’:
lr
’:
In a horizontal flow, the bottom margin of an in-flow block-level element is always adjoining to the top margin of its next in-flow block-level sibling, unless that sibling has clearance:
<p style="margin-bottom: 2em">The bottom margin of this box…</p> <p style="margin-top: 3em">… collapses with the top margin of this box, to yield max(2em, 3em) = 3em margin.</p>
The top margin of an in-flow block-level element is adjoining to its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance:
<div style="margin-top: 2em; padding: 0; border: 0"> <p style="margin-top: 3em"> The top margin of the DIV and the P collapse, to yield max(2em, 3em) = 3em margin. </p> </div>
The bottom margin of an in-flow block-level element with a ‘height’ of ‘auto
’ and ‘min-height’ less than the element's used
height and ‘max-height’ greater than the element's used
height is adjoining to its last in-flow block-level child's bottom margin
if the element has no bottom padding or border:
<div style="margin-bottom: 2em; padding: 0; border: 0; height: auto; min-height: 0; max-height: 100em"> <p style="margin-bottom: 3em"> The bottom margin of the DIV and the P collapse, to yield max(2em, 3em) = 3em margin. </p> </div>
An element's own margins are adjoining if the ‘min-height’ property is zero, and it has
neither vertical borders nor vertical padding, and it has a ‘height’ of either 0 or
‘auto
’, and it does not contain a line
box, and all of its in-flow children's margins (if any) are adjoining:
<div style="margin-top: 2em; margin-bottom: 3em"> <p style="position: absolute"> The DIV is empty and its top and bottom margins collapse. </p> </div>
When an element's own margins collapse, and that element has had clearance applied to it, its top margin collapses with the adjoining margins of subsequent siblings but that resulting margin does not collapse with the bottom margin of the parent block:
<div style="margin-bottom: 2em"> <p style="float: left"> The margins of the next two Ps collapse <p style="clear: left; margin-top: 4em; margin-bottom: 3em"> </p> <p style="margin-top: 1em; margin-bottom: 1em"> </p> </div>
The top and bottom margins of the two empty Ps collapse all together. But they can't collapse with the bottom of the DIV, because one of the two empty P's has clearance.
Check this. This is probably the only possible interpretation of the rules, but it is certainly not obvious that the clearance of one element may stop later elements from collapsing…
Collapsing is based on the used value of ‘padding’, ‘margin’, and ‘border’ (i.e., after resolving any percentages). The collapsed margin is calculated over the used value of the various margins.
Name: | width |
Value: | <length> | <percentage> | auto |
Initial: | auto |
Applies to: | all elements but non-replaced inline elements, table rows, and row groups |
Inherited: | no |
Percentages: | refer to width of containing block |
Media: | visual |
Computed value: | the percentage or ‘auto ’ as
specified or the absolute length; ‘auto ’ if the property does not apply
|
Name: | height |
Value: | <length> | <percentage> | auto |
Initial: | auto |
Applies to: | all elements but non-replaced inline elements, table columns, and column groups |
Inherited: | no |
Percentages: | see prose |
Media: | visual |
Computed value: | the percentage or ‘auto ’ (see
prose under <percentage>) or the absolute length; ‘auto ’ if the property does not apply
|
These properties specify the width and height of the content area, padding area or border area (depending on ‘box-sizing’) of certain boxes.
Values have the following meanings:
Do we want to define unknown percentages in CSS3? Something
simple, such as ‘auto
’, or something
more fancy, such as trying to solve percentages?
Negative values are illegal.
For example, the following rule fixes the content width of paragraphs at 100 px:
p { width: 100px }
Name: | min-width, min-height |
Value: | <length> | <percentage> | inherit |
Initial: | 0 |
Applies to: | all elements but non-replaced inline elements, table rows, and row groups |
Inherited: | no |
Percentages: | refer to width, resp. height of containing block |
Media: | visual |
Computed value: | the percentage as specified or the absolute length |
Name: | max-width, max-height |
Value: | <length> | <percentage> | none |
Initial: | none |
Applies to: | all elements but non-replaced inline elements, table rows, and row groups |
Inherited: | no |
Percentages: | refer to width, resp. height of containing block |
Media: | visual |
Computed value: | the percentage as specified or the absolute length or ‘none ’
|
These properties allow authors to constrain content widths and heights to a certain range. Values have the following meanings:
Negative values are illegal.
The following two algorithms define the used value of ‘width’ and ‘height’ respectively and also the used values of the ‘margin’ properties and of ‘top’, ‘right’ ‘bottom’ and ‘left’.
Note that they do not affect the computed values of ‘width’ and ‘height’. Also note that in some cases the used width has to be known in order to calculate the used height, or vice versa,
For ‘width’:
For ‘height’:
However, for replaced elements with an intrinsic ratio and both
‘width’ and ‘height’ specified as ‘auto
’, the algorithm is as follows:
Select from the table the resolved height and width values for the appropriate constraint violation. Take the max-width and max-height as max(min, max) so that min ≤ max holds true. In this table w and h stand for the results of the width and height computations ignoring the ‘min-width’, ‘min-height’, ‘max-width’ and ‘max-height’ properties. Normally these are the intrinsic width and height, but they may not be in the case of replaced elements with intrinsic ratios.
Constraint violation | Resolved width | Resolved height |
---|---|---|
none | w | h |
w > max-width | max-width | max(max-width * h/w, min-height) |
w < min-width | min-width | min(min-width * h/w, max-height) |
h > max-height | max(max-height * w/h, min-width) | max-height |
h < min-height | min(min-height * w/h, max-width) | min-height |
(w > max-width) and (h > max-height), where (max-width/w ≤ max-height/h) | max-width | max(min-height, max-width * h/w) |
(w > max-width) and (h > max-height), where (max-width/w > max-height/h) | max(min-width, max-height * w/h) | max-height |
(w < min-width) and (h < min-height), where (min-width/w ≤ min-height/h) | min(max-width, min-height * w/h) | min-height |
(w < min-width) and (h < min-height), where (min-width/w > min-height/h) | min-width | min(max-height, min-width * h/w) |
(w < min-width) and (h > max-height) | min-width | max-height |
(w > max-width) and (h < min-height) | max-width | min-height |
Then apply the appropriate rules in the subsections below, as if ‘width’ and ‘height’ were computed as these values.
Note that some values of the ‘image-scaling’ property ([CSS3PAGE]) may further change the used values of ‘width’ and ‘height’.
The following subsections apply if the element's containing block is horizontal. If it is vertical, the same rules apply, but with every occurrence of “left” replaced by “top,” “right” by “bottom,” “top” by “right,” “bottom” by “left”, “height” by “width” and “width” by “height.”
The ‘width’ and
‘height’ properties do
not apply. For each of ‘left’, ‘right’, ‘top’, ‘bottom’, ‘margin-left’, ‘margin-right’, ‘margin-top’ and ‘margin-bottom’, the used value is equal to
the computed value, except that a computed value of ‘auto
’ becomes a used value of ‘0
’.
Note that this section applies equally when the containing block is horizontal as when it is vertical.
The used values of ‘margin-left’, ‘margin-right’, ‘margin-top’ and ‘margin-bottom’ are equal to the computed
value, except that a computed value of ‘auto
’ becomes a used value of ‘0
’.
If ‘height’ and
‘width’ both have computed
values of ‘auto
’ and the element also
has an intrinsic width, then that intrinsic width is the used value of
‘width’.
If ‘height’ and
‘width’ both have computed
values of ‘auto
’ and the element also
has an intrinsic height, then that intrinsic height is the used value of
‘height’.
If ‘height’ and
‘width’ both have computed
values of ‘auto
’ and the element has no
intrinsic width, but does have an intrinsic height and intrinsic ratio; or
if ‘width’ has a computed
value of ‘auto
’, ‘height’ has some other computed
value, and the element has an intrinsic ratio; then the used value of
‘width’ is:
(used height) * (intrinsic ratio)
If ‘height’ and
‘width’ both have computed
values of ‘auto
’ and the element has no
intrinsic height, but does have an intrinsic width and intrinsic ratio; or
if ‘height’ has a
computed value of ‘auto
’, ‘width’ has some other computed
value, and the element has an intrinsic ratio; then the used value of
‘height’ is:
(used width) / (intrinsic ratio)
If ‘height’ and
‘width’ both have computed
values of ‘auto
’ and the element has an
intrinsic ratio but no intrinsic height or width and the containing
block's width doesn't itself depend on the replaced element's width, then
the used value of ‘width’
is calculated from the constraint
equation used for block-level, non-replaced elements in normal flow.
The used value for ‘height’ is: (used width) / (intrinsic ratio).
If ‘width’ has a computed value of ‘auto’, but none of the conditions above are met, then the used value of ‘width’ becomes 300px. If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
If ‘height’ has a computed value of ‘auto’ and none of the rules above define its used value, then the used value of ‘height’ must be set to the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
Theoretically, a device may be wider than than 300px but not tall enough for 150px. In that case the resulting replaced element will be too tall. But this is the formulation in CSS 2.1 and it seems not worth improving such an edge case.
Percentage intrinsic widths are first evaluated with respect to the containing block's width, if that width doesn't itself depend on the replaced element's width. If it does, then a percentage intrinsic width on that element can't be resolved and the element is assumed to have no intrinsic width.
Note that this section applies equally when the containing block is horizontal as when it is vertical.
visible
’This section also applies to block-level
non-replaced elements in normal flow when ‘overflow’ does not compute to ‘visible
’ but has been
propagated to the viewport.
The following constraints must hold among the used values of the properties.
‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ + scrollbar width (if any) = width of containing block
If ‘width’ is not
‘auto
’ and ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + scrollbar width
(if any) (plus any of ‘margin-left’ or ‘margin-right’ that are not ‘auto
’) is larger than the width of the containing
block, then any ‘auto
’ values for
‘margin-left’ or
‘margin-right’ are,
for the following rules, treated as zero. We should drop
this paragraph. It causes blocks that are wider than their parent not to
be centered (unlike blocks that are narrower), which looks strange.
All the above properties that have a computed value other than
‘auto
’ have a used value equal to the
computed value, except if they all have a computed value other than
‘auto
’. Then the values are said to be
“over-constrained” and one of the used values will have to be
different from its computed value. If the ‘direction’ property of the containing block
has the value ‘ltr
’, the specified
value of ‘margin-right’ is ignored and the value is
calculated so as to make the equality true. If the value of ‘direction’ is ‘rtl
’, this happens to ‘margin-left’ instead.
If there is exactly one value specified as ‘auto
’, its used value follows from the equality.
If ‘width’ is set to
‘auto
’, any other ‘auto
’ values become ‘0
’ and ‘width’ follows from the resulting equality.
If both ‘margin-left’ and ‘margin-right’ are ‘auto
’, their used values are equal. This
horizontally centers the element with respect to the edges of the
containing block.
The “scrollbar width” value is only relevant if the user agent uses a scrollbar as its scrolling mechanism. See the definition of the ‘overflow’ property.
If ‘margin-top’, or
‘margin-bottom’
are ‘auto
’, their used value is 0. If
‘height’ is ‘auto
’, the height depends on whether the element
has any block-level children and whether it has
padding or borders:
If it only has inline-level children, the height is the distance between the top of the topmost line box and the bottom of the bottommost line box.
If it has block-level children, the height is the distance between the top border-edge of the topmost block-level child box that doesn't have margins collapsed through it and the bottom border-edge of the bottommost block-level child box that doesn't have margins collapsed through it. However, if the element has a nonzero top padding and/or top border, or is the root element, then the content starts at the top margin edge of the topmost child. (The first case expresses the fact that the top and bottom margins of the element collapse with those of the topmost and bottommost children, while in the second case the presence of the padding/border prevents the top margins from collapsing.) Similarly, if the element has a nonzero bottom padding and/or bottom border, then the content ends at the bottom margin edge of the bottommost child.
Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored, and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
This section applies to block-level,
non-replaced elements when ‘overflow’ does not compute to ‘visible
’ (except if the
‘overflow’ property's
value has been propagated to the viewport).
Apply the rules for block-level, non-replaced elements in normal flow, but ignore the resulting values for ‘height’, ‘margin-top’ and ‘margin-bottom’.
If ‘margin-top’, or
‘margin-bottom’
are ‘auto
’, their used value is 0. If
‘height’ is ‘auto
’, its used value is defined by “‘Auto
’ heights
for flow roots.”
The used values of ‘margin-left’, ‘margin-right’, ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that a computed value of ‘auto
’
gives a used value of 0.
The used value of ‘width’ is the computed value, unless that is
‘auto
’, when used value is the shrink-to-fit width.
The used value of ‘height’ is the computed value, unless that is
‘auto
’, when the used value is defined
by “‘Auto
’
heights for flow roots.”
For inline-block boxes, the margin box is used when calculating the height of the line box. Does this belong here?
For the purposes of this section and the next, the term static position (of an element) refers, roughly, to the position an element would have had in the normal flow. More precisely:
static
’ and ‘float’ had been ‘none’. The value is negative if the box's margin
is to the left of the containing block's edge.
But rather than actually calculating the dimensions of that hypothetical box, user agents are free to make a guess at its probable position.
For the purposes of calculating the static position, the containing block of fixed positioned elements is the initial containing block instead of the viewport, and all scrollable boxes should be assumed to be scrolled to their origin.
This constraint must hold among the used values:
‘left’ + ‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ + ‘right’ + scrollbar width (if any) = width of containing block
If all three of ‘left’,
‘width’, and ‘right’ are ‘auto
’: First set any ‘auto
’ values for ‘margin-left’ and ‘margin-right’ to 0. Then, if the ‘direction’ property of the
containing block is ‘ltr
’ set ‘left’ to the static position and apply rule number three below;
otherwise, set ‘right’ to
the static position and apply rule number
one below.
If none of the three is ‘auto
’: If
both ‘margin-left’
and ‘margin-right’
are ‘auto
’, solve the equation under
the extra constraint that the two margins get equal values, unless this
would make them negative, in which case when direction of the containing
block is ‘ltr
’ (‘rtl
’), set ‘margin-left’ (‘margin-right’) to zero and solve for
‘margin-right’
(‘margin-left’).
Should we remove the phrase starting with
“unless”? If one of ‘margin-left’ or ‘margin-right’ is ‘auto
’, solve the equation for that value. If the
values are over-constrained, ignore the value for ‘left’ (in case the ‘direction’ property of the containing block is
‘rtl
’) or ‘right’ (in case ‘direction’ is ‘ltr
’) and solve for that value.
Otherwise, set ‘auto
’ values for
‘margin-left’ and
‘margin-right’ to
0, and pick the one of the following six rules that applies.
auto
’ and ‘right’ is not ‘auto
’, then the width is shrink-to-fit. Then solve for ‘left’.
auto
’ and ‘width’ is not ‘auto
’, then if the ‘direction’ property of the containing block
is ‘ltr
’ set ‘left’ to the static
position, otherwise set ‘right’ to the static
position. Then solve for ‘left’ (if ‘direction is
’'rtl‘) or ‘right’ (if ‘direction’ is
’ltr'').
auto
’ and ‘left’ is not ‘auto
’, then the width is shrink-to-fit. Then solve for ‘right’.
auto
’, ‘width’ and ‘right’ are not ‘auto
’, then solve for ‘left’.
auto
’, ‘left’ and ‘right’ are not ‘auto
’, then solve for ‘width’.
auto
’, ‘left’ and ‘width’ are not ‘auto
’, then solve for ‘right’.
This constraint must also hold among the used values:
‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ + scrollbar height (if any) = height of containing block
If all three of ‘top’,
‘height’, and ‘bottom’ are ‘auto
’, set ‘top’ to the static position and apply rule number
three below.
If none of the three are ‘auto
’: If
both ‘margin-top’ and
‘margin-bottom’
are ‘auto
’, solve the equation under
the extra constraint that the two margins get equal values. If one of
‘margin-top’ or
‘margin-bottom’ is
‘auto
’, solve the equation for that
value. If the values are over-constrained, ignore the value for ‘bottom’ and solve for that value.
Otherwise, pick the one of the following six rules that applies.
auto
’ and ‘bottom’ is not ‘auto
’: The used value of ‘bottom’ is its computed value. The used height
is defined by “‘Auto
’ heights for flow roots.” The used
values of ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that any ‘auto
’ gives a used
value of 0. Finally, the constraint gives the used value of ‘top’.
auto
’ and ‘height’ is not ‘auto
’: The used value of ‘top’ is its static
position. The used values of ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that any ‘auto
’ gives a used
value of 0. Finally, the constraint gives the used value for ‘bottom’.
auto
’ and ‘top’ is not ‘auto
’: The used height is defined by “‘Auto
’ heights
for flow roots.” The used values of ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that any ‘auto
’ gives a used
value of 0. Finally, the constraint gives the used value of ‘bottom’.
auto
’, ‘height’ and ‘bottom’ are not ‘auto
’: The used values of ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that any ‘auto
’ gives a used
value of 0. The constraint gives the used value for ‘top’.
auto
’, ‘top’ and ‘bottom’ are not ‘auto
’: The used values of ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that any ‘auto
’ gives a used
value of 0. The constraint gives the used value for ‘height’.
auto
’, ‘top’ and ‘height’ are not ‘auto
’: The used values of ‘margin-top’ and ‘margin-bottom’ are their computed values,
except that any ‘auto
’ gives a used
value of 0. The constraint gives the used value for ‘bottom’.
The “scrollbar height” and “scrollbar width” values are only relevant if the user agent uses a scrollbar as its scrolling mechanism. See the definition of the ‘overflow’ property.
This situation is similar to the previous one, except that the element may have an intrinsic size or ratio. The sequence of substitutions is now:
auto
’, the used
value is equal to the computed value.
auto
’, then if ‘direction’ of the containing
block is ‘ltr
’, the used value of
‘left’ is its static position; else if ‘direction’ is ‘rtl
’, the used value of ‘right’ is its static
position.
auto
’, then the used value of
‘top’ is its static position.
auto
’, and ‘margin-left’ is ‘auto
’, then the used value of ‘margin-left’ is 0.
auto
’, and ‘margin-right’ is ‘auto
’, then the used value of ‘margin-right’ is 0.
auto
’ and both ‘margin-left’ and ‘margin-right’ are ‘auto
’, then the used values satisfy the extra
constraint that ‘margin-right’ and ‘margin-left’ are equal, unless this would
make them negative, in which case when the direction of the containing
block is ‘ltr
’ (‘rtl
’), the used value of ‘margin-left’ (‘margin-right’) is 0. Remove the part starting with “unless”? It looks better
to center the image.
The remaining used values, if any, follows from these two constraints:
‘left’ + ‘margin-left’ + ‘border-left-width’ + ‘padding-left’ + ‘width’ + ‘padding-right’ + ‘border-right-width’ + ‘margin-right’ + ‘right’ + scrollbar width (if any) = width of containing block
‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ + scrollbar height (if any) = height of containing block
If the first equation is over-constrained, ignore the value for either
‘left’ (in case the
‘direction’ property
of the containing block is ‘rtl
’) or
‘right’ (in case ‘direction’ is ‘ltr
’) and solve for that value.
If the second equation is over-constrained, ignore the value for ‘bottom’ and solve for that value.
Apply the rules for inline replaced elements, but ignore the resulting values for ‘margin-left’ and ‘margin-right’. To compute the used value of those, apply the rules for block-level, non-replaced elements using the used values just found for ‘width’, ‘border’ and ‘padding’ as if they were the computed values.
The used values of the margins are equal to the computed values, except
that the used values of any margins computed as ‘auto
’ are ‘0
’.
The used value of ‘width’ is equal to the computed value, except that
if ‘width’ is computed as
‘auto
’, the used value is the shrink-to-fit width.
If the computed value of ‘height’ is not ‘auto
’, the used value is the computed value.
Otherwise the used height depends on the descendants, as defined in “‘Auto
’ heights
for flow roots.”
Auto
’ heights for flow rootsIn certain cases (see the preceding sections), the height of an element is computed as follows:
If it only has inline-level children, the height is the distance between the top of the topmost line box and the bottom of the bottommost line box.
If it has block-level children, the height is the distance between the top margin-edge of the topmost block-level child box and the bottom margin-edge of the bottommost block-level child box.
Absolutely positioned children are ignored, and relatively positioned boxes are considered without their offset. Note that the child box may be an anonymous block box.
In addition, if the element has any floating descendants whose bottom margin edge is below the bottom, then the height is increased to include those edges. Only floats that are children of the element itself or of descendants in the normal flow are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.
Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS does not define the exact algorithm. Thirdly, find the available width: in this case, this is the width of the containing block minus the used values of ‘margin-left’, ‘border-left-width’, ‘padding-left’, ‘padding-right’, ‘border-right-width’, ‘margin-right’, and the widths of any relevant scroll bars.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
Define in more detail, using a text by David Baron.
(This section is not normative.)
A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or “floating” box) is that content may flow along its side (or be prohibited from doing so by the ‘clear’ property). Content flows down the right side of a left-floated box and down the left side of a right-floated box. The following is a (non-normative) introduction to float positioning and content flow; the exact rules governing float positioning are given in the next section.
A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float. If there is a line box, the top of the floated box is aligned with the top of the current line box.
If there isn't enough horizontal room for the float, it is shifted downward until either it fits or there are no more floats present.
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float didn't exist. However, line boxes created next to the float are shortened to make room for the margin box of the float. If a shortened line box is too small to contain any further content, then it is shifted downward until either it fits or there are no more floats present. Any content in the current line before a floated box is re-flowed in the first available line on the other side of the float. In other words, if inline boxes are placed on the line before a left float is encountered that fits in the remaining line box space, the left float is placed on that line, aligned with the top of the line box, and then the inline boxes already on the line are moved accordingly to the right of the float (the right being the other side of the left float) and vice versa for rtl and right floats.
In the following document fragment, the containing block is too narrow to contain the content next to the float, so the content gets moved to below the floats where it is aligned in the line box according to the text-align property.
p { width: 10em; border: solid aqua; } span { float: left; width: 5em; height: 5em; border: solid blue; } ... <p> <span> </span> Supercalifragilisticexpialidocious </p>
This fragment might look like this:
Several floats may be adjacent, and this model also applies to adjacent floats in the same line.
The following rule floats all IMG boxes with class="icon"
to the left (and sets the left margin to ‘0
’):
img.icon { float: left; margin-left: 0; }
Consider the following HTML source and style sheet:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HTML> <HEAD> <TITLE>Float example</TITLE> <STYLE type="text/css"> IMG { float: left } BODY, P, IMG { margin: 2em } </STYLE> </HEAD> <BODY> <P><IMG src=img.png alt="This image will illustrate floats"> Some sample text that has no other... </BODY> </HTML>
The IMG box is floated to the left. The content that follows is formatted to the right of the float, starting on the same line as the float. The line boxes to the right of the float are shortened due to the float's presence, but resume their “normal” width (that of the containing block established by the P element) after the float. This document might be formatted as:
Formatting would have been exactly the same if the document had been:
<BODY> <P>Some sample text <IMG src=img.png alt="This image will illustrate floats"> that has no other... </BODY>
because the content to the left of the float is displaced by the float and re-flowed down its right side.
As stated in “Collapsing margins,” the margins of floating boxes never collapse with margins of adjacent boxes. Thus, in the previous example, vertical margins do not collapse between the P box and the floated IMG box.
The contents of floats are stacked as if floats generated new stacking contexts, except that any elements that actually create new stacking contexts take part in the float's parent's stacking context. A float can overlap other boxes in the normal flow (e.g., when a normal flow box next to a float has negative margins). When this happens, floats are rendered in front of non-positioned in-flow blocks, but behind in-flow inlines.
Here is another illustration, showing what happens when a float overlaps borders of elements in the normal flow.
The following example illustrates the use of the ‘clear’ property to prevent content from flowing next to a float.
Assuming a rule such as this:
p { clear: left }
formatting might look like this:
Name: | float |
Value: | left | right | none | <page-floats> |
Initial: | none |
Applies to: | all, but see 9.7 |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
This property specifies whether a box should float to the left, right, or not at all. It may be set for any element, but only applies to elements that generate boxes that are not absolutely positioned. The values of this property have the following meanings:
[To do: copy from CSS2 [CSS21] and generalize to vertical text]
Note that a box with a value of ‘float’ other than ‘none
’ is a flow
root.
The border box of a table, a block-level
replaced element, or an element in the normal flow that is a flow root (such as an element with ‘overflow’ other than
‘visible
’) must
not overlap any floats in the same flow as the element itself. If
necessary, implementations should clear the said element by placing it
below any preceding floats, but may place it adjacent to such floats if
there is sufficient space, by increasing one margin and
decreasing the opposite margin. (“Sufficient space” means that the
opposite margin does not become negative.)
Name: | clear |
Value: | none | left | right | both |
Initial: | none |
Applies to: | block-level elements |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
[To do: copy from CSS2 [CSS21] and generalize to vertical text]
In the preceding sections, several things (such as flow roots) depend on the value of ‘overflow’. We probably need to rewrite them in terms of “overflow-x and/or -y” or similar.
Name: | overflow-x, overflow-y, |
Value: | visible | hidden | scroll | auto | no-display | no-content |
Initial: | visible |
Applies to: | non-replaced block-level
elements and non-replaced ‘inline-block ’ elements
|
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified, except ‘visible’, see text |
Name: | overflow |
Value: | [ visible | hidden | scroll | auto | no-display | no-content ]{1,2} |
Initial: | see individual properties |
Applies to: | non-replaced block-level
elements and non-replaced ‘inline-block ’ elements
|
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified, except ‘visible’, see text |
These properties specify whether content is clipped when it overflows the element's content area. It affects the clipping of all of the element's content except any descendant elements (and their respective content and descendants) whose containing block is the viewport or an ancestor of the element. ‘Overflow-x’ determines clipping at the left and right edges, ‘overflow-y’ at the top and bottom edges.
‘Overflow’ is a shorthand. If it has one keyword, it sets both ‘overflow-x’ and ‘overflow-y’ to that keyword; if it has two, it sets ‘overflow-x’ to the first and ‘overflow-y’ to the second. Keywords have the following meanings:
auto
’ value is
UA-dependent, but should cause a scrolling
mechanism to be provided for overflowing boxes.
display: none
’
were specified. [This idea is due to Till Halbach
<tillh@opera.com>, July 21, 2005]
visibility:
hidden
’ were specified. [This idea is due to Till Halbach
<tillh@opera.com>, July 21, 2005]
Even if ‘overflow’
is set to ‘visible
’, content may be clipped to a
UA's document window by the native operating environment.
UAs must apply the ‘overflow’ property set on the root element to
the viewport. HTML UAs must instead apply the ‘overflow’ property from the BODY element to
the viewport, if the value on the HTML element is ‘visible
’. The ‘visible
’ value when used
for the viewport must be interpreted as ‘auto
’. The element from which the value is
propagated must have a used value for ‘overflow’ of ‘visible
’.
The para above is from CSS 2.1. Need to check if the introduction of overflow-x/y changes anything.
In the case of a scrollbar being placed on an edge of the element's box, it should be inserted between the inner border edge and the outer padding edge. The space taken up by the scrollbars affects the computation of the dimensions in the rendering model.
A UA may use multiple scrolling mechanisms at the same time. E.g., if content overflows both to the right and to the bottom, it may use a marquee effect for the overflow to the right and a scrollbar for the overflow to the bottom.
Note that a box with ‘overflow’ other than ‘visible
’ is a flow root.
Consider the following example of a block quotation (<blockquote>) that is too big for its containing block (established by a <div>). Here is the source:
<div> <blockquote> <p>I didn't like the play, but then I saw it under adverse conditions - the curtain was up.</p> <cite>- Groucho Marx</cite> </blockquote> </div>
Here is the style sheet controlling the sizes and style of the generated boxes:
div { width : 100px; height: 100px; border: thin solid red; } blockquote { width : 125px; height : 100px; margin-top: 50px; margin-left: 50px; border: thin dashed black } cite { display: block; text-align : right; border: none }
The initial value of ‘overflow’ is ‘visible
’, so the <blockquote> would
be formatted without clipping, something like this:
Setting ‘overflow’
to ‘hidden
’ for
the <div>, on the other hand, causes the <blockquote> to be clipped
by the containing block:
A value of ‘scroll’ would tell UAs that support a visible scrolling mechanism to display one so that users could access the clipped content.
Consider this case where an absolutely positioned element is mixed with an overflow parent. Style sheet:
container { position: relative; border: solid; } scroller { overflow: scroll; height: 5em; margin: 5em; } satellite { position: absolute; top: 0; } body { height: 10em; }
Document fragment:
<container> <scroller> <satellite/> <body/> </scroller> </container>
In this example, the “scroller” element will not scroll the “satellite” element, because the latter's containing block is outside the element whose overflow is being clipped and scrolled.
The combination of collapsing margins, ‘max-height’ and ‘overflow: auto
’ can lead to subtle differences in
implementations, unless special care is taken. A UA should assume that an
element can be rendered without a scrolling mechanism first,
perform all the collapsing of margins, and check that the content height
is indeed less than the ‘max-height’. If it is not, the process is
repeated under the assumption that a scrolling mechanism is
needed.
In the following document fragment, the outer DIV has ‘height: auto
’, but ‘max-height: 5em
’. The inner DIV has large margins
and would normally just fit:
... #d1 { overflow: auto; max-height: 5em } #d2 { margin: 2em; line-height: 1 } ... <div id=d1> <div id=d2> This DIV has big margins. </DIV> </DIV>
If we assume that d1 needs scroll bars, then the height of d1, including the single line of text and twice 2em of margins, adds up to 5em plus a scrollbar. Since that is greater than 5em, the maximum allowed height, it seems we made the right assumption and d1 indeed needs scrollbars.
However, we should have started by assuming that no scrollbars are needed. In that case the content height of d1 is exactly the maximum height of 5em, proving that the assumption was correct and d1 indeed should not have scrollbars.
The computed values of ‘overflow-x’ and ‘overflow-y’ are the same as their specified values, except that some combinations with ‘visible’ are not possible: if one is specified as ‘visible’ and the other is ‘scroll’ or ‘auto’, then ‘visible’ is set to ‘auto’. The computed value of ‘overflow’ is equal to the computed value of ‘overflow-x’ if ‘overflow-y’ is the same; otherwise it is the pair of computed values of ‘overflow-x’ and ‘overflow-y’.
The scrolling mechanism depends on the UA. The most common mechanism is a scrollbar, but panners, hand cursors, page flickers, etc. are also possible. A value of ‘scroll’ would tell UAs that support a visible scrolling mechanism to display one so that users can access the clipped content. The ‘overflow-style’ property lets an author specify one or more preferred scrolling mechanism.
Note that ‘overflow-x’ and ‘overflow-y’ did not exist in CSS2.
Note that ‘text-overflow’ (see [CSS3TEXT]) can be used to give a visual indication where text has been clipped.
Name: | overflow-style |
Value: | auto | [scrollbar | panner | move | marquee] [, [scrollbar | panner | move | marquee]]* |
Initial: | auto |
Applies to: | same as ‘overflow’ |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
This property specifies the preferred scrolling methods for elements
that overflow (see the ‘overflow’ property.) The value is either
‘auto
’, meaning no preference, or a
list of methods in order of preference. The UA should use the first
scrolling method in the list that it supports. If it supports none of
them, it must act as if the value was ‘auto
’.
A UA that support a certain scrolling mechanism may be able to support it only in certain cases. E.g., a UA may be able to use the marquee effect only in the horizontal direction (or the line progression direction), or it may be able to use a panner only if none of the ancestor boxes uses a panner.
move
’ refers to a method
where the user can move the content of the element directly (rather than
indirectly by moving a scrollbar or a panner). Typically, the mouse
pointer changes into a hand or a cross of four arrows to indicate that
the user can drag the content around with the mouse. Sometimes the user
needs to explicitly activate the move mode and in that case he often can
use both dragging (with the mouse) and key events to move the content.
marquee
’) consists of the content moving
autonomously, without any user events to control it. A user who waits
long enough will eventually see all the content that overflows.
This specification does not define what scrollbars, panners or the
visual indicators for the ‘move
’ method
look like. The ‘marquee
’ method is
further defined below.
Another idea is to make ‘overflow’ a shorthand for ‘overflow-style’ and
overflow-policy, where overflow-policy has syntax “visible | hidden |
scroll | auto” and ‘overflow’ has “<‘overflow-policy’> || <‘overflow-style’>”.
Then it is possible to write, e.g., ‘overflow: auto
marquee, scrollbar
’.
We will probably want to introduce overflow-x and overflow-y in CSS3 to separate the policy in the two directions. In that case we may want:
‘overflow’ is then
a shorthand that sets -x and -y to the same value. (‘overflow: auto
’ is ambiguous, as is ‘overflow: auto auto
’, but it doesn't matter.)
The marquee effect consists of the UA slowly moving the content of a box so that, over time, all parts of the box are visible at least once. The speed of the movement, whether the movement is in one direction only or back and forth, how far the content moves and how often may vary. But, unlike for most other scrolling mechanisms, these factors are not dependent on user events. Typically, marquee is used in contexts where there is no room for a scrollbar or other visible mechanism or when user interaction is limited: instead of actively moving hidden content into view with a scrollbar or similar mechanism, the user waits while the content moves by.
The following rules put the contents of each list item on a single line (unless it has hard line breaks) and causes the list items that are too wide to use a marquee effect (on UAs that support marquee):
li {overflow: auto; overflow-style: marquee; white-space: nowrap}
Name: | marquee-style |
Value: | scroll | slide | alternate |
Initial: | scroll |
Applies to: | same as ‘overflow’ |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
The values are:
Is ‘bounce
’ a better name
than ‘alternate
’?
The content of an element moves as one piece. E.g., if a element has two lines of text, both lines scroll together, even if only one of them overflows.
Name: | marquee-loop |
Value: | <non-negative-integer> | infinite |
Initial: | 1 |
Applies to: | same as ‘overflow’ |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
This property specifies how often the content moves. UAs should restart the loop count every time the element turns from completely invisible into (fully or partially) visible. E.g., an element that is outside the viewport starts moving when it is scrolled into view.
A UA may also take the visibility of the UA viewport itself into account, e.g., if the element is hidden behind a pop-up window or if the UA is iconified.
If ‘marquee-loop’
is different for different states of the element, e.g., ‘p {marquee-loop: 0} p:hover {marquee-loop:
infinite}
’, the loop counter must be reset each time the
element enters a state with a different computed value.
For example, if the content of an li overflows under the following style rules, the content moves once when the li gets the focus or is hovered over. But, when it already has the focus when it is hovered over, the ‘marquee-loop’ property doesn't change and thus the content doesn't move again:
li {overflow: auto; overflow-style: marquee; marquee-loop: 0} li:focus, li:hover {marquee-loop: 1}
Is ‘infinite
’ a better
default than ‘1
’?
Name: | marquee-direction |
Value: | forward | reverse |
Initial: | reverse |
Applies to: | same as ‘overflow’ |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | ltr or rtl |
This property determines the initial direction in which the content moves if the marquee effect is used. The actual direction depends on ‘direction’ and ‘block-progression’ as follows:
reverse | forward | ||
---|---|---|---|
tb | ltr | left | right |
rtl | right | left | |
rl / lr | ltr | up | down |
rtl | down | up |
Note that ‘marquee-style:
alternate
’ moves content in the opposite direction on
even-numbered loops.
Note that ‘reverse
’ allows text to
be read in the normal order. E.g., in English text (‘block-progression: tb
’ and ‘direction: ltr
’), text appears at the right edge,
moves to the left and disappears at the left edge.
Name: | marquee-speed |
Value: | slow | normal | fast |
Initial: | normal |
Applies to: | same as ‘overflow’ |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
This property determines how fast the content scrolls. The actual speed depends on the UA and the type of content. But, for a given UA and a given element, the following must always be true: slow < normal < fast.
Name: | visibility |
Value: | visible | hidden | collapse |
Initial: | visible |
Applies to: | all elements |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | as specified |
This property specifies whether the boxes generated by an element are
rendered. Invisible boxes still affect layout (set the ‘display’ property to ‘none
’ to suppress box
generation altogether). Values have the following meanings:
visibility:
visible
’.
collapse
’ has the same
meaning as ‘hidden
’.
Should probably be in the extended Box module instead of here…
Name: | rotation |
Value: | <angle> |
Initial: | 0 |
Applies to: | block-level elements, inline-table and inline-block |
Inherited: | no |
Percentages: | N/A |
Media: | visual |
Computed value: | 0deg ≤ angle < 360deg |
Name: | rotation-point |
Value: | <bg-position> |
Initial: | 50% 50% |
Applies to: | block-level elements |
Inherited: | no |
Percentages: | Width and height of border box |
Media: | visual |
Computed value: | for <length> the absolute value, otherwise a percentage |
The value of ‘rotation-point’ is a pair of values that defines a point as an offset from the top left border edge. Percentages refer to the width and height of the border box. Values may be negative.
‘Rotation’ rotates a
block-level element counterclockwise around the
point given by ‘rotation-point’. The border, padding and
content are rotated, and also any background that is not ‘fixed
’. All static or relatively positioned child
elements (and their static and relatively positioned children,
recursively) are rotated along. But absolutely positioned and fixed
descendant elements are not.
Note that this means that rotation is relative. A child of a box that is rotated 45deg and that has a rotation of -45deg itself, actually ends up horizontal (but probably in a different location than when both rotations had been 0).
Rotation doesn't affect parent or sibling elements, they are laid out as if the element's rotation was 0. Conceptually, the element is first laid out without any rotation, then any relative positioning is applied to it (see [CSS3POS]) and finally any rotation. The rotation point is relative to the box after relative positioning.
Note that, like relative positioning, rotation can thus cause an element's box to overlap other boxes. It is the author's responsibility to give the element wide enough margins if such overlapping is not desired.
When a box is broken over several columns or pages, each of the boxes is rotated separately around its own rotation point.
The computed value of ‘rotation’ is the angle normalized to fall in 0deg ≤ angle < 360deg. The computed value or ‘rotation-point’ is a pair in which any <length> is made absolute, keywords are replaced by percentages and percentages are left as specified.
This example puts H1 elements upside down. It relies on the ‘rotation-point’ having
its default value of ‘50% 50%
’.
H1 {rotation: 180deg}
This example displays column headers in a table diagonally. It uses ‘block-progression’ (see [CSS3TEXTLAYOUT]) to write the column headers vertically and applies ‘rotation’ to rotate the headers 45 degrees to the left. A fairly wide padding is applied, to make sure the text of the headings doesn't overlap.
thead th { block-progression: rl; padding: 0.5em 1em; rotation: 45deg; rotation-point: bottom left }
In the table example, how are the borders rotated? Because the borders belong to two elements that are rotated individually.
Dave Hyatt proposes to generalize the property and call it “transform” with a syntax and functionality like in SVG, i.e., a property that accepts a series of transformations (rotations, translations, arbitrary affine transformations).
This section defines the painting order in more detail than described in the rest of the specification.
Definitions:
:before
’ box in the line box, which comes before
the content of the box, and so forth.
The bottom of the stack is the furthest from the user, the top of the stack is the nearest to the user:
The stacking context background and most negative positioned stacking contexts are at the bottom of the stack, while the most positive positioned stacking contexts are at the top of the stack.
The canvas is transparent if contained within another, and given a UA-defined color if it is not. It is infinite in extent and contains the root element. Initially, the viewport is anchored with its top left corner at the canvas origin.
The stacking order for an element generating a stacking context (see the ‘z-index’ property) is:
If the element is a root element:
If the element is a block, list-item, or other block equivalent:
Otherwise, if the element is a block level table:
Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order.
For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent:
Otherwise, the element is a table:
All non-positioned floating descendants, in tree order. For each one of these, treat the element as if it created a new stacking context, but any descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one.
If the element is an inline element that generates a stacking context, then:
Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
If the element is a block-level replaced element, then: the replaced content, atomically.
Otherwise, for each line box of that element:
For inline-block and inline-table elements:
For inline-level replaced elements:
Some of the boxes may have been generated by line splitting or the Unicode bidirectional algorithm.
Optionally, if the element is block-level, the outline of the element (see 10 below).
All positioned descendants with ‘z-index:
auto
’ or ‘z-index: 0
’,
in tree order. For those with ‘z-index:
auto
’, treat the element as if it created a new stacking
context, but any descendants which actually create a new stacking
context should be considered part of the parent stacking context, not
this new one. For those with ‘z-index:
0
’, treat the stacking context generated atomically.
Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.
Finally, implementations that do not draw outlines in steps above must draw outlines from this stacking context at this stage. (It is recommended to draw outlines in this step and not in the steps above.)
The background of the root element is only painted once, over the whole canvas.
While the backgrounds of bidirectional inlines are painted in tree order, they are positioned in visual order. Since the positioning of inline backgrounds is unspecified [still the case?], the exact result of these two requirements is UA-defined.
Normative references:
Informative references:
Property | Values | Initial | Applies to | Inh. | Percentages | Media |
---|---|---|---|---|---|---|
clear | none | left | right | both | none | block-level elements | no | N/A | visual |
display | inline | block | inline-block | list-item | run-in | compact | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | ruby | ruby-base | ruby-text | ruby-base-group | ruby-text-group | <template>| none | inline | all elements | no | N/A | visual (‘none’ applies to all media) |
float | left | right | none | <page-floats> | none | all, but see 9.7 | no | N/A | visual |
height | <length> | <percentage> | auto | auto | all elements but non-replaced inline elements, table columns, and column groups | no | see prose | visual |
margin | [ <length> | <percentage> | auto ]{1,4} | (see individual properties) | see text | no | width* of containing block | visual |
margin-top , margin-right, margin-bottom, margin-left | <length> | <percentage> | auto | 0 | see text | no | width* of containing block | visual |
marquee-direction | forward | reverse | reverse | same as ‘overflow’ | yes | N/A | visual |
marquee-loop | <non-negative-integer> | infinite | 1 | same as ‘overflow’ | no | N/A | visual |
marquee-speed | slow | normal | fast | normal | same as ‘overflow’ | no | N/A | visual |
marquee-style | scroll | slide | alternate | scroll | same as ‘overflow’ | no | N/A | visual |
max-width, max-height | <length> | <percentage> | none | none | all elements but non-replaced inline elements, table rows, and row groups | no | refer to width, resp. height of containing block | visual |
min-width, min-height | <length> | <percentage> | inherit | 0 | all elements but non-replaced inline elements, table rows, and row groups | no | refer to width, resp. height of containing block | visual |
overflow | [ visible | hidden | scroll | auto | no-display | no-content ]{1,2} | see individual properties | non-replaced block-level elements and non-replaced ‘inline-block’ elements | no | N/A | visual |
overflow-style | auto | [scrollbar | panner | move | marquee] [, [scrollbar | panner | move | marquee]]* | auto | same as ‘overflow’ | yes | N/A | visual |
overflow-x, overflow-y, | visible | hidden | scroll | auto | no-display | no-content | visible | non-replaced block-level elements and non-replaced ‘inline-block’ elements | no | N/A | visual |
padding | [ <length> | <percentage> ]{1,4} | (see individual properties) | all elements | no | width* of containing block | visual |
padding-top , padding-right, padding-bottom, padding-left | [ <length> | <percentage> ] | 0 | all elements | no | width* of containing block | visual |
rotation | <angle> | 0 | block-level elements, inline-table and inline-block | no | N/A | visual |
rotation-point | <bg-position> | 50% 50% | block-level elements | no | Width and height of border box | visual |
visibility | visible | hidden | collapse | visible | all elements | yes | N/A | visual |
width | <length> | <percentage> | auto | auto | all elements but non-replaced inline elements, table rows, and row groups | no | refer to width of containing block | visual |
Properties defined elsewhere: