CSS 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 their layout as a collection of rectangular boxes containing words, lines, paragraphs, tables, etc., each with properties such as size, color and font.
This module describes the basic types of boxes: block, list item, inline, etc.; and some of their properties, including margins, padding and width/height. It defines a layout called a “flow,” in which a series of boxes is laid out one after the other, and it defines “floating” boxes. Other kinds of layout, such as tables, absolute positioning, ruby annotations, grid layouts, columns and page boxes, are described by other modules. Also, the layout of text inside a line (including the handling of left-to-right and right-to-left scripts) is defined elsewhere.
In CSS level 3, boxes may contain either horizontal or vertical text. Different orientations can be mixed.
The CSS Working Group plans to ask for W3C Recommendation status for this specification only when there are sufficiently many implementations. See the section “CR exit criteria” for details.
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 float displacement. Please help us improve the next draft by pointing out such differences.
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.
This CSS module depends on the following other CSS modules:
Investigate if it is possible to make a pseudo-element to select anonymous boxes ('::paragraph'). See minutes of 10 Aug 2011.
Note: The model in this specification differs from the model described in the CSS level 2 specification [[!CSS21]], because it is generalized to apply also to vertical text.
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. Each child has one parent, except for the unique element that has no parent, which 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 set of rectangular boxes, whose size, position, and stacking level on the canvas depend on their properties. We say that an element generates one or more boxes. 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. Inline-level boxes are like words inside a line.
When the specification says a box A contains a box B, then B is a box generated by an element that is a descendant of the element that generated A. Typically, box B is geometrically contained in box A as well, but that need not be the case, because of, e.g., overflow or negative margins.
Note: 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).
Relation between four displayed boxes in the rendered document (on the right) and the three corresponding elements in the source document on the (left).
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.
Each box belongs to exactly one element. It is either generated directly by the element, or it is an anonymous box (defined below), which is inserted because the layout rules of CSS require a box to contain a certain kind of other box, but the boxes generated by the child elements are not of that kind. The anonymous box is defined to belong to the parent.
Note: This is mainly important for WYSIWYG document editors: if the user selects a box on the screen in order to set a property, the editor knows which element to set the property on.
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.
The various areas and edges of a typical box
Boxes have padding, a border and margins (see the figure). Different properties determine the thickness of each of these (which may be zero). The margins are also subject to collapsing.
Each box has a content area (a.k.a. content box). 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. The padding area and content area together form the padding box. Outside the padding is the border area and the outside boundary of that area is the border edge. The border area, padding area and content area together form the border box. 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.
Line boxes cannot have any padding, border or margin, and therefore their margin edge, border edge, padding edge and content edge all coincide.
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.
Note that the edges always form rectangles, even if there is a 'border-radius' [[CSS3BG]] or a shape [[CSS3-EXCLUSIONS]].
A box or element is horizontal if its 'writing-mode' property is ''horizontal-tb'', otherwise it is vertical. The orientation of a box or element is the pair of values of its 'writing-mode' and 'direction'
Note that there are theoretically eight possible orientations, but CSS only defines six:
| 'writing-mode: horizontal-tb' | 'writing-mode: vertical-rl' | 'writing-mode: vertical-lr' | |
|---|---|---|---|
| 'direction: ltr' |
Text is written from left to right and paragraphs grow downwards
|
Text is written top to bottom and paragraphs grow to the left
|
Text is written top to bottom and paragraphs grow to the right
|
| 'direction: rtl' |
Text is written from right to left and paragraphs grow downwards |
Text is written bottom to top and paragraphs grow to the left |
Text is written bottom to top and paragraphs grow to the right |
There is no “horizontal-bt.”
This specification sometimes refers to abstract edges head, end, tail and start, which are relative to the orientation of a box. They map to top, right, bottom and left as follows:
| Value of 'writing-mode' | Value of 'direction' | Meaning of “head” | Meaning of “end” | Meaning of “tail” | Meaning of “start” |
|---|---|---|---|---|---|
| ''horizontal-tb'' | ''ltr'' | top | right | bottom | left |
| ''horizontal-tb'' | ''rtl'' | top | left | bottom | right |
| ''vertical-rl'' | ''ltr'' | right | bottom | left | top |
| ''vertical-rl'' | ''rtl'' | right | top | left | bottom |
| ''vertical-lr'' | ''rtl'' | left | bottom | right | top |
| ''vertical-lr'' | ''ltr'' | left | top | right | bottom |
For example, the “head padding” by default refers to the 'padding-top' and the “end border” is by default the 'border-right'.
[Alternative terminology:]
This specification sometimes refers to abstract edges A, B, C and D, which are relative to the orientation of a box. They map to top, right, bottom and left as follows:
| Value of 'writing-mode' | Value of 'direction' | Meaning of “A” | Meaning of “B” | Meaning of “C” | Meaning of “D” |
|---|---|---|---|---|---|
| ''horizontal-tb'' | ''ltr'' | top | right | bottom | left |
| ''horizontal-tb'' | ''rtl'' | top | left | bottom | right |
| ''vertical-rl'' | ''ltr'' | right | bottom | left | top |
| ''vertical-rl'' | ''rtl'' | right | top | left | bottom |
| ''vertical-lr'' | ''rtl'' | left | bottom | right | top |
| ''vertical-lr'' | ''ltr'' | left | top | right | bottom |
For example, the “A padding” by default refers to the 'padding-top' and the “B border” is by default the 'border-right'.
Similarly, the specification sometimes refers to the inline and block flow dimensions of a box, instead of width and height, as follows:
| Writing mode | Meaning of “inline dimension” | Meaning of “block flow dimension” |
|---|---|---|
| horizontal | width | height |
| vertical | height | width |
These correspond to the dimensions in the inline base direction and the block flow direction, respectively.
[Alternative terminology:]
Similarly, the specification sometimes refers to the B-D and A-C dimensions of a box, instead of width and height, as follows:
| Writing mode | Meaning of “B-D” | Meaning of “A-C” |
|---|---|---|
| horizontal | width | height |
| vertical | height | width |
These correspond to the dimensions in the inline base direction and the block flow direction, respectively.
Finally, the headside, endside, tailside and startside of a box are defined as the sides that correspond to the head, end, tail and start, of the containing block of the box.
For example, if a box has a 'writing-mode' of ''horizontal-tb'', then its top content edge acts as its head content edge, and the headside edges of its children are therefore their top edges, independent of what their own 'writing-mode' is.
The second child box is a vertical box and has its “head” content edge on the right. But its “headside” content edge is at the top.
[Alternative terminology:]
Finally, the A′, B′, C′ and D′ sides of a box are defined as the sides that correspond to the A, B, C and D sides of the containing block of the box.
For example, if a box has a 'writing-mode' of ''horizontal-tb'', then its top content edge acts as its A content edge, and the A′ edges of its children are therefore their top edges, independent of what their own 'writing-mode' is.
The second child box is a vertical box and has its “A” content edge on the right. But its “A′” content edge is at the top.
Check terms. At Cambridge ftf Aug 2008 we chose: Property name: block-flow with values tb | lr | rl | bt. Descriptive terms: horizontal mode (= tb & bt), vertical mode (= lr & rl). The May 2012 Writing Modes module now has 'writing-mode' with values ''horizontal-tb'', ''vertical-rl'' and ''vertical-lr'' (and no ''bt'' anymore).
User agents for continuous media generally offer users a viewport (a window or other viewing area on the screen) through which users consult a document. User agents may change the document's layout when the viewport is resized (see the initial containing block).
When the viewport is smaller than the area of the canvas (see below) on which the document is rendered, the user agent should offer a scrolling mechanism. There is at most one viewport per canvas, but user agents may render to more than one canvas (i.e., provide different views of the same document).
For all media, the term canvas describes the space where the formatting structure is rendered. The canvas is infinite for each dimension of the space.
For the purposes of the width and height calculations below, CSS distinguishes four kinds of replaced elements:
For raster images without reliable resolution information, a size of 1 px unit per image source pixel must be assumed. These images thus are of type 1.
E.g., in the section on inline replaced elements, if the replaced element is an HTML document and the height is specified as ''auto'', e.g.:
... <object data="example.html"
style="width: 30em; height: auto"></object>...
then the used height will be 150px, which is unlikely to be the real height of the example.html document. But if the height is specified as ''complex'', e.g.:
... <object data="example.html"
style="width: 30em; height: complex"></object>...
then the height will be the height the example.html document normally has when displayed on its own with the given width. This enables almost seamless integration of external text in a document, without a scrollbar or similar. (The external text is still displayed with its own style sheet.)
An (external) mathematical formula in MathML is an example of replaced content with an intrinsic width and height. Assume the file m.mml contains a formula, then the HTML fragment
... derive <img src="m.mml" alt="that the sum of p(i) for i greater than 0 equals N"> for the case...
renders the formula at its intrinsic size.
The mathematical formula would however benefit from a way to negotiate available space against intrinsic size, or even negotiate available space against the number of boxes, so that the formula could be broken in two or more boxes and occupy space on two or more lines (similar to how lines of text are broken or words are hyphenated). But an easier solution might be to extend HTML with native support for math and CSS with math boxes, so that replaced elements remain single boxes.
As described in the introduction, elements give rise to boxes and those boxes are laid out on a canvas. Different kinds of boxes are laid out differently. This section describes the layout of one flow of boxes.
The approximate model for the layout of a flow of boxes is that sibling boxes are laid out one after the other in one long series with margins between them and parent boxes tightly wrap the series of child boxes. The 'writing-mode' property of the parent determines if that series grows down (''tb''), to the left (''rl''), to the right (''lr'') or up (''bt''). Although the rules below depend on terms that are only defined further down, the rules are given at the outset, to provide at least an approximate model of how boxes are positioned relative to one another.
The following rules define the position of block-level boxes relative to the box that is their flow root. Other sections and other modules describe how other boxes are laid out. E.g., floating boxes are described further down in this module and absolutely positioned boxes are described in the Absolute Positioning module [[CSS3POS]].
Before applying these rules, the width, height and margins of each box must be computed as described in the sections “Calculating widths, heights and margins” and “Collapsing margins.”
Consider the first box (in document order) of a set of sibling boxes that all belong to the same flow. There are four cases:
If none of its margins collapse with its parent's head margin and the box is not collapsed through, then the box is placed such that the box's headside margin edge touches the parent's head content edge, the startside margin edge touches the parent's start content edge and the endside margin edge touches the parent's end content edge.
[Add illustration.]
[Alternative terminology:] If none of its margins collapse with its parent's A margin and the box is not collapsed through, then the box is placed such that the box's A′ margin edge touches the parent's A content edge, the D′ margin edge touches the parent's D content edge and the B′ margin edge touches the parent's B content edge.
If none of its margins collapse with its parent's head margin but the box is collapsed through, then its content edge (which is also its border edge and padding edge) is defined as what it would have been if the box had a non-zero tailside border. (I.e., recompute the margins given that border and then apply the previous rule.)
Note that the box is effectively invisible, but the edges have to be defined to position any descendants, such as floating or absolutely positioned children.
If exactly one of its margins collapses with its parent's head margin, then the box is placed such that the box's headside border edge touches the parent's head content edge, the startside margin edge touches the parent's start content edge and the endside margin edge touches the parent's end content edge.
[Add illustration.]
If two of its margins collapse with its parent's head margin, then its position is such that its content edge (which is also its border edge) touches its parent's head border edge and that its startside margin edge touches its parent's start content edge and its endside margin edge touches the parent's end content edge.
Note that the box is effectively invisible, but the edges have to be defined to position any descendants.
For a box that has a preceding sibling in the same flow there are two cases:
If the box is not collapsed through, it is positioned such that its margin edge touches the parent's start content edge and end content edge and such that its content edge on the touches the [...]
A box that has a preceding sibling in the same flow and that is collapsed through, [...]
The layout of boxes in the flow is in large part determined by the interplay of the 'display' properties of an element and its parent, and then fine-tuned with margins and padding.
| 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 | align-box | 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 |
There is an old proposal to split 'display' into display-role (the function of the element in its parent) and display-model (how the element lays out it children). That allows some combinations that have no keyword, such as a table cell ('display-role: table-cell') that is itself a table ('display-model: table'), without the need for an extra wrapper element. It allows certain things (for math layout, e.g.), but is not easy to use. An alternative proposal is an '::outside' pseudo-element to create an extra box on which to set a different 'display' value. That is not easy either, and doesn't cascade well. And a third proposal is to allow two values on 'display': if there are two (in any order), one is the role and the other the model, unless the pair makes no sense. That doesn't make the concept any easier, but it hides the complexity better.
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.
Note that both 'clear-after' and ''align-box'' can be used to force the next element after this one to start after any floats inside this element, but the effect is not exactly the same. E.g., 'display: box' also affects certain forms of margin collapsing.
Note that 'vertical-al ign' applies to ''align-box'' elements, hence the name. The 'vertical-align' property doesn't apply to other block-level elements, except ''table-cell'' elements.
Any sense in vertically spreading out the contents, something like 'vertical-align: justify'?
Simpler to not use 'vertical-align', but creating ''top-box'', ''middle-box'' and ''bottom-box''?
The 'vertical-align' property applies to ''align-box'' elements [check in [[!CSS3TEXT]]!], and can thus be used to create vertically centered content, without wrapping the content in a table (which may not be always possible, and also causes the 'width' property to behave differently).
div.slide {
display: align-box;
height: 15em;
vertical-align: middle;
border: thin solid }
with a document fragment like this:
<div class=slide>
<ul>
<li>Bullet lists are boring
<li>They distract from the speaker
<li>Don't use them!
</ul>
</div>
might look like this figure:
The 'vertical-align: middle' causes the content of the ''align-box'' to be vertically centered.
The computed value of 'display' depends on 'position' [[CSS3POS]], 'float' and 'overflow':
| 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 |
There may be documents that combine different layout models, such as documents that combine HTML (typically rendered with the CSS box model) and SVG (rendered with its own graphics model). If an element that is rendered according to the CSS box model has a child that is to be rendered with a different model, that child needs to have a 'display' property with a value that indicates that the child is not in the box model.
Such a child is treated as a replaced element for the purposes of determining its size, position, margins, padding and border.
Should we allow a more complex model, where such a child may negotiate with the CSS environment to have several boxes and several baselines, so that it can take part in line breaking and page breaking?
This specification defines no value(s) for the 'display' property that indicate that an element is formatted according to a different model than the box model, but separate specifications may do so.
A block-level box is a box that has a computed value for 'display' of ''block'', ''align-box'', ''list-item'', ''table'', ''table-*'' (i.e., all table boxes, see [[CSS3TBL]]), ''run-in'' (under certain circumstances, see “Run-in boxes” ), or ''compact'' (under certain circumstances, see “Compact boxes”).
An inline-level box is a box that has a computed value for 'display' of ''inline'', ''inline-block'', ''inline-table'', ''ruby'', ''run-in'' (under certain circumstances), or ''compact'' (under certain circumstances).
[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:
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):
When the fragment is rendered, the text before the q is wrapped in an anonymous block and the text after the q in another.
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 'writing-mode' properties. The containing block of a box is defined as follows:
In the above, a block container box is, informally, a box that can contain block boxes. More precisely: any box generated by a (pseudo-)element with a computed value for 'display' of ''block'', ''inline-block'', ''table-caption'', ''table-cell'' or ''list-item''. Note that most floating and absolutely positioned elements have a computed 'display' of ''block''. Also, a flow root has a computed 'display' of ''block''. Or insert the definition of block container box from CSS 2.1 here?
Also define principal box somewhere.
Issue 142 of CSS 2.1 suggests that an anonymous cell box, unlike anonymous block boxes, can establish the containing block for its children. If that is accepted, make sure the table module modifies the above definition.
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.
If an element [or a viewport?] has scrollbars (see 'overflow'), then any space taken up by the scrollbars should be excluded from (subtracted from the dimensions of) any containing block formed by that element.
A flow root is a box that satisfies at least one of the following:
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 'writing-mode' apply to inlines.
Note: 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 all of the following are true:
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 { writing-mode: tb; float: left }
blockquote[lang|=ja] { writing-mode: 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 a vertical box inside a
horizontal parent 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 'writing-mode' 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 edges of its containing block (if the flow root is ''tb''), or its top and bottom margin edges coincide with the top and bottom edges of its containing block (if the flow root is ''rl'' or ''lr'').
A ''run-in'' element (or pseudo-element) A behaves as follows:
In the above, “siblings” and “children” include both normal elements and :before/:after pseudo-elements.
An element or pseudo-element C inhibits run-in behavior if one or more of the following are true. (Note that the definition is recursive.)
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. It is undefined in level 2 if a run-in inherits from a ':first-line' pseudo-element. How about in level 3?
Define here or in extended box module?
A compact box is a box that is either put in the margin of the next box or becomes a block of its own, depending on whether it is small enough to fit in the margin or not. The typical use case is for lists where most labels are small enough to fit in the margin, except for a few.
An example is the DL list in HTML. Its COMPACT attribute indicates to the formatter that the labels of the list are good candidates for display as compact boxes:
<h3>Farm animals</h3> <dl compact> <dt>cat <dd>Lorem ipsum dolor sit amet, consectetaur adipisicing elit… <dt>dog <dd>Ut enim ad minim veniam, quis nostrud exercitation… <dt>hippopotamus <dd>Duis aute irure dolor in reprehenderit in voluptate velit… <dt>fly <dd>Excepteur sint occaecat cupidatat non proident, sunt in… </dl>
With a style rule like
dl[compact] dt {display: compact}
this might be rendered as in the figure below.
Three of the four labels are narrow enough to fit in the left margin. The one that is too wide is converted into a block.
Whether a compact box C is displayed as a block or in the margin is determined as follows. Let N be the next sibling element in document order in the same flow as C, if any. Let W be the hypothetical distance between the startside margin edge and endside margin edge of C if the 'display' property of C were set to ''block'' and any ''auto'' on its inline dimension were replaced by ''fit-content''.
If C is displayed as a block, it is a block-level element and it is sized and positioned exactly as if its 'display' had been ''block''.
Otherwise, C is placed such that its startside margin edge aligns with the start margin edge of its containing block and its headside border edge aligns with the headside border edge of N. It is in this case an inline-level element.
Do we do anything to avoid that floats overlap with C? Do we do anything if C is taller than N? E.g., adjust the 'min-height' of N?
Simple example...
This example shows a compact box that has a different writing mode than its containing block:
dl {writing-mode: tb; direction: ltr}
dd {margin-left: 3em}
dt {display: compact; writing-mode: rl}
...
<dl>
<dt>cat
<dd>Lorem ipsum dolor sit amet, consectetaur adipisicing elit…
</dl>
The margin that is considered is the left margin of the DD, because the containing block (established by the DL) is top-to-bottom/left-to-right. That margin is thus compared to the width of the DT and it is large enough, which leads to a rendering similar to the figure below.
The word “cat” written sideways fits to the left of the definition.
| Name: | padding |
| Value: | [ <length> | <percentage> | auto ]{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> | auto ] |
| 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 }
Values may not be negative, thus the third line is ignored, but what about the fourth?
p { font-size: 10pt;
padding-left: 2em;
padding: -11pt;
padding-left: calc(1em - 11pt)
}
Margins in CSS serve to add both horizontal and vertical space between boxes.
| 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 | |
Add a stretch value to allow vertical distribution of blocks in a fixed-height containing block? css3-flexbox currently (May 2012) proposes to use ''auto'', but in normal flow we probably need something else, because ''auto'' already means ''0'' there.
<stretch> = fill( [ <length> | <percentage> ] )
This sets an elastic margin with a minimum thickness. Maybe it is enough without the minimum thickness, i.e.:
<stretch> = fill
Collapsing margins of which at least one has a <stretch> value would yield 'fill(M - N), or maybe just 'fill'.
To find the size of such a collapsed margin, find the nearest enclosing containing block in the same flow that has a fixed height, call that height H1. Compute the height of the content in that containing block (while treating 'fill(P)' as if it was simply P) and call that height H2. Count the number N of stretchable margins. If H2 < H1, then increase all the stretchable margins by (H1 - H2)/N. If there is no such enclosing block, 'fill(P)' simply means P.
In a multi-column element, each column box is a separate containing block for the purpose of stretching the margins.
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.” The meaning of ''auto'' is also explained there.
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, as defined in this section, 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-bottom: 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.
Schematic representation of the previous example.
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.
Schematic representation of the previous example.
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.
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”)
A margin of a box collapses with the head margin of its parent box if those two margins are adjoining.
A margin of a box collapses with the tail margin of its parent box if those two margins are adjoining.
The head margin of a box collapses with the tail margin of a sibling box if the two margins are adjoining.
The top and bottom margins of a box A collapse with each other if the two margins are adjoining and the parent box B is horizontal. (The box is “collapsed through.”)
The left and right margins of a box A collapse with each other if the two margins are adjoining and the parent box B is vertical. (The box is “collapsed through.”)
If a box A is collapsed through and it has the same mode as its parent (i.e., both are horizontal or both are vertical), then the position of its head border edge is defined as follows.
Note that box A itself is invisible and its position has no effect on the positions of the other elements with whose margins it is being collapsed; the border edge position is only required for laying out descendants of A.
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>] && [border-box | content-box]? | available | min-content | max-content | fit-content | 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 specified keyword, the specified percentage (see prose under <percentage>) or the absolute length; ''auto'' if the property does not apply |
| Name: | height |
| Value: | [<length> | <percentage>] && [border-box | content-box]? | available | min-content | max-content | fit-content | complex | 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 specified keywords, the specified percentage (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 or border area (depending on 'box-sizing') of certain boxes.
Values have the following meanings:
Another possible value is <non-negative-number>, which would mean ''min-content'' times that number.
Note that ''available'', ''max-content'', ''min-content'', ''fit-content'', ''border-box'', ''content-box'' and ''complex'' do not exist in level 2.
The keyword values (in contrast to length and percentage values) are not influenced by the 'box-sizing' property, they always set the size of the content box, even if 'box-sizing' is ''border-box''.
''Available'', ''max-content'', ''min-content'' and ''fit-content'' only have effect in the inline progression direction: when 'writing-mode' is ''tb'' and these keyword are set on 'height', they act like ''auto''; ditto when 'writing-mode' is something else and the keywords are set on 'width'.
Note that 'width: fit-content' is the same as 'width: auto' for floats and tables, and 'width: available' is the same as 'width: auto' for blocks in the normal flow.
For example, the following rule fixes the content width of paragraphs at 100 px:
p { width: 100px }
This example shows the use of the keyword values. Assume these style rules:
div {width: 20em}
p.available {width: available}
p.min-content {width: min-content}
p.max-content {width: max-content}
p.fit-content {width: fit-content}
p.float {float: left; width: auto}
p.auto {width: auto}
* {outline: thin solid red}
Then a document like this might be rendered as in the figure below:
<div>
<p class=available>available: as wide as parent.
<p class=min-content>min-content: as narrow as possible.
<p class=max-content>max-content: As wide as needed, even
if that means wider than the parent.
<p class=fit-content>fit-content: As wide as needed.
<p class=fit-content>fit-content: As wide as needed, but
no wider than the parent.
<p class=float>auto: depends on flow (=float).
<p class=auto>auto: depends on flow (=normal).
</div>
Rendering of the example: ''min-content'' and ''max-content'' depend only on the content; ''available'' depends only on the containing block; ''fit-content'' depends on both; and ''auto'' acts either like ''available'' or like ''fit-content'', depending on the type of box.
This example sets the width of the border box of an element to 50%. It includes a fallback (48%) for UA that do not support the ''border-box'' keyword, such as level 2 UAs:
div.side {
width: 48%;
width: 50% border-box }
It is equivalent to
div.side {
width: 50%;
box-sizing: border-box }
except that the latter doesn't have a fallback for level 2 UAs (which don't support the 'box-sizing' property).
| Name: | min-width, min-height |
| Value: | <length> | <percentage> | available | min-content | max-content | fit-content |
| 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, the keyword as specified, or the absolute length |
| Name: | max-width, max-height |
| Value: | <length> | <percentage> | available | min-content | max-content | fit-content | 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, the keyword as specified, the absolute length, or ''none'' |
These properties allow authors to constrain content widths and heights to a certain range. Values have the following meanings:
The keyword values (in contrast to length and percentage values) are not influenced by the 'box-sizing' property, they always set the size of the content box, even if 'box-sizing' is ''border-box''.
''Available'', ''max-content'', ''min-content'' and ''fit-content'' only have effect in the inline progression direction: when 'writing-mode' is ''tb'', keyword values on 'min-height' and 'max-height' act like '0' and ''none'', resp., and when 'writing-mode' is something else, keyword values on 'min-width' and 'max-width' act like '0' and ''none'', resp.
The size of a box often depends on the width or height of its content. This section defines two measures of that size: the intrinsic preferred width (IPREF) is, roughly, the size the content would have if no “soft” line breaks were inserted; the intrinsic minimum width (IMIN) is, roughly, the narrowest the box can get by breaking all lines at all possible places. Or stated another way: they are the largest width that the content can usefully fill and the smallest width that the content can fit in without unintended overflow.
For example, in a simple paragraph with just text the intrinsic preferred width is the width of the line if all words are laid out on one line; and the intrinsic minimum width is the width of the longest word.
The intrinsic minimum width (IMIN) of a horizontal, non-replaced element E is defined as the smallest length ≥ 0 such that
OVERFLOW(E,IMIN) ≤ OVERFLOW(E,w) for all w ≥ 0
where the function OVERFLOW(E,w) is defined as follows. Set the 'display' of E to ''block'', 'float' to ''none'', 'position' to ''static'', 'overflow' to ''visible'', 'min-width' to ''0'', 'max-width' to ''none'', 'height' to ''auto'', 'min-height' to ''0'', 'max-height' to ''none'' and 'width' to w. Then measure the total width W of E including all overflow, considering E and all its descendants in the same flow and all floats of which E is the containing block. Then
OVERFLOW(E,w) = W - w
The intrinsic preferred width (IPREF) of a horizontal, non-replaced element E is defined as the smallest length ≥ 0 such that
HEIGHT(E,IPREF) ≤ HEIGHT(E,w) for all w ≥ 0
and
HEIGHT(E,IPREF) < HEIGHT(E,w) or OVERFLOW(E,IPREF) ≤ OVERFLOW(E,w) for all w ≥ 0
where HEIGHT(E,w) is defined as follows. Set the 'display' of E to ''block'', 'float' to ''none'', 'position' to ''static'', 'overflow' to ''visible'', 'min-width' to ''0'', 'max-width' to ''none'', 'height' to ''auto'', 'min-height' to ''0'', 'max-height' to ''none'' and 'width' to w. Then HEIGHT(E,w) is the height as defined below in “Auto heights for flow roots.”
OVERFLOW is not necessarily monotonic in w and a binary search for IMIN and IPREF may thus fail.
The corresponding definitions for vertical elements are analogous, with width and height swapped.
We probably want a definition that gives the same result in easy cases (only inline content) but is quicker to compute in complex cases.
UA's may also, if speed is preferred over quality, use the approximate intrinsic minimum width (AMIN) instead of IMIN and the approximate intrinsic preferred width (APREF):
AMIN = max(W1,W2,W3,W4)
APREF = max(P1,P2,P3,P4)
where
Note that several kinds of child elements are ignored for the calculation of AMIN, e.g., vertical elements with 'width' of ''auto''. Also, tables aren't laid out.
The corresponding definitions for vertical elements are analogous, with width and height swapped.
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':
If 'transform' is not ''none'', the used width or height is further modified as follows:
Note that translations [[!CSS3-2D-TRANSFORMS]] do not affect the width or height and also do not affect the placement of boxes in the normal flow (see “Basic flow layout” ).
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.”
For the purposes of evaluating percentages in the following subsections, if the width of the containing block is unknown, then assume the width is '100vw'. Likewise, if the height of the containing block is unknown, then assume it is '100vh'.
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 calculated from the computed value by evaluating percentages and replacing ''auto'' by 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' derive from 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', and the element has an intrinsic width but no intrinsic ratio, then that intrinsic width is the used value of 'width'.
If 'height' has a computed value of 'auto', and the element has an intrinsic height but no intrinsic ratio, then that intrinsic width is the used value of 'width'.
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.
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 used values of the head padding, tail padding, head margin and tail margin are calculated from their computed values, with any ''auto'' values replaced by 0.
If the computed value of the block flow dimension is not ''auto'', then the used value is calculated by evaluating the computed value. Otherwise, the block flow dimension is the distance between two edges that are defined as follows:
The above reflects the fact that the margins of the element may collapse with the margins of its first and last children (unless the element has a border or padding). In that case the children's margins fall outside the block flow dimension.
The position of the edges is calculated without applying relative positioning, if any, to the children. And only children in the normal flow are taken into account, i.e., floating boxes and absolutely positioned boxes are ignored.
For example, the DIV in this fragment has a bottom border but no padding or border at the top. The height is thus calculated from the border edge of the first child (img1) to the margin edge of the last child (img2). The result is 8em.
div {border-bottom: 0.2em dashed}
img {height: 3em; display: block; margin: 1em}
...
<div>
<img src="img1" alt=...>
<img src="img2" alt=...>
</div>
The height is measured from the top border edge of the first IMG to the bottom margin edge of the last.
With respect to the inline dimension, the following constraint must hold among the used values of the given properties.
start margin + start border + start padding + inline dimension + end padding + end border + end margin = inline dimension of containing block
The used values of the above properties, except for any values that are ''auto'', are calculated from the computed values, evaluating percentages. If this makes the inline dimension negative, then set its used value to 0. Ditto for start padding and end padding. Note that such negative values can only happen when the specified value includes 'calc()'. Then apply one of the following cases:
If none of the values is ''auto'', then there are three sub-cases:
Note that the best way to center a block is 'margin-left: auto; margin-right: auto; alignment: center'. Setting the margins to ''auto'', instead of leaving them at 0, provides a fallback for UAs that do not support 'alignment' (which is a level 3 feature).
Note also that only 'alignment: center' guarantees proper centering. Setting the margins to ''auto'' only centers blocks if they are narrower than their containing block, because only one of the two margins is allowed to become negative.
The following examples illustrate different ways of aligning a fixed-width block in its parent. Assume English text, default values for 'writing-mode' and 'direction', a P of fixed with (e.g., 'width: 30em'), and the following HTML mark-up:
<div> <p>A paragraph here. </div>
The following aligns the right border edge of the P with the right content edge of the DIV:
p {alignment: right}
The following centers the P:
p {alignment: center}
Adding ''auto'' margins provides a fallback for UAs that do not support 'alignment'. (The fallback has the desired effect as long as the DIV is wider than the P.)
p {margin-left: auto; margin-right: auto; alignment: center}
“Conflicting” combinations of ''auto'' margins and 'alignment' are well-defined, but not very useful. They cause 'alignment' to be all but ignored. The following right-aligns the P (unless it is too wide for the DIV):
p {margin-left: auto; alignment: left}
Similarly, the following left-aligns the P in the DIV:
p {margin-right: auto; alignment: right}
Fixed or percentage margins can be combined with alignment. The following puts the right border edge of the P at 2em inside the right content edge of the DIV:
p {margin-right: 2em; alignment: right}
The following does the same. The value of 'margin-left' is ignored in a right-aligned block:
p {margin-right: 2em; margin-left: 4em; alignment: right}
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).
The used values of head padding, tail padding, head margin and tail margin are calculated from the computed values, with any ''auto'' values replaced by 0.
If the block flow dimension is ''auto'', the used value is defined by “''Auto'' heights for flow roots.” Otherwise, the used value is evaluated from the computed value.
Apply the rules for start margin, start padding, inline dimension, end padding and end margin as given above in “Block-level, non-replaced elements in normal flow when 'overflow' computes to ''visible''.”
Not yet generalized with head, tail, etc.
The used values of 'margin-left', 'margin-right', 'margin-top' and 'margin-bottom' are derived from their computed values, except that a computed value of ''auto'' gives a used value of 0.
If the computed value of 'width' is ''auto'', the used value is the same as for ''fit-content''. Otherwise the computed value is evaluated to give the used value.
If the computed value of 'height' is ''auto'', the used value is defined by “''Auto'' heights for flow roots.” If it contains a percentage and the height of the containing block is not known (depends on this element), then the used value is also defined by “''Auto'' heights for flow roots.” Otherwise it is calculated by evaluating the computed value.
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:
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' = 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.
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' = 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.
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:
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' = width of containing block
'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = 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 derived from the computed values, except that the used values of any margins computed as ''auto'' are '0'.
The used value of 'width' is derived from the computed value, except that if 'width' is computed as ''auto'', the used value is the same as for ''fit-content''.
If the computed value of 'height' is ''auto'', the used value is given by “''Auto'' heights for flow roots.” If the computed value includes a percentage and the height of the containing block is not known (depends on this element), then the used value is computed as if the computed value were ''auto''. Otherwise the computed value is evaluated to give the used value.
In 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.
| Name: | float |
| Value: | [ left | right | top | bottom | start | end | none | <page-floats> ] && contour? |
| Initial: | none |
| Applies to: | all, but see text |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | as specified |
Adding ''start'' and ''end'' was decided at 2009-12-02 telcon. Precide definitions not yet decided: does it depend on 'direction' of the element itself or its parent?
This property specifies whether a box should float to the left, right, or not at all. It only applies if the element has a 'display' other than ''none'' and a 'position' of ''static'' or ''relative''.
The 'float' property in turn influences the computed value of 'display'. See “The display property.”
The values of this property have the following meanings:
User agents may treat float as ''none'' on the root element.
The exclusion zone of a floating element is, roughly, the area that text may not intrude into when it flows around a float. More precisely, given a point P and a floating element F, the following determines if P is inside or outside the exclusion zone of F:
If F is a replaced element and its value of 'float' includes the keyword ''contour'' and F has no border and no padding:
If F is a horizontal element:
If 'float' is ''left'' or ''top'', then P is inside the exclusion zone of F iff P or any point to the right of P on a horizontal line through P is a in a non-transparent area of F.
If 'float' is ''right'' or ''bottom'', then P is inside the exclusion zone of F iff P or any point to the left of P on a horizontal line through P is a in a non-transparent area of F.
If F is vertical:
If 'float' is ''left'' or ''top'', then P is inside the exclusion zone of F iff P or any point below P on a vertical line through P is a in a non-transparent area of F.
If 'float' is ''right'' or ''bottom'', then P is inside the exclusion zone of F iff P or any point above P on a vertical line through P is a in a non-transparent area of F.
If F is not a replaced element, or if 'float' does not include the keyword ''contour'', or if F has a border or a padding:
If F is horizontal:
If 'float' is ''left'' or ''top'', then P is inside the exclusion zone of F iff P or any point to the right of P on a horizontal line through P is inside the margin area of F.
If 'float' is ''right'' or ''bottom'', then P is inside the exclusion zone of F iff P or any point to the left of P on a horizontal line through P is inside the margin area of F.
If F is vertical:
If 'float' is ''left'' or ''top'', then P is inside the exclusion zone of F iff P or any point below P on a vertical line through P is inside the margin area of F.
If 'float' is ''right'' or ''bottom'', then P is inside the exclusion zone of F iff P or any point above P on a vertical line through P is inside the margin area of F.
Non-transparent in this case means anything other than fully transparent. E.g., an area that is 90% transparent is non-transparent.
When 'float' is 'left contour', then the exclusion zone of the element includes all non-transparent parts (blue) and all points that are to the left of a non-transparent part (grey).
Note that the 'margin' is ignored for the purposes of determining the exclusion zone if ''contour'' is used. To create a visual “margin” around an image, an author can instead include an area in the image that is 99% transparent.
It might occasionally be nice to be able to give that “margin” a thickness in em without scaling the whole image, but that is a difficult operation…
Replaced elements can be handled by plug-ins and the plug-in API may not provide access to the contour of the object. Should there be a sentence about UAs not having to compute a contour in such a case?
(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 margin edge touches the containing block edge or the margin 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:
The text is too long to fit in a shortened line box next to the float (dark blue box) and so it is pushed down until it is passed the float.
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:
An image showing the various margins of the BODY, P and IMG element. Not that the top margin of the floating IMG does not collapse with the top margins of the P and BODY elements.
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.
A floating image obscures borders of block boxes it overlaps.
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:
Both paragraphs have set 'clear: left', which causes the second paragraph to be “pushed down” to a position below the float – clearance is added above its top margin to accomplish this (see the 'clear' property).
Here are the precise rules that govern the positions of floats with a horizontal containing block. References to other elements in these rules refer only to other elements in the same flow as the float's parent.
This HTML fragment results in the b floating to the right.
<P>a<SPAN style="float: right">b</SPAN></P>
If the P element's width is enough, the a and the b will be side by side. It might look like this:
The rules for a float with a containing block with 'writing-mode: rl' are exactly the same after replacing left with top, right with bottom, top with right, bottom with left and adjusting the text accordingly. Here they are:
[Still some words like lower and higher to replace...]
The rules for a float with a containing block with 'writing-mode: lr' are exactly the same after replacing left with top, right with bottom, top with left and bottom with right. They are given here for completeness:
[...]
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, define clearance.]
The main use case is to make sure an element is at least as high as all its floating descendants. I.e., at the end of the element, clear the floats that are descendants of the element, but not any floats that were declared before the element. There are three possible approaches:
| Name: | clear-after |
| Value: | none | left | right | top | bottom | inside | outside | start | end | both | descendants |
| Initial: | none |
| Applies to: | block-level elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | specified value |
It is sometimes useful to make sure that the bottom border of a block-level element goes below floating elements. The 'clear-after' property increases the element's padding as needed. More precisely: If there are any floats in the current flow up to and including the end of this element that float to the indicated side(s), then find the one whose tailside margin edge is furthest away from the head content edge of the containing block. Then increase the tailside padding of the current element by the minimum amount needed so that the padding edge is at least as far away from the head content edge of the containing block as the tailside margin edge of that float.
Note: Since a floating element is a flow root, setting 'clear-after' on such an element only takes into account any descendant floats in the flow established by the element itself.
The value of the property determines which kinds of floats are taken into account:
Use only two values: height-includes-floats and height-does-not-include floats? [DavidB 2004-02-29]
The effect of 'clear-after: left' on a paragraph next to a floating image: the bottom padding of the paragraph is stretched, so that the original padding and the border go below the float.
Instead of a new property 'clear-after', another idea is to add one or more values to 'clear'. If 'clear' is turned into a set, instead of a single value, one could add the value 'after' (clears both left and right floats) or several values like 'left-after' and 'right-after':
| Name: | clear |
| Value: | none | [ left | right | top | bottom | inside | outside | start | end | both | after]+ |
| Initial: | none |
| Applies to: | block-level elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | specified value |
The following rule would ensure that a SECTION starts below all preceding floats and doesn't end until after all floats it contains:
section {clear: left right after}
Daniel Beardsmore proposed a property 'underhang-limit: <count of full lines>' to protect against the case that the last line of a paragraph (or the last few lines) is shown under a float. In that case it looks better to indent that line like the other lines of the paragraph. The default is '1', i.e., no protection.
When some content of an element is placed outside the element's content box, the element is said to overflow. This module allows overflow to be clipped, other modules may add other treatments, e.g., scale it down or to scroll it (“marquee,” see [[CSS3-MARQUEE]]).
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:
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:
Possible rendering with 'overflow: visible'
Setting 'overflow' to ''hidden'' for the <div>, on the other hand, causes the <blockquote> to be clipped by the containing block:
Possible rendering with 'overflow: hidden'
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: | 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:
| Name: | alignment |
| Value: | top | right | bottom | left | center |
| Initial: | see text |
| Applies to: | block-level elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | specified value |
Another way to allow real centering of boxes would be to allow 'margin: any' (or 'margin: fill' or some other keyword that suggest “as large as possible, even if that means negative”) with the meaning that 'margin: auto' had before CSS 2.1. See also ACTION-18 (especially the ideas at end of Bert's comment ), which is continued in ISSUE-53.
For consistency with 'text-align', maybe this should be called 'block-align'.
This property influences how a block in the normal flow is aligned in its parent in the inline progression direction. It affects the used values of 'margin-left' and 'margin-right' (for horizontal blocks) or 'margin-top' and 'margin-bottom' (for vertical blocks), as defined in “Calculating widths, heights and margins.”
The initial value depends on both 'writing-mode' and 'direction', as follows:
| tb | rl | lr | |
|---|---|---|---|
| ltr | left | top | top |
| rtl | right | bottom | bottom |
Note that this property doesn't exist in level 2.
The 'alignment' property in combination with the ''fit-content'' value of 'width' can be used to make borders that enclose just the content of a heading, without the need for an additional element:
h2 {
margin-top: 1em;
margin-bottom: 1em;
border: solid;
padding: 0.5em;
alignment: center;
width: fit-content}
<p>Lorem ipsum dolor sit amet... <h2>A section heading</h2> <p>Lorem ipsum dolor sit amet... <h2>Another section heading</h2> <p>Lorem ipsum dolor sit amet...
See the figure below for a possible rendering.
A possible rendering of the example.
Other names: block-align (but note that it influences the children of the block, not the block itself), block-vertical-align (but note that it really means horizontal if the block's 'writing-mode' is ''lr'' or ''rl'').
Another way to allow centering and other alignments of boxes would be to allow 'margin: any' (or 'margin: fill' or some other keyword). See the explanation at the end of Bert's comment on ACTION-18. This is ISSUE-53.
| Name: | child-align |
| Value: | top | middle | bottom | left | right | auto |
| Initial: | auto |
| Applies to: | block-level elements, table cells and inline blocks |
| Inherited: | yes |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | the initial value or as specified |
This property describes how block-level content of a block is aligned vertically, or more precisely: in the block progression direction. Values have the following meanings:
| top | bottom | left | right | |
|---|---|---|---|---|
| tb | top | bottom | top | top |
| rl | right | right | left | right |
| lr | left | left | left | right |
An element with 'child-align' values other than ''auto'' is a flow root. Content of such a block is formatted as follows:
Note that the effect of 'child-align' can also be achieved with template layout [[CSS3LAYOUT]]. E.g.,
div {child-align: bottom}
is the same as
div {grid: "a"};
div::slot(a) {vertical-align: bottom}
except that the latter forces the DIV to be a block, while the former leaves the 'display' value of the DIV unchanged (but has no effect unless the DIV is block-level).
When this property applies and is not ''auto'', then 'vertical-align' does not apply. E.g., the placement of the content of a table cell is determined by 'vertical-align' only if 'child-align' is ''auto'', otherwise 'child-align' determines the placement.
Or, alternatively, 'child-align' doesn't apply to elements that 'vertical-align' applies to, i.e., only to ''block'', ''list-item'', ''inline-block'' and ''run-in'' (under circumstances).
In paged media and in multi-column layout, page breaks and column breaks are calculated first, then the content is vertically aligned according to the property within each portion of the parent block.
This section defines the painting order in more detail than described in the rest of the specification.
The bottom of the stack is the furthest from the user, the top of the stack is the nearest to the user:
Schematic diagram of a stacking context with four layers.
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 positioned descendants and 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:
For each line box that the element is in:
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 each box that is a child of that element, in that line box, in tree order:
background color of element.
background image of element.
border of element.
For inline elements:
For all the element's in-flow, non-positioned, inline-level children that are in this line box, and all runs of text inside the element that is on this line box, in tree order:
If this is a run of text, then:
Otherwise, jump to 7.2.1 for 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, the outline of the element (see 10 below).
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 positioned descendants and 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 in CSS 2.1, the exact result of these two requirements is UA-defined. CSS3 may define this in more detail. [Replace 2.1 by 3. Check if inline backgrounds are still undefined, otherwise say result is UA-dependent.]
A <number> value sets the width or height to that many times the intrinsic width resp. height of the element. The computed value is the number itself.
If a replaced element does not have an intrinsic size or if it has a complex relation between width and height, the used value for 'width: N' is N × W, where W is 300px or the largest width that fits the device, whichever is smaller; the used value for 'height: N' is N × W/2.
Here are some examples. Compare the following rules to set the size of an image, assuming 'height' is ''auto'' in each case:
img {width: 50px} /* exactly 50px wide */
img {width: 50%} /* half as wide as the containing block */
img {width: 50em} /* 50× the current font size */
img {width: auto} /* the intrinsic size */
img {width: 1} /* ditto, i.e., the intrinsic size */
img {width: 0.5} /* half the intrinsic width */
Note that <number> does not exist in CSS level 2.
We describe the meaning of ''auto'' on elements that have horizontal flow. Vertical flow is analogous, but with the roles of 'width' and 'height' interchanged.
On a replaced element, the meaning of ''auto'' depends on whether the element has an intrinsic size or not, as follows.
If the replaced element has an intrinsic width and an intrinsic height, then the used value for 'width: auto' is
(intrinsic width)/(intrinsic height) × (used value for height),
The used value for 'height: auto' is
(intrinsic height)/(intrinsic width) × (used value for width),
unless both 'width' and 'height' are ''auto'', in which case the used value of the former is the intrinsic width and the used value of the latter is the intrinsic height.
If the element has an aspect ratio (but no intrinsic width or height, because then it would fall under the preceding case), then the used value for 'width: auto' is
(aspect ratio) × (used value for height),
The used value for 'height: auto' is
(used value for width) / (aspect ratio),
unless both 'width' and 'height' are ''auto'', in which case the used width is 300px or the maximum width that fits the device, whichever is smaller; and the used height is (aspect ratio) × (used width).
If the element has an intrinsic width, but no intrinsic height and no aspect ratio (i.e., the height can be chosen freely), then the value used for 'width: auto' is the intrinsic width and the value used for 'height: auto' is 150px or half the maximum width that fits the device, whichever is smaller.
If the element has an intrinsic height, but no intrinsic width and no aspect ratio, then the value used for 'height: auto' is the intrinsic height and the value used for 'width: auto' is 300px or the maximum width that fits the device, whichever is smaller.
If the element has a complex relation between width and height, then the used value of ''auto'' is the result of the algorithm below.
If the element has no intrinsic width, no intrinsic height, no aspect ratio and no relation between width and height, then the value used for 'width: auto' is 300px or the largest width that fits the device, whichever is smaller; and the value used for 'height: auto' is 150px or half the largest width that fits the device, whichever is smaller.
Examples of replaced elements with an intrinsic size are most raster images (PNG, JPEG, etc.) and certain SVG graphics. SVG graphics and other scalable images may also have just an aspect ratio and no intrinsic width or height. Certain SVG graphics may have neither an intrinsic size nor an aspect ratio; they adapt to any width and height. Examples of replaced elements with a complex relation between width and height are HTML files and objects that can only take certain discrete sizes, such as a command a line that must be a whole number of characters wide and high.
For non-replaced elements, ''auto'' on 'height' is always the intrinsic height that corresponds to the element's computed width. The computed value of ''auto'' on 'width' depends on the type of box:
Note that in CSS2, floating elements (case 1) were given a certain small, UA-dependent width, but in CSS3 they are given their intrinsic width (often referred to as "shrink-wrapped").
'Min-width', 'max-width', 'min-height' and 'max-height' impose further constraints on the computed value. See below.
Should this algorithm be defined by CDF/WICD instead? Or by some plug-in API? If the replaced object has a complex relation between width and height, then the CSS UA cannot itself compute the value to use for ''auto'' or ''shrink-wrap''. Instead, the UA has to ask an external “oracle”. We assume there is a function that the CSS UA can call, which takes as input the following parameters:
Note that most can be of various types: <length>, <percentage>, ''auto'', ''shrink-wrap'' or ''none''.
The auxiliary width is the width of the containing block minus this element's margin, padding and border, unless the containing block's width depends on this element's width, in which case the width of the viewport is given. The suggested height is analogous, but using the containing block's height.
The returned values are
If 'width' is ''auto'' or ''shrink-wrap'', the used width will be
max(min-width, min(preferred-width, max(min-width, max-width)))
If 'height' is ''auto'' or ''shrink-wrap'', the used height will be
max(min-height, min(preferred-height, max(min-height, max-height)))
If the used width is different from the preferred width, the UA may call the oracle again with the used width instead of the computed width in order to get a new value for the preferred height.
Note that the size of the box may still be different from the object's preferred size. Whether the object resizes to the box's size or not depends on the object. The 'fit' property determines how the object is positioned relative to the box if their sizes differ.
If a CSS UA is used as an oracle, it should behave as follows: The parameters should be interpreted as the corresponding style rules on the root element of the object (':root') with specificity 1 at the start of the author style sheet. The auxiliary width and height should be interpreted as the size of the viewport.
The following example of an HTML file with another HTML file transcluded is rendered with the transclusion taking its full height. The visual result will be very much as if the trancluded document was simply a block element in the outer document (except that it doesn't share its style).
...
<style type="text/css">
object {display: block; width: 100%; height: shrink-wrap}
</style>
...
<object data="other.html">
<p>See <a href="other.html">other</a> document.
</object>
...
Note that the oracle may need to have access to the whole object before computing its width and height. E.g., the height of a transcluded HTML file is only known after the whole file has been downloaded and formatted. Thus the use of ''shrink-wrap'' may cause a delay in the rendering of a document, or may cause reflow if the oracle is called asynchronously.
Note that there was no concept of “complex width/height” in CSS level 2, so UAs that understand level 3 will use a different size for transcluded HTML files than UAs for level 2. In particular, level 2 UAs will render a 300 by 150px block with scrollbars instead of a block that is as big as neeeded to contain the transclusion.
| Name: | float-displace |
| Value: | line | indent | block | block-within-page |
| Initial: | line |
| Applies to: | all block-level elements |
| Inherited: | yes |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | Same as specified value |
| Computed value: | specified value |
Alternative definition, that (1) avoids the need for 'indent-edge-reset' and (2) changes not just the line boxes, but also the content edge, so that list markers stay close to the content:
Line boxes are shortened so they don't overlap floats. See below for the details. The element's margin, border or padding are not influenced by the presence of floats. (This is the only behavior in CSS level 2.)
Line boxes are first shortened as for ''line''. If the distance between the start edge of the content box and the start edge of the line box is then not zero, then that distance is further increased by the element's relative indent (defined below). Ditto for the end edge. The element's margin, border or padding are not influenced by the presence of floats.
The margins of the element are increased (and the width thus reduced) by the amount necessary so that the border box of the element doesn't overlap any floats in the same flow that are created by elements earlier in the document; and then the margins are increased even more by the amount of the relative indent on the relevant side of the element. If that causes the element to have more overflow than it would have had with a value of ''line'', the element is moved down instead (by adding clearance) just enough that it doesn't have more overflow, or that its top border edge is just below the bottom margin edge of all floats.
Line boxes inside the element are shortened and/or moved as needed the same way as for ''line''.
Note that floats that are descendants of the element do not influence the element's margins, but they may influence the line boxes.
Like block, except that the parts of the element on different pages are treated as separate blocks for the purpose of this property and are only indented as necessary to avoid floats on the same page.
Note that centered text ('text-align' is ''center'') is centered relative to the content edges, not relative to the edges of the line box.
Note also that ''block'' and ''block-within-page'' influence the position of the element's list marker (if any), because list markers are positioned relative to the content edge. Indeed, this may be the main reason for using 'float-displace': to move the list markers from one side of the float (or on top of the float) to the other side.
A line box normally stretches from an element's content edge to the opposite content edge, unless it overflows (see [[!CSS3TEXT]]), but if the element's 'float-displace' is ''line'' or ''indent'' it may fall short of either or both content edges. The following defines how line boxes are shortened in the case of ''line'':
For all elements E, and all floats F whose parent is in the same flow as E, and all line boxes L of E: if L contains any inline boxes that are generated by elements that come after F in the document, then L must may not overlap the exclusion zone of F.
Note that a line box next to a float cannot overflow: if an inline box is too wide for a shortened line box, the line box is left empty and the inline box is put in the next line box in which it fits, or the next one that is not shortened by floats. [Is this indeed correctly defined in [[!CSS3TEXT]]?]
Implementation note: Note that the height of a line box depends on its content. It may be, e.g., that a line box next to a float has enough room horizontally for three words, but adding the third word would increase the height of the line box and make it overlap the next float further down. In that case the third word cannot be added to that line box and must be put in the next line box (or even further down).
The relative indent on side S of an element E is defined recursively as follows:
How line boxes are constructed is explained in the CSS Text Module [[!CSS3TEXT]]. The presence of a float modifies that construction in two ways: the length of the line box can become shorter (i.e., shorter than the distance between the element's content edges) and, unlike a normal line box, such a shorter line box may be empty. The following describes these effects in detail.
We consider construction of line boxes in horizontal elements first. (Vertical elements are analogous and are defined below.) Let L be a line box
Yet another alternative. This one adds a fixed indent rather than one that depends on the context:
Value: auto | <length> && [ block | block-within-page ]? Inherited: no
Line boxes are shortened and/or moved so they don't overlap floats. (This is the only behavior in CSS level 2.)
Line boxes are shortened and/or moved as for ''auto'', except that the amount they are shortened by, if possible, is equal to the amount necessary to not overlap any float plus the given <length>.
If the keyword ''block'' is present in addition to a <length>, the margins of the element are increased (and the width thus reduced) by the amount necessary so that the border box of the element doesn't overlap any floats in the same flow that are created by elements earlier in the document; and then the margins are increased even more by the given <length>. If that causes the element to have more overflow than it would have had with a value of ''auto'', the element is moved down instead (by adding clearance) just enough that it doesn't have more overflow, or that its top border edge is just below the bottom margin edge of all earlier floats in the same flow.
Line boxes inside the element are shortened and/or moved as needed the same was as for ''auto''.
Note that floats that are descendants of the element do not influence the element's margins, but they may influence the line boxes.
Like block, except that the parts of the element on different pages are treated as separate blocks for the purpose of this property and are only indented as necessary to avoid floats on the same page.
Note that all values, except ''auto'', also cause centered lines to no longer be centered if they are next to a float.
Note also that ''block'' and ''block-within-page'' influence the position of the element's list marker (if any), because list markers are positioned relative to the content edge. Indeed, this may be the main reasons for using 'float-displace': to move the list markers from one side of the float (or on top of the float) to the other side.
Example: Assume that the floating image is tall than the paragraph it is part of.
img {float: left}
ul {float-displace: 2em block}
li {margin-left: 2em}
with document fragment
<p> <img src=... alt=... style="float: left"> Paragraph before the list. <ul> <li>First item <li>Second item </ul>
Without the image, the rendering might look like this:
Paragraph before the list. * First item * Second item
With the image, but without the rule for 'float-displace', the output might look like this:
+----+Paragraph before the list. |\ /| | */ |First item | *\ |Second item |/ \| +----+
With the 'float-displace' rule, the UL is indented extra to avoid the image, plus 2em more:
+----+Paragraph before the list. |\ /| | \/ | * First item | /\ | * Second item |/ \| +----+
This property determines the line wrapping policy in the presence of floats. Values have the following meanings:
Example of 'float-displace: indent'. Note that the “bar” paragraph has the same indent (green arrow) next to the float as below it .
The containing block's width as used by the horizontal formatting model is reduced by the width of the floats intruding upon its content area (not taking into account floating descendants or floating elements that appear later in the document tree). The block is then flowed in this reduced containing block width.
If the effective containing block width is, by the algorithm given above, reduced to a value smaller than the sum of the margin-left, border-width-left, padding-left, width, padding-right, border-width-right, and margin-right values (treating any 'auto' values as zero) then the margin-top of the block is increased until the effective containing block width is no longer so constrained or until all floats have been cleared, whichever occurs first.
Example of 'float-displace: block'
A set of rules for HTML might look like this:
OL, UL, LI {float-displace: indent}
TABLE {float-displace: block}
Lines in a list will get extra indentation when they are next to a float, so you can still see that they are part of the list, and tables will be made narrower as a whole.
| Name: | indent-edge-reset |
| Value: | none | margin-edge | border-edge | padding-edge | content-edge | inherit |
| Initial: | none |
| Applies to: | all elements with a block-level inner formatting context. |
| Inherited: | no |
| Percentages: | n/a |
| Media: | visual |
| Computed value: | specified value |
This property determines which edge to use as the reference indent edge when calculating the amount of indent to preserve when the value of 'float-displace' is set to ''indent''.
The reference indent edge is the nearest ancestor in the same formatting context which has a non-none value for 'indent-edge-reset'. If no ancestor in the formatting context has a value specified for this property, then the content edge of the root of the formatting context is used.
Levels 1, 2 and 3…
UAs that render must either support vertical elements or the ''vertical'' media feature.
As described in the W3C process document, a Candidate Recommendation (CR) is a specification that W3C recommends for use on the Web. The next stage is “Recommendation,” when the specification is sufficiently implemented.
For this specification to be proposed as a W3C Recommendation, the following conditions shall be met. There must be at least two independent, interoperable implementations of each feature. Each feature may be implemented by a different set of products, there is no requirement that all features be implemented by a single product. For the purposes of this criterion, we define the following terms:
A minimum of sixth months of the CR period must have elapsed. This is to ensure that enough time is given for any remaining major errors to be caught.
Features will be dropped if two or more interoperable implementations are not found by the end of the CR period.
Features may/will also be dropped if adequate/sufficient (by judgment of CSS WG) tests have not been produced for those feature(s) by the end of the CR period.
To do…
Normative references:
Informative references: