Position Values at a Glance

position: static

1
2
3

Default. Elements follow normal document flow.

position: relative

1
2
3

Offset from normal position. Space preserved.

position: absolute

1
3
2

Removed from flow. Positioned to ancestor.

position: fixed

1
3
Fixed

Fixed to viewport. Stays on scroll.

position: sticky

Sticky

Hybrid. Relative until scroll threshold.

Static Position (Default)

position: static is the default value. Elements appear in the normal document flow and ignore top, right, bottom, left, and z-index properties.

position: static (default)
Box 1
Box 2
Box 3

Elements flow naturally. Setting top, left, etc. has no effect on static elements.

.element {
  position: static; /* default - top/right/bottom/left ignored */
}

Relative Position

position: relative offsets the element from its normal position. The original space is preserved in the document flow.

position: relative; top: 30px; left: 20px
Static
Original
Relative
Static

The green box moves 30px down and 20px right from where it would normally be. The dashed outline shows its original position in the flow.

Key Insight

Relative positioning moves the visual rendering but keeps the element's space in the flow. Other elements don't fill the gap left behind.

.relative-box {
  position: relative;
  top: 30px;   /* moves down */
  left: 20px;  /* moves right */
}

Absolute Position

position: absolute removes the element from normal flow and positions it relative to its nearest positioned ancestor (or the viewport if none exists).

position: absolute with various offsets
Top Left
Top Right
Center
Bottom Right

Absolute elements position themselves relative to the demo container (which has position: relative). The center box uses the transform: translate(-50%, -50%) centering technique.

Positioning Context

An absolutely positioned element looks for the nearest ancestor with position set to relative, absolute, fixed, or sticky. If none found, it positions to the viewport.

.parent { position: relative; }

.absolute-child {
  position: absolute;
  top: 20px;
  right: 20px;
}

/* Center technique */
.centered {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}

Fixed Position

position: fixed positions the element relative to the viewport. It stays in place even when the page scrolls.

position: fixed; bottom: 30px; right: 30px

Click to show a fixed position element in the bottom-right corner

Fixed elements are removed from document flow and positioned relative to the viewport. Common uses: navigation bars, floating action buttons, cookie notices.

Click to hide
.fixed-button {
  position: fixed;
  bottom: 30px;
  right: 30px;
  z-index: 1000;
}

Sticky Position

position: sticky is a hybrid between relative and fixed. The element behaves as relative until a scroll threshold is met, then becomes fixed.

position: sticky; top: 0

Scroll down to see the sticky header in action...

This content scrolls normally beneath the sticky header.

The header will stick to the top of its scroll container when you scroll past it.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.

Sticky positioning is perfect for section headers, navigation, and table headers.

Unlike fixed positioning, sticky elements remain within their parent container.

Keep scrolling to see it stick!

When you scroll back up, it returns to its normal position in the flow.

This creates a natural, intuitive user experience.

The purple header sticks to the top when scrolling. Unlike fixed, it stays within its container bounds.

Sticky Requirements

Sticky positioning requires: 1) A scroll container (parent with overflow: auto/scroll), 2) A threshold (top, bottom, etc.), and 3) The parent must have sufficient height to scroll.

.sticky-header {
  position: sticky;
  top: 0; /* sticks at top of scroll container */
}

Z-Index Stacking

The z-index property controls the stacking order of positioned elements. Higher values appear in front of lower values.

z-index: 1, 2, 3
z-index: 1
z-index: 2
z-index: 3

Each box overlaps the previous one. The purple box (z-index: 3) appears on top because it has the highest stack order.

.layer-1 { position: absolute; z-index: 1; }
.layer-2 { position: absolute; z-index: 2; }
.layer-3 { position: absolute; z-index: 3; }

Inset Shorthand

The inset property is a shorthand for top, right, bottom, and left. It simplifies creating full-coverage overlays and positioned containers.

inset: 20px
inset: 20px
(20px from all edges)

Using inset: 20px is equivalent to setting top, right, bottom, and left all to 20px.

