Codecraft
Codecraft
CSS Fundamentals

Positioning

7 min read📖 Intermediate
CSS positioning controls where an element sits on the page relative to its normal flow, its parent, or the viewport. The position property accepts five values: static, relative, absolute, fixed, and sticky.

Most elements follow the normal document flow — block elements stack vertically, inline elements sit side by side. Positioning lets you step outside that flow and place elements exactly where you need them.

static (default)

Every element is position: static by default. It follows normal document flow and is not affected by top, right, bottom, or left.

.box {
  position: static; /* default — no need to write this */
}

relative

The element stays in normal flow but can be nudged using offset properties. The space it originally occupied is preserved.

.nudged {
  position: relative;
  top: 10px;    /* move down 10px from its normal position */
  left: 20px;   /* move right 20px */
}

position: relative is also used to create a positioning context for absolutely positioned children.

absolute

The element is removed from normal flow and positioned relative to its nearest ancestor that has a non-static position. If no such ancestor exists, it positions relative to the page.

.card {
  position: relative; /* positioning context */
}

.badge {
  position: absolute;
  top: 12px;
  right: 12px;
}
💡

The most common pattern: set position: relative on a parent and position: absolute on a child to pin the child to a corner or edge of the parent.

fixed

The element is removed from normal flow and positioned relative to the viewport. It stays in place when the page scrolls — ideal for sticky headers, floating buttons, and overlays.

.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: white;
  border-bottom: 1px solid #e5e7eb;
}

sticky

A hybrid of relative and fixed. The element scrolls normally until it hits a threshold, then sticks in place.

.section-header {
  position: sticky;
  top: 0;             /* sticks when it reaches the top of the viewport */
  background: white;
  z-index: 10;
}

z-index

When positioned elements overlap, z-index controls which one appears on top. Higher values sit in front of lower values.

.modal {
  position: fixed;
  z-index: 1000;
}

.overlay {
  position: fixed;
  z-index: 999;
}

.navbar {
  position: sticky;
  z-index: 100;
}

z-index only works on elements with a position other than static.

Centering with absolute positioning

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

This is a classic trick — offset by 50% then pull back by half the element's own size using transform.

Have anything to say about this lesson?

Your feedback helps improve these tutorials. If something was confusing or missing, let us know.

We don't currently reply to feedback — but if we add that feature in the future, we'll reach out to you.