CSS Positioned Layout Module Level 3

Editor’s Draft,

More details about this document
This version:
https://drafts.csswg.org/css-position-3/
Latest published version:
https://www.w3.org/TR/css-position-3/
Feedback:
CSSWG Issues Repository
Inline In Spec
in Wiki
Editors:
Elika J. Etemad / fantasai (Apple)
Tab Atkins Jr. (Google)
Former Editors:
(Microsoft)
(Microsoft)
Suggest an Edit for this Spec:
GitHub Editor

Abstract

This module contains defines coordinate-based positioning and offsetting schemes of CSS: relative positioning, sticky positioning, absolute positioning, and fixed positioning.

CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

Please send feedback by filing issues in GitHub (preferred), including the spec code “css-position” in the title, like this: “[css-position] …summary of comment…”. All issues and comments are archived. Alternately, feedback can be sent to the (archived) public mailing list [email protected].

This document is governed by the 18 August 2025 W3C Process Document.

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:

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:

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:

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: 50px; top: 50px }

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: 50px; top: 50px }
#em1  { position: absolute; left: 100px; top: 100px }

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:

  1. 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.

  2. 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:

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:

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}