CSS: Positioning

Control exactly where elements appear on the page.

The position Property

The position property determines how an element is placed in the document. Once positioned, the top, right, bottom, and left properties move it.

ValueIn Flow?Positioned Relative To
staticYesNormal document flow: top/left/etc. have no effect
relativeYesIts own original position in the flow
absoluteNoNearest positioned ancestor (not static)
fixedNoThe viewport: stays visible while scrolling
stickyYes (until threshold)Normal flow until scroll threshold, then viewport

position: static (Default)

Every element has position: static by default. Elements flow one after another in the order they appear in the HTML. The top, right, bottom, and left properties have no effect on static elements.

position: static

Static is the default. Elements stack vertically as block elements or flow inline. offset properties (top, left, etc.) are ignored.

  • Default value: no need to write it explicitly
  • top, right, bottom, left and z-index have no effect on static elements
  • Elements appear in the order they are written in the HTML
  • position: static: also used to explicitly reset a positioned element back to normal flow

position: static

Three static elements stacking in normal document flow.

position: relative

A relatively positioned element stays in the normal flow, its original space is preserved. The top, left etc. properties move it relative to where it would have been.

position: relative

relative nudges an element from its natural position without removing it from the flow. Its original space is still reserved, other elements do not move to fill it.

  • The element stays in the flow: its space is preserved
  • top: 20px moves the element 20px down from its natural position
  • Most important use: creates a positioning context for child elements with position: absolute
  • Without relative on a parent, absolute children escape to the nearest positioned ancestor

position: relative

The shifted box moves but its original space is preserved.

position: absolute

An absolutely positioned element is removed from the normal flow. Other elements ignore it and fill the space it left. It is placed relative to its nearest ancestor that has a position other than static.

position: absolute

absolute pulls the element out of the flow and positions it inside the nearest positioned ancestor. If no ancestor is positioned, it uses the initial containing block (the viewport).

  • Removed from the flow: other elements act as if it does not exist
  • Positioned relative to the nearest ancestor with position: relative/absolute/fixed/sticky
  • Pattern: set position: relative on the parent, position: absolute on the child
  • top: 0; right: 0 places it in the top-right corner of the parent

position: absolute

A badge anchored to the top-right corner of its parent.

position: fixed

A fixed element is removed from the flow and positioned relative to the viewport. It stays in the same place on screen even as the user scrolls, perfect for navigation bars and floating buttons.

position: fixed

fixed elements are anchored to the viewport and never move when the page scrolls. They always stay visible regardless of scroll position.

  • Removed from the flow: does not affect surrounding elements
  • Positioned relative to the viewport (the browser window), not any parent
  • Common uses: sticky navigation bar, floating chat button, cookie banner
  • Tip: add margin or padding to the page body so fixed headers do not overlap content

position: fixed

A fixed bar that stays at the top of the viewport while content scrolls.

position: sticky

A sticky element behaves like relative until the page is scrolled to a defined threshold, then it acts like fixed, sticking in place until its parent scrolls out of view.

position: sticky

sticky is relative until the scroll threshold is reached, then sticks. It requires a top, bottom, left, or right value to define the sticking point.

  • top: 0: sticks to the top of the viewport when scrolled to that point
  • Stays in the flow, unlike fixed, it does not overlap content below its parent
  • The element stops sticking when its parent container scrolls out of view
  • Common uses: sticky table headers, section navigation labels
  • Does not work if any ancestor has overflow: hidden or overflow: auto

position: sticky

The section header sticks to the top as you scroll inside the section.

top, right, bottom, left Properties

These four properties move a positioned element from each edge. They only work when position is set to anything other than static.

top / right / bottom / left

These offset properties move the element from each respective edge. For absolute and fixed, they set the distance from the parent or viewport edge.

  • top: 20px: moves element 20px from the top edge of its containing block
  • right: 0: flush with the right edge
  • left: 50%: moves element so its left edge is at the center
  • Setting opposite sides (top and bottom or left and right) stretches an absolute element to fill the space
  • inset: 0: shorthand for top: 0; right: 0; bottom: 0; left: 0 (fills the parent)

Offset Properties

Four elements anchored to each corner of the parent.

z-index and Stacking Context

When positioned elements overlap, z-index controls which one appears on top. A higher z-index means closer to the viewer.

z-index

z-index only works on positioned elements (not static). A stacking context is an isolated layer: z-index values inside it are compared only against siblings in the same context.

  • z-index: 1: above elements with lower or auto z-index
  • z-index: -1: behind the normal flow
  • z-index only works when position is not static
  • Stacking context: created by position + z-index, opacity < 1, transform, filter, etc.
  • z-index inside a stacking context is scoped: it cannot escape its parent context

z-index

Higher z-index appears in front regardless of DOM order.

Floating (Legacy): float and clear

float was the original CSS technique for multi-column layouts. It removes an element from the normal flow and pushes it to the left or right so other content wraps around it.

float and clear

float was designed for text wrapping around images, like magazine layouts. It was repurposed for page layouts before flexbox and grid existed.

  • float: left: element floats to the left; content wraps on the right
  • float: right: element floats to the right; content wraps on the left
  • clear: both: element moves below all floated elements above it
  • clearfix: a technique to prevent a parent from collapsing when all children are floated

float

Text wraps around a left-floated image.

Why float is Outdated for Layouts

Float was never designed for page layouts, it was designed for text wrapping around images. Using it for columns required complex hacks like clearfix. Flexbox and Grid solve layout problems cleanly and should be used instead.

Use Flexbox or Grid Instead

Float layouts require clearfix hacks, collapse parent containers, and are fragile. Flexbox and Grid were built specifically for layout and handle alignment, spacing, and responsiveness with ease.

  • float collapses the parent container height: requires clearfix workarounds
  • Equal-height columns are impossible with float without hacks
  • Flexbox: one-dimensional layout, rows or columns
  • Grid: two-dimensional layout, rows and columns simultaneously
  • Only use float today: for wrapping text around an image (its original purpose)

Flexbox Instead of Float

Three equal columns using flexbox, no clearfix needed.

Knowledge Check

1. Which position value removes an element from the normal document flow?

2. An element with position: absolute is placed relative to:

3. Which position value keeps an element fixed to the viewport as the user scrolls?

4. What does position: sticky require to work?

5. What is a stacking context?