In our last lesson, we took control over the CSS box model, ensuring our elements are sized in a predictable way with box-sizing: border-box. Now that we can confidently define the size of our layout's building blocks, it's time to master their placement.
This lesson dives into the CSS position property, a concept that unlocks a new dimension of control over your layouts. We will explore the five different positioning values: static, relative, absolute, fixed, and sticky. Understanding how each one works is fundamental to creating the polished, multi-layered interfaces you see in modern websites and web apps, from dropdown menus and modal dialogs to fixed navigation bars.
By the end of this session, you'll be able to precisely position elements on a page, taking them out of their default arrangement when needed to build complex and beautiful user interfaces.
The Document Flow and position: static
By default, every element on a web page exists in what's called the "normal document flow." Block-level elements stack vertically, one after another, while inline elements flow horizontally like words in a sentence. This default behavior is governed by position: static.
Because it's the default, you'll rarely write position: static; yourself. The key thing to know is that when an element is static, the positioning properties top, left, bottom, right, and z-index have no effect on it. It simply sits where the document flow places it.
Let's watch a quick explanation from Kevin Powell to solidify this baseline.
This clip provides a concise overview of position: static as the default, non-positioned state.
Watch the segment from the beginning to understand why this value is the default and why properties like top and left don't apply to it.
The image below gives a great visual overview of all the position values we'll be covering. Keep it in mind as we explore each one.

position: relative - A Gentle Nudge
The first step away from the default flow is position: relative. Applying this value to an element makes it a positioned element, which "unlocks" the top, left, bottom, and right properties. You can use these properties to offset the element from its original spot in the normal flow.
The crucial characteristic of position: relative is that even though the element is visually moved, it still reserves its original space in the document flow. Other elements are not affected and won't move to fill the gap.
While you can use relative for minor visual adjustments, its most important role is to serve as a containing block for absolutely positioned child elements, which we'll cover next.
Kevin Powell demonstrates how position: relative works, highlighting that it moves an element while its original space is preserved.
Watch from this section. Pay close attention to how the text moves over other content, but the space it originally occupied remains empty.
position: absolute - Breaking Free
This is where things get really powerful. When you set an element to position: absolute, it is completely removed from the normal document flow. The space it once occupied collapses, and other elements reflow as if the absolute element never existed.
An absolutely positioned element is then placed relative to its nearest positioned ancestor. A "positioned ancestor" is any parent element whose position value is anything other than static (e.g., relative, absolute, fixed, or sticky). If no positioned ancestor is found, the element is positioned relative to the initial containing block, which is typically the <html> element (the viewport).
This leads to a very common and essential pattern in CSS:
- Create a wrapper or container element.
- Give the wrapper
position: relative;. You often don't need to add anytoporleftvalues; its only job is to become a positioned ancestor. - Give the child element you want to place precisely
position: absolute;and usetop,left, etc., to position it within therelativeparent.
Let's see this in action with a practical example.
Learn CSS Positioning Quickly With A Real World Example
This video from Slaying The Dragon provides a clear, real-world example of using position: absolute to place an element and then constraining it within a relative parent.
Watch the initial demonstration of position: absolute from the beginning to see how it's removed from the flow and positioned relative to the page. Next, watch carefully as the video explains how to create a positioned ancestor by adding position: relative to the parent container. This is a core concept.
For a more hands-on experience, the following article by Ahmad Shadeed includes excellent interactive examples.
This interactive article will let you experiment with the relationship between relative and absolute positioning.
First, read the conceptual overviews for absolute positioning. Notice the key phrase: "the containing block is the closest positioned parent". Next, scroll down to the interactive section titled "Relative Position". In the code editor, set the .wood-wrapper to position: relative;. Continue to the next interactive section, "Absolute Position". Set the .fabric to position: absolute; and then experiment with different values for top, left, right, and bottom to see how it moves within the relative wrapper. Try some of the other "Absolute Position" examples as well.
position: fixed - Glued to the Screen
Like absolute, position: fixed removes an element from the document flow. The key difference is that a fixed element is always positioned relative to the viewport (the browser window). It does not care about any relative parents.
This means that a fixed element will stay in the same place on the screen even when the user scrolls the page. This is perfect for creating elements like navigation headers that are always visible, cookie banners, or "scroll to top" buttons.
Learn CSS Positioning Quickly With A Real World Example
This part of the Slaying The Dragon video clearly shows the behavior of position: fixed and demonstrates its most common use case: creating a fixed header.
Watch the segment on fixed positioning. Notice how it's removed from the flow (like absolute) but stays locked to the viewport on scroll.
position: sticky - The Modern Solution
position: sticky is a hybrid of relative and fixed. An element with position: sticky is treated as relative until it reaches a specified threshold during scrolling. Once it hits that point (e.g., top: 0;), it "sticks" and behaves like a fixed element.
However, unlike a truly fixed element, a sticky element is confined to its parent container. It will stick to the top of the viewport only as long as its parent container is visible on the screen.
This makes sticky the ideal modern choice for creating headers. The header can start in the normal document flow, and as you scroll past it, it sticks to the top of the viewport without the layout-breaking side effects of position: fixed.
Kevin Powell provides an excellent deep dive into sticky, including how to solve a common problem when using it inside a Flexbox or Grid layout.
This comprehensive section explains the power of position: sticky for modern UIs and covers an important "gotcha" you might encounter.
Watch the segment from this point. First, see how sticky is used to create a header that sticks on scroll. Then, pay close attention to the sidebar example. You'll see that position: sticky doesn't work initially because the element is a flex item that is being stretched. The solution (align-self: start;) is a crucial piece of practical knowledge.
Conclusion
You've now explored one of the most powerful tools in the CSS layout toolkit. By moving beyond the static document flow, you can create dynamic, layered, and user-friendly interfaces. Mastering the nuances between these values is a huge step toward building professional-grade digital products.
Here are the key takeaways:
static: The default. The element is in the normal document flow.top/lefthave no effect.relative: A "positioned" element. Can be offset withtop/left, but its original space is reserved. Its main use is to be a containing block forabsolutechildren.absolute: Removed from the document flow entirely. Positioned relative to the nearest positioned ancestor.fixed: Removed from the document flow. Positioned relative to the viewport and does not move on scroll.sticky: A hybrid. Acts likerelativeuntil a scroll threshold is met, then behaves likefixedwithin the bounds of its parent container.
In this lesson, we briefly mentioned that applying a position value (other than static) activates the z-index property. In our next lesson, we will focus entirely on z-index and the concept of "stacking contexts," learning how to precisely control which elements appear in front of others.