Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
CSS Floats and Positioning Level 3 allows authors to have text and other inline content wrap around specified elements, thereby allowing for the creation of more intricate layouts than is currently possible with existing CSS floaters. Specifically, CSS 3 Floats, also known as "positioned floats", can be absolutely positioned on a web document, while still affecting the document flow. Authors can individually specify whether intersected block elements surrounding a positioned float (e.g. paragraphs, divs, etc.) overlap with the positioned float, and if so how they overlap with it. Positioned float can also be styled with a wrap-shape property, which specifies both how text within the positioned float is laid out and how content outside the positioned float wraps around the positioned float. It is also possible to define a shape based on transparency values within an image.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the CSS Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to www-style@w3.org (subscribe, archives). All feedback is welcome.
Publication as a Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This CSS3 module depends on the following other CSS3 modules:
This CSS3 module has normative references to the following other CSS3 modules:
This CSS3 module has non-normative (informative) references to the following other CSS3 modules:
| Name: | float |
| Value: | [ none | left | right | inherit | positioned ] |
| Initial: | none |
| Applies To: | all elements, but see Relationships between 'display', 'position', and 'float' |
| Inherited: | yes |
| Media: | visual |
| Computed value: | as specified |
This property specifies whether a box should float content around itself, or not at all. It may be set for any element, but only applies to elements that generate boxes that are not absolutely positioned when values 'left' and 'right' are used. The values of this property have the following meanings:
User agents may treat float as 'none' on the root element.
Here are the precise rules that govern the behavior of 'left' or 'right' floats [CSS21]:
If, within the block formatting context, there is an in-flow negative vertical margin such that the float's position is above the position it would be at were all such negative margins set to zero, the position of the float is undefined.
References to other elements in the above rules refer only to other elements in the same block formatting context as the left or right float.
The precise rules for 'positioned' floats are as follows:
#figure
{
width: 100px;
height: 100px;
background-color: blue;
float: positioned;
position: absolute;
bottom: 50px;
left: 40%;
}
Positioned float 50px above bottom border and 40% container from the left containing block border.
| Name: | position |
| Value: | [ static | absolute | fixed | relative | page ] |
| Initial: | none |
| Applies To: | all elements |
| Inherited: | yes |
| Media: | visual |
| Computed value: | as specified |
The values of this property have the following meanings:
@media screen {
h1#first { position: fixed }
}
@media print {
h1#first { position: static }
}
User agents must not paginate the content of fixed boxes. User agents may choose to treat 'position: fixed' positioned floats as position: page.
Note that user agents may print invisible content in other ways. See "Content outside the page box" in Chapter 13, Paged media. [CSS21]
In the illustration following the example, content has been spread across two pages. A positioned float embedded in the content will be positioned 50px from the bottom edge of whatever page the positioned float is rendered in.
#figure
{
width: 100px;
height: 100px;
background-color: blue;
float: positioned;
position: page;
bottom: 50px;
}
Note that when float: positioned and position:
page is set,
the position of the positioned float is calculated relative to the
initial containing block and is not updated repeatedly as the containing
block moves
(for example, when content in the user agent window is scrolled).
The first image below shows how the positioned float is offset from the bottom of the initial containing block, while the second image shows that the positioned float remains in its initial position relative to content, even after the content is moved relative to the viewport.
#figure
{
width: 200px;
height: 100px;
background-color: blue;
float: positioned;
position: page;
bottom: 50px;
}
In the following illustration, a positioned float has been positioned based on the initial position of the content relative to the UA window.
In the following illustration, the positioned float's position is maintained, even as the content scrolls upward.
User agents may treat position as 'static' on the root element.
An element is said to be positioned
if its
position property
has a value other than static.
Positioned
elements generate positioned boxes, laid out according to four
properties:
| Name: | top |
| Value: | [ <length> | <percentage> | auto ] |
| Initial: | auto |
| Applies To: | positioned elements and positioned floats |
| Inherited: | no |
| Percentages: | refer to height of containing block |
| Media: | visual |
| Computed value: | If specified as a length, the corresponding absolute length; if specified as a percentage, the specified value; otherwise 'auto'. |
The top property specifies how far an absolutely positioned box's top margin edge is offset below the top edge of the box's containing block. For relatively positioned boxes, the offset is with respect to the top edges of the box itself (i.e., the box is given a position in the normal flow, then offset from that position according to these properties). For page positioned boxes, the offset is with respect to the top edge of the initial containing box itself.
| Name: | right |
| Value: | [ <length> | <percentage> | auto ] |
| Initial: | auto |
| Applies To: | positioned elements and positioned floats |
| Inherited: | no |
| Percentages: | refer to height of containing block |
| Media: | visual |
| Computed value: | If specified as a length, the corresponding absolute length; if specified as a percentage, the specified value; otherwise 'auto'. |
Like top, but specifies how far a box's right margin edge is offset to the left of the right edge of the box's containing block. For relatively positioned boxes, the offset is with respect to the right edge of the box itself. For page positioned boxes, the offset is with respect to the right edge of the initial containing box itself.
| Name: | bottom |
| Value: | [ <length> | <percentage> | auto ] |
| Initial: | auto |
| Applies To: | positioned elements and positioned floats |
| Inherited: | no |
| Percentages: | refer to height of containing block |
| Media: | visual |
| Computed value: | If specified as a length, the corresponding absolute length; if specified as a percentage, the specified value; otherwise 'auto'. |
Like top, but specifies how far a box's bottom margin edge is offset above the bottom of the box's containing block. For relatively positioned boxes, the offset is with respect to the bottom edge of the box itself. For page positioned boxes, the offset is with respect to the bottom edge of the initial containing box itself.
| Name: | left |
| Value: | [ <length> | <percentage> | auto ] |
| Initial: | auto |
| Applies To: | positioned elements and positioned floats |
| Inherited: | no |
| Percentages: | refer to height of containing block |
| Media: | visual |
| Computed value: | If specified as a length, the corresponding absolute length; if specified as a percentage, the specified value; otherwise 'auto'. |
Like top, but specifies how far a box's left margin edge is offset to the right of the left edge of the box's containing block. For relatively positioned boxes, the offset is with respect to the left edge of the box itself. For page positioned boxes, the offset is with respect to the left edge of the initial containing box itself.
The values for the four properties have the following meanings:
The three properties that affect box generation and layout - 'display', 'position', and 'float' - interact as follows:
| Specified value | Computed value |
|---|---|
| inline-table | table |
| inline, 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 |
To illustrate the differences between normal flow, relative positioning, left and right floats, positioned floats, and absolute positioning, we provide a series of examples based on the following HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>Comparison of positioning schemes</TITLE>
</HEAD>
<BODY>
<P>Beginning of body contents.
<SPAN id="outer"> Start of outer contents.
<SPAN id="inner"> Inner contents.</SPAN>
End of outer contents.</SPAN>
End of body contents.
</P>
</BODY>
</HTML>
In this document, we assume the following rules:
body { display: block; font-size:12px; line-height: 200%;
width: 400px; height: 400px }
p { display: block }
span { display: inline }
The final positions of boxes generated by the outer and inner elements vary in each example. In each illustration, the numbers to the left of the illustration indicate the normal flow position of the double-spaced (for clarity) lines.
Note. The diagrams in this section are illustrative and not to scale. They are meant to highlight the differences between the various positioning schemes in CSS, and are not intended to be reference renderings of the examples given.
Consider the following CSS declarations for outer and inner that do not alter the normal flow of boxes:
#outer { color: red }
#inner { color: blue }
The <P> element contains all inline content: anonymous inline text and two SPAN elements. Therefore, all of the content will be laid out in an inline formatting context, within a containing block established by the P element, producing something like the following:
To see the effect of relative positioning, we specify:
#outer { position: relative; top: -12px; color: red }
#inner { position: relative; top: 12px; color: blue }
Text flows normally up to the outer element. The outer text is then flowed into its normal flow position and dimensions at the end of line 1. Then, the inline boxes containing the text (distributed over three lines) are shifted as a unit by '-12px' (upwards).
The contents of inner, as a child of outer, would normally flow immediately after the words "of outer contents" (on line 1.5). However, the inner contents are themselves offset relative to the outer contents by '12px' (downwards), back to their original position on line 2.
Note that the content following outer is not affected by the relative positioning of outer.
Note also that had the offset of outer been '-24px', the text of outer and the body text would have overlapped.
Now consider the effect of floating the inner element's text to the right by means of the following rules:
#outer { color: red }
#inner { float: right; width: 130px; color: blue }
Text flows normally up to the inner box, which is pulled out of the flow and floated to the right margin (its 'width' has been assigned explicitly). Line boxes to the left of the float are shortened, and the document's remaining text flows into them.
To show the effect of the 'clear' property, we add a sibling element to the example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>Comparison of positioning schemes II</TITLE>
</HEAD>
<BODY>
<P>Beginning of body contents.
<SPAN id=outer> Start of outer contents.
<SPAN id=inner> Inner contents.</SPAN>
<SPAN id=sibling> Sibling contents.</SPAN>
End of outer contents.</SPAN>
End of body contents.
</P>
</BODY>
</HTML>
The following rules:
#inner { float: right; width: 130px; color: blue }
#sibling { color: red }
cause the inner box to float to the right as before and the document's remaining text to flow into the vacated space:
However, if the 'clear' property on the sibling element is set to 'right' (i.e., the generated sibling box will not accept a position next to floating boxes to its right), the sibling content begins to flow below the float:
#inner { float: right; width: 130px; color: blue }
#sibling { clear: right; color: red }
Next, we consider the effect of absolute positioning. Consider the following CSS declarations for outer and inner:
#outer {
position: absolute;
top: 200px; left: 200px;
width: 200px;
color: red;
}
#inner { color: blue }
which cause the top of the outer box to be positioned with respect to its containing block. The containing block for a positioned box is established by the nearest positioned ancestor (or, if none exists, the initial containing block, as in our example). The top side of the outer box is '200px' below the top of the containing block and the left side is '200px' from the left side. The child box of outer is flowed normally with respect to its parent.
The following example shows an absolutely positioned box that is a child of a relatively positioned box. Although the parent outer box is not actually offset, setting its 'position' property to 'relative' means that its box may serve as the containing block for positioned descendants. Since the outer box is an inline box that is split across several lines, the first inline box's top and left edges (depicted by thick dashed lines in the illustration below) serve as references for 'top' and 'left' offsets.
#outer {
position: relative;
color: red
}
#inner {
position: absolute;
top: 200px; left: -100px;
height: 130px; width: 130px;
color: blue;
}
This results in something like the following:
If we do not position the outer box:
#outer { color: red }
#inner {
position: absolute;
top: 200px; left: -100px;
height: 130px; width: 130px;
color: blue;
}
the containing block for inner becomes the initial containing block (in our example). The following illustration shows where the inner box would end up in this case.
Relative and absolute positioning may be used to implement change bars, as shown in the following example. The following fragment:
<P style="position: relative; margin-right: 10px; left: 10px;">
I used two red hyphens to serve as a change bar. They
will "float" to the left of the line containing THIS
<SPAN style="position: absolute; top: auto; left: -1em; color: red;">--</SPAN>
word.</P>
might result in something like:
First, the paragraph (whose containing block sides are shown in the illustration) is flowed normally. Then it is offset '10px' from the left edge of the containing block (thus, a right margin of '10px' has been reserved in anticipation of the offset). The two hyphens acting as change bars are taken out of the flow and positioned at the current line (due to 'top: auto'), '-1em' from the left edge of its containing block (established by the P in its final position). The result is that the change bars seem to "float" to the left of the current line.
Finally, we consider the effect of positioned floats. Consider the following CSS declarations for outer and inner:
#outer {
float: positioned;
position: absolute;
top: 0px;
left: 100px;
color: red;
}
#inner { color: blue }
These rules cause the top of the outer box to be positioned with respect to its containing block. The containing block for a positioned box is established by the nearest positioned ancestor (or, if none exists, the initial containing block, as in our example). The top side of the outer box is '0px' below the top of the containing block and the left side is '100px' from the left side. Text flows normally up to the outer pox, which is pulled out of the flow and floated. Line boxes to the left and right of the positioned float are shortened, and the document's remaining text flows into them.
Two properties are used to specify how inline content and positioned floats interact. The 'flow-wrap' property applies to block or table elements, and specifies how poistioned floats impact inline content within those elements. Conversely, the 'wrap-type' property applies to positioned floats, and specifies how those positioned floats interact with inline content in block or table elements.
| Name: | flow-wrap |
|---|---|
| Value: | none | wrap |
| Initial: | wrap |
| Applies to: | block elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | as specified |
| Name: | wrap-type |
|---|---|
| Value: | none | around | left | right | top-bottom |
| Initial: | around |
| Applies to: | positioned float elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | as specified |
![]() |
![]() |
![]() |
![]() |
Define a circle as the shape of a positioned float. The center of the circle shape is computed as follows: cx = 50% from the div width, cy = 50% from the div height. The div has the id = "circle" and the center of the circle is calculated percent from the div box dimensions. The radius cannot be specified as percent, therefore is specified in units.
<style>
#circle {
wrap-shape: circle(50%, 50%, 30px);
wrap-margin: 10px;
}
</style>
<div id="circle">
<img src="mycircle.png"/>
</div>
<div>Lorem ipsum</div>
It might be easier to just use the original image alpha channel to define the positioned float shape.
<style>
#circle {
background: url(mycircle.png);
wrap-image: url(mycircle.png);
wrap-margin: 10px;
}
</style>
<div id="circle"></div>
<div>Lorem ipsum</div>

The #circle DIV's shape is used as a shape for the region with content. Note: mycircle.png has a solid fill
There are cases when multiple positioned floats with different 'left' or 'right' modes will overlap the same text lines. In that case the rules will still apply, meaning that overlapping lines will be skipped (see the image below for more details).
We thought about defining a value 'exclusion' ('no-content') for the 'wrap-type' property. Such value would make the wrap shape as exclusion only, as opposed to content. However, we were unable to find a compelling reason/use case for such a value.
A positioned float's shape, which any surrounding text wraps around, and a positioned float's inner shape, which defines how any text inside the positioned float will be shaped, is defined by the wrap-shape property.
| Name: | wrap-shape |
| Value: | [ auto | <shape>] |
| Initial: | auto |
| Applies To: | block elements |
| Inherited: | no |
| Media: | visual |
| Computed value: | as specified |
Shapes are used to describe the value of the wrap-shape property.
The shape can be defined using SVG style basic shapes as defined by the SVG Shapes. [SVG112]
All the lengths can be expressed in percentages and are defined in the coordinate space of the element. Percentages will take into account the element width/height excluding any padding or margins. The (x,y) coordinates are relative to the block's content box.
When defining a polygon area using percentages, the content box of the element must always be fully known in advance.
If the polygon is not closed the user-agent will automatically add a new vertex at the end.
The content of the path() function will be parsed
using SVG PathData notation.
<div id="circle" style="wrap-shape: circle(50%, 50%, 40px); width: 100px; height: 100px;"></div>
In this example, the actual position of the positioned float shape polygon is determined based on the position of the "circle" div element.
| Name: | wrap-image |
|---|---|
| Value: | none | <url> |
| Initial: | none |
| Applies to: | block elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | as specified |
Positioned float shape can be defined by specifying a source image whose alpha channel is used to compute the positioned float shape. As with other image elements, the same values for the 'background-image' property may be used with wrap-image. Furthermore, 'wrap-image-repeat', 'wrap-image-attachment', 'wrap-image-position', and 'wrap-image-size' are all possible properties to use in combination with wrap-image, and are equivalent to the ones available for the background property, as defined in CSS Background module [CSS3BG]. The properties apply only to the wrap-image.
The positioned float shape is computed to be the path that encloses the area where the opacity of the specified image is greater than the wrap-image-threshold value (see below). If the wrap-image-threshold is not specified, the default value to be considered is 50%.
Note: Images can also define cavities and text should wrap inside them. In order to avoid this, another positioned float element can be overlaid.
Positioned float shape defined using the alpha channel of the specified image, opacity threshold 50%.
<style>
#id {
wrap-image: url(myimage.png);
}
</style>
| Name: | wrap-image-threshold |
|---|---|
| Value: | <percent> |
| Initial: | 50% |
| Applies to: | block elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Computed value: | as specified |
Defines the alpha channel threshold used to define the wrap-shape using an image. The default is 50%, meaning that all the pixels that are more than 50% transparent define the path of the positioned float shape.
Positioned float shape defined using the alpha channel of the specified image, opacity filter 75%.
<style>
#id {
wrap-image: url(myimage.png);
wrap-image-threshold: 75%;
}
</style>
| Name: | wrap-margin |
|---|---|
| Value: | <length> |
| Initial: | 0 |
| Applies to: | positioned floats |
| Inherited: | no |
| Percentages: | refer to width of containing block |
| Media: | visual |
| Computed value: | as specified |
| Name: | wrap-padding |
|---|---|
| Value: | <length> |
| Initial: | 0 |
| Applies to: | block elements |
| Inherited: | no |
| Percentages: | refer to width of containing block |
| Media: | visual |
| Computed value: | as specified |
The wrap-margin and wrap-padding properties can be used to further offset the inner or outer wrap shape from each other. Note that these properties only take non-negative values.
Text wrapping around an irregular shape.
<style>
#div2 {
wrap-shape: poly(50px, 50px, 10px);
wrap-margin: 10px;
wrap-padding: 10px;
}
</style>
This spec would not have been possible without input and support from Eugene Veselov and Markus Mielke.