1. Introduction
This section is not normative.
The CSS layout algorithms, by default, size and position boxes in relation to each other so that nothing overlaps.
This specification defines several ways to violate these assumptions when needed, moving elements around in ways that can make them overlap other content:
-
Relative positioning, which visually shifts a box relative to its laid-out location.
-
Sticky positioning, which visually shifts a box relative to its laid-out location in order to keep it visible when a scrollable ancestor would otherwise scroll it out of sight.
-
Absolute positioning, which ignores normal layout entirely, pulling the element out of flow and positioning it relative to its containing block with no regard for other content.
-
Fixed positioning, which absolutely positions the box and affixes it to the viewport or page frame so that it is always visible.
These positioning schemes, controlled by the position property and the inset properties, are powerful but easy to misuse. With appropriate care, they allow many interesting and useful layouts that couldn’t otherwise be achieved with standard layout rules; without, they allow a page to be laid out in an unusable overlapping jumble of content.
1.1. Module Interactions
This module replaces and extends the positioning scheme features defined in [CSS2] sections:
- 9.1.2 Containing blocks
- 9.3 Positioning schemes
- 9.4.3 Relative positioning
- 9.6 Absolute positioning
- 9.7 Relationships between display, position, and float
- 9.8 Comparison of normal flow, floats, and absolute positioning
- 10.1 Definition of "containing block"
- 10.3.7 Absolutely positioned, non-replaced elements
- 10.3.8 Absolutely positioned, replaced elements
- 10.6.4 Absolutely positioned, non-replaced elements
- 10.6.5 Absolutely positioned replaced elements
It also replaces and supersedes the inset* property definitions in [CSS-LOGICAL-1] (CSS Logical Properties 1 § 4.3 Flow-relative Offsets: the inset-block-start, inset-block-end, inset-inline-start, inset-inline-end properties and inset-block, inset-inline, and inset shorthands).
1.2. Value Definitions
This specification follows the CSS property definition conventions from [CSS2] using the value definition syntax from [CSS-VALUES-3]. Value types not defined in this specification are defined in CSS Values & Units [CSS-VALUES-3]. Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions, all properties defined in this specification also accept the CSS-wide keywords as their property value. For readability they have not been repeated explicitly.
2. Choosing A Positioning Scheme: position property
Name: | position |
---|---|
Value: | static | relative | absolute | sticky | fixed |
Initial: | static |
Applies to: | all elements except table-column-group and table-column |
Inherited: | no |
Percentages: | N/A |
Computed value: | specified keyword |
Canonical order: | per grammar |
Animation type: | discrete |
The position property determines which of the positioning schemes is used to calculate the position of a box. Values other than static make the box a positioned box, and cause it to establish an absolute positioning containing block for its descendants. Values have the following meanings:
- static
- The box is not a positioned box, and is laid out according to the rules of its parent formatting context. The inset properties do not apply.
- relative
- The box is laid out as for static, then offset from the resulting position. This offsetting is a purely visual effect, and, unless otherwise specified, does not affect the size or position of any other non-descendant box except insofar as it increases the scrollable overflow area of its ancestors. This positioning scheme is called relative positioning.
- sticky
- Identical to relative, except that its offsets are automatically adjusted in reference to the nearest ancestor scroll container’s scrollport (as modified by the inset properties) in whichever axes the inset properties are not both auto, to try to keep the box in view within its containing block as the user scrolls. This positioning scheme is called sticky positioning.
- absolute
-
The box is taken out of flow
such that it has no impact on the size or position of its siblings and ancestors,
and does not participate in its parent’s formatting context.
Instead, the box is positioned and sized solely in reference to its absolute positioning containing block, as modified by the box’s inset properties, see § 4 Absolute Positioning Layout Model. It can overlap in-flow content or other absolutely positioned elements, and is included in the scrollable overflow area of the box that generates is containing block. This positioning scheme is called absolute positioning.
- fixed
-
Same as absolute,
except the box is positioned and sized relative to a fixed positioning containing block
(usually the viewport in continuous media, or the page area in paged media).
The box’s position is fixed with respect to this reference rectangle:
when attached to the viewport
it does not move when the document is scrolled,
and when attached to the page area
is replicated on every page when the document is paginated.
This positioning scheme is called
fixed positioning
and is considered a subset of absolute positioning.
Authors may wish to specify fixed in a media-dependent way. For instance, an author may want a box to remain at the top of the viewport on the screen, but not at the top of each printed page. The two specifications may be separated by using an '@media' rule, as in:
@media screen{ h1#first{ position : fixed} } @media print{ h1#first{ position : static} }
A position value of absolute or fixed blockifies the box, causes float to compute to none, and forces the box to establish an independent formatting context.
2.1. Containing Blocks of Positioned Boxes
The containing block of a static, relative, or sticky box is as defined by its formatting context. For fixed and absolute boxes, it is defined as follows:
- If the box has position: absolute:
-
The containing block is established
by the nearest ancestor box that establishes an absolute positioning containing block,
in the following way:
- If the ancestor is not an inline box,
- the containing block is formed by the padding edge of the ancestor, unless otherwise specified (for example, see CSS Grid Layout 1 § 9.1 With a Grid Container as Containing Block).
- If the ancestor is an inline box, using the writing mode of that box,
-
the containing block is formed by forming a rectangle from
the start-most content edges (in both axes) of the first box fragment of the ancestor,
and the end-most content edges of the end-most box fragment(s) of the ancestor in each axis.
If there are multiple fragments on the same line
(e.g. due to bidi reordering),
take the start-most fragment
as the first fragment.
What is a useful containing block to form when the box is fragmented across multiple lines? [Issue #8284]
Note: The containing block formed by a fragmented inline box was undefined in [CSS2].
If no ancestor establishes one, the absolute positioning containing block is the initial containing block.
Note: Properties that can cause a box to establish an absolute positioning containing block include position, transform, will-change, contain…
- If the box has position: fixed:
-
The containing block is established
by the nearest ancestor box that establishes an fixed positioning containing block,
with the bounds of the containing block
determined identically to the absolute positioning containing block.
Note: Properties that can cause a box to establish a fixed positioning containing block include transform, will-change, contain…
If no ancestor establishes one, the fixed positioning containing block is:
-
in continuous media, the layout viewport (whose size matches the dynamic viewport size); as a result, fixed boxes do not move when the document is scrolled.
Note: In this respect, they are similar to fixed background images (background-attachment: fixed).
-
in paged media, the page area of each page; fixed positioned boxes are thus replicated on every page. (They are fixed with respect to the page box only, and are not affected by being seen through a viewport; as in the case of print preview, for example.)
Note: As a result, parts of fixed-positioned boxes that extend outside the layout viewport/page area cannot be scrolled to and will not print.
-
With no positioning, the containing blocks (C.B.) in the following document:
<!DOCTYPE html> < html > < head > < title > Illustration of containing blocks</ title > </ head > < body id = "body" > < div id = "div1" > < p id = "p1" > This is text in the first paragraph...</ p > < p id = "p2" > This is text< em id = "em1" > in the< strong id = "strong1" > second</ strong > paragraph.</ em ></ p > </ div > </ body > </ html >
are established as follows:
For box generated by | C.B. is established by |
---|---|
html | initial C.B. (UA-dependent) |
body | html |
div1 | body |
p1 | div1 |
p2 | div1 |
em1 | p2 |
strong1 | p2 |
If we position "div1":
#div1{ position : absolute; left : 50 px ; top : 50 px }
its containing block is no longer "body"; it becomes the initial containing block (since there are no other positioned ancestor boxes).
If we position "em1" as well:
#div1{ position : absolute; left : 50 px ; top : 50 px } #em1{ position : absolute; left : 100 px ; top : 100 px }
the table of containing blocks becomes:
For box generated by | C.B. is established by |
---|---|
html | initial C.B. (UA-dependent) |
body | html |
div1 | initial C.B. |
p1 | div1 |
p2 | div1 |
em1 | div1 |
strong1 | em1 |
By positioning "em1", its containing block becomes the nearest positioned ancestor box (i.e., that generated by "div1").
2.1.1. Further Adjustments to the Containing Block
Some features can alter the effective containing block rectangle of absolutely positioned boxes. These are applied in the following order, with earlier steps modifying the containing block that later steps see:
-
The grid-placement properties on an absolutely positioned box whose containing block is generated by a grid container can change the containing block rectangle to a specified grid area. See CSS Grid Layout 1 § 9.1 With a Grid Container as Containing Block.
-
The position-area and position-try properties can change the containing block rectangle to a specified area of an position-area grid. See CSS Anchor Positioning § 3.1 The position-area Property.
The element’s original containing block is its containing block before applying any of these effects.
2.2. Painting Order and Stacking Contexts
The z-index property applies to all positioned boxes. When z-index is auto:
-
Fixed and sticky positioned boxes nonetheless form a stacking context.
-
Relative and absolute positioned boxes do not form a stacking context, but are painted as if those elements did generated new stacking contexts, except that their positioned descendants and any would-be child stacking contexts take part in the current stacking context.
Note: The root element always forms a stacking context regardless.
See CSS2 § 9.9 Layered presentation and Appendix E: Elaborate description of Stacking Contexts for details about z-index, stacking contexts, and painting order.
3. Positioning Coordinates
The precise location of a positioned box is controlled by the inset properties: the physical inset properties top, right, bottom, left; the flow-relative inset properties inset-block-start, inset-inline-start, inset-block-end, and inset-inline-end; and their shorthands, inset-block, inset-inline, and inset.
The interpretation of these inset properties varies by positioning scheme:
-
for absolute positioning, they represent insets from the containing block.
-
for relative positioning, they represent insets from the box’s original margin edge.
-
for sticky positioning, they represent insets from the scrollport edge.
3.1. Box Insets: the top, right, bottom, left, inset-block-start, inset-inline-start, inset-block-end, and inset-inline-end properties
Name: | top, right, bottom, left, inset-block-start, inset-inline-start, inset-block-end, inset-inline-end |
---|---|
Value: | auto | <length-percentage> |
Initial: | auto |
Applies to: | positioned elements |
Inherited: | no |
Percentages: | refer to size of containing block; see prose |
Computed value: | the keyword auto or a computed <length-percentage> value |
Canonical order: | per grammar |
Animation type: | by computed value type |
Logical property group: | inset |
These inset properties represent an inward “inset” on the corresponding side of the box (with respect to the box’s own writing mode; see CSS Writing Modes 3 § 6 Abstract Box Terminology). For example, top represents a downward inset of the top edge. The physical and flow-relative properties interact as defined in [CSS-LOGICAL-1]. Values have the following meanings:
- <length>
- The inset is a fixed distance from the reference edge. Negative values are allowed.
- <percentage>
- The inset is a percentage relative to the containing block’s size in the corresponding axis (e.g. width for left or right, height for top and bottom). For sticky positioned boxes, the inset is instead relative to the relevant scrollport’s size. Negative values are allowed.
- auto
- Represents an unconstrained inset; the exact meaning depends on the positioning scheme.
Note: For fixed positioned elements, using large values or negative values can easily move elements outside the viewport and make the contents unreachable through scrolling or other means.
3.2. Box Insets Shorthands: the inset-block, inset-inline, and inset properties
Name: | inset-block, inset-inline |
---|---|
Value: | <'top'>{1,2} |