.box { inset: 20px; } /* all sides */
.box { inset: 10px 20px; } /* vertical | horizontal */
.overlay { position: fixed; inset: 0; } /* full viewport */

Anchor Positioning

CSS Anchor Positioning lets you tether an element to an "anchor" element on the page. The positioned element automatically tracks its anchor, making it perfect for tooltips, popovers, and dropdown menus, without any JavaScript.

Browser Support: Anchor positioning is available in Chrome 125+, Edge 125+. Firefox and Safari have partial/no support. The demos below simulate the behavior with JavaScript so they work everywhere.

How It Works

1. Declare an anchor with anchor-name: --my-anchor
2. Point a positioned element at it with position-anchor: --my-anchor
3. Place it using position-area (logical grid) or the anchor() function (precise edges)
4. Add fallbacks with position-try-fallbacks for when space runs out

position-area Explorer

The position-area property places an anchored element on a conceptual 3×3 grid surrounding the anchor. Click any cell below to see where the target lands.

position-area: top
Anchor
Positioned

Click a position:

Generated CSS:

/* 1. Define the anchor */ .anchor { anchor-name: --my-anchor; } /* 2. Position the target */ .target { position: fixed; position-anchor: --my-anchor; position-area: top; }
/* Anchor element */
.button {
  anchor-name: --tooltip-anchor;
}

/* Positioned tooltip */
.tooltip {
  position: fixed;
  position-anchor: --tooltip-anchor;
  position-area: top;    /* appears above the anchor */
  margin-bottom: 8px;    /* gap between anchor and tooltip */
}

The anchor() Function

For precise control, use the anchor() function inside inset properties. It returns the computed position of a specific edge of the anchor element.

anchor() edge alignment
Anchor
top bottom left right
Target Element
.target { position: fixed; position-anchor: --my-anchor; bottom: anchor(top); left: anchor(center); translate: -50% 0; }

anchor(top) returns the top edge, anchor(center) the midpoint. Combine with translate for perfect centering.

/* anchor() returns the position of an anchor edge */
.tooltip {
  position: fixed;
  position-anchor: --btn;

  /* Place tooltip above the button, centered */
  bottom: anchor(top);
  left: anchor(center);
  translate: -50% 0;
  margin-bottom: 8px;
}

/* Available edges: top, right, bottom, left, center */
/* For x-axis: left, center, right  */
/* For y-axis: top, center, bottom  */

Fallback Positions

When an anchored element would overflow its container, position-try-fallbacks lets you define alternative positions. The browser automatically picks the first one that fits.

position-try-fallbacks: flip-block
Anchor
Tooltip (top)
position-area: top

Drag the slider to push the anchor toward the bottom and watch the tooltip flip!

.tooltip { position: fixed; position-anchor: --btn; position-area: top; /* Flip vertically if no room above */ position-try-fallbacks: flip-block; }

When the anchor is near the top edge, the tooltip automatically flips below. flip-block mirrors the block axis (top↔bottom), flip-inline mirrors inline (left↔right).

/* Auto-flip when out of space */
.tooltip {
  position: fixed;
  position-anchor: --menu-btn;
  position-area: top;

  /* Built-in fallback keywords */
  position-try-fallbacks: flip-block;          /* top ↔ bottom */
  position-try-fallbacks: flip-inline;         /* left ↔ right */
  position-try-fallbacks: flip-block flip-inline; /* both axes */
}

/* Custom fallback sequence */
@position-try --below {
  position-area: bottom;
}
@position-try --right {
  position-area: right;
}
.tooltip {
  position-try-fallbacks: --below, --right;
}

Spanning with position-area

Add span- prefixes to make an anchored element stretch across multiple grid cells. This is useful for wide dropdowns or full-width popovers.

Spanning examples

position-area: top / span-all

target
target
target
ANCHOR
.dropdown { position: fixed; position-anchor: --menu; position-area: top / span-all; }
/* Span the full width above the anchor */
.dropdown {
  position: fixed;
  position-anchor: --trigger;
  position-area: bottom / span-all;
}

/* Span to the left from center */
.panel {
  position-area: top / span-left;
}

/* Two-value syntax: block-axis / inline-axis */