On this page
Position (relative, absolute, fixed, sticky)
CSS Position Property: Relative, Absolute, Fixed and Sticky
Focus keyword: CSS position. The position property lets you take elements out of normal flow or pin them to a spot. It powers badges, tooltips, dropdown menus, sticky headers, modals and overlays. In this lesson you will learn all five values, the offset properties, how the containing block works, and the most common mistakes. All examples are live and editable.
Trending keywords covered in this lesson
position relative vs absolute, position fixed, position sticky header, inset shorthand, containing block, offset properties top right bottom left, sticky not working, overflow and sticky, CSS tooltip, notification badge, overlay, scroll-margin-top, CSS anchor positioning, dvh units, position center.
1. The Five Position Values
- static (default): normal flow. Offsets and z-index do not work.
- relative: stays in flow, and can be nudged with offsets. Its original space is kept.
- absolute: removed from flow and placed relative to its nearest positioned ancestor.
- fixed: removed from flow and placed relative to the viewport. It stays in place while scrolling.
- sticky: behaves like relative until a scroll threshold is reached, then sticks like fixed inside its scroll container.
2. Offset Properties: top, right, bottom, left and inset
Offsets only work on positioned elements (anything except static). The shorthand inset sets all four at once: inset: 0 means top, right, bottom and left are all 0. Logical versions exist too: inset-block and inset-inline, which adapt to writing direction.
3. position: relative
With relative, top: 20px moves the element 20px down from where it would normally be, without affecting neighbours. Its most common job is not to move anything, but to act as the anchor (containing block) for absolute children. That is why you often see position: relative with no offsets.
4. position: absolute
- Takes no space in the normal flow, so siblings move up to fill the gap.
- Positions itself against the nearest ancestor whose position is not static. If there is none, it uses the initial containing block (the page).
- Without width or offsets, it shrinks to fit its content.
- With
inset: 0it stretches to fill its containing block, perfect for overlays and background layers. - Typical uses: badges, close buttons, tooltips, dropdown panels, image captions.
5. position: fixed
Fixed elements are positioned against the viewport, so they do not move on scroll. Use it for top bars, floating action buttons, cookie banners and modals. Notes: a fixed element is removed from flow, so add padding or margin to the page content to avoid overlap. If any ancestor has transform, filter or perspective, fixed positioning is calculated from that ancestor instead of the viewport. On mobile use 100dvh instead of 100vh for full-height layers because browser toolbars change the visible height.
6. position: sticky
Sticky needs a threshold such as top: 0. The element scrolls normally until it reaches that offset, then stays there until its parent ends. Sticky is ideal for table headers, sidebars, section titles and table of contents.
Why sticky is not working
- No
top,bottom,leftorrightvalue is set. - An ancestor has
overflow: hidden,autoorscroll, which becomes the scroll container. (Useoverflow: clipinstead of hidden when you only want clipping.) - The parent is exactly as tall as the sticky element, so there is no room to stick.
- In a flex container, the item stretches to full height. Add
align-self: start.
7. Containing Block Cheat Sheet
- relative: itself (for its offsets)
- absolute: nearest positioned ancestor (padding box)
- fixed: viewport (unless a transformed ancestor exists)
- sticky: nearest scrolling ancestor
8. Anchored Headers and scroll-margin-top
When you have a sticky or fixed header, links to #section may scroll content under it. Fix it with scroll-margin-top on the target, for example section { scroll-margin-top: 80px; }.
9. The New CSS Anchor Positioning
Modern browsers are adding CSS anchor positioning (anchor-name, position-anchor and anchor()) so tooltips and popovers can attach to any element without JavaScript or a relative parent. Check browser support and keep a fallback. The HTML popover attribute and dialog element pair well with it.
10. Accessibility Notes
- Positioned elements can change visual order, but keyboard order follows the HTML. Keep them in sync.
- Do not cover focused elements with sticky or fixed bars.
- Make sure overlays can be closed with the Escape key.
11. Common Mistakes
- Using absolute without a positioned parent, so the element flies to the page corner.
- Forgetting that absolute and fixed elements do not add height to the parent.
- Using top and bottom offsets on static elements.
- Sticky headers that never stick because of an overflow ancestor.
- Positioning entire page layouts with absolute instead of grid or flexbox.
Key Takeaways
Relative keeps flow and creates an anchor, absolute pins to that anchor, fixed pins to the viewport, sticky switches between relative and fixed based on scroll. Use inset for short code and prefer flex and grid for page layout.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Make the SALE badge sit in the top right corner of the card, half outside the edge. Decide which element needs position relative and which needs position absolute.
Press Run to execute.
Show expected output
Card is position relative, badge is position absolute with negative top and right offsetsThis is a self-check — compare your result with the expected output above.
Make the table header stay visible while the list scrolls inside the 200px tall container. Remember to set a top value and a solid background.
Press Run to execute.
Show expected output
th uses position: sticky with top: 0 and a solid backgroundThis is a self-check — compare your result with the expected output above.
Was this page helpful?