CSS Portal

CSS Position Visualizer

CSS position is one of the most fundamental, and most misunderstood properties in web development. It controls how an element is placed in the document, whether it stays in the normal flow of the page, and what it uses as a reference point for its coordinates. Getting it wrong is responsible for an enormous number of layout bugs: overlapping elements, content hidden behind navbars, tooltips stuck in the wrong place, z-index seemingly doing nothing.

This tool gives you a live, interactive playground for every position value. Click through static, relative, absolute, fixed, and sticky, drag the sliders, and see exactly what changes and why. Then go further with the z-index and stacking context sections, covering the gotcha that trips up even experienced developers - and finish with the Layout Debugger, a realistic mini-page where you can deliberately break things to understand what position values actually do in the real world.

☕
Enjoying this site?

Help keep it running with a small coffee donation. Every bit of support is appreciated!

Buy us a coffee

position: static

    Controls

    Preview

    A real mini browser window. Scroll inside it.

    CSS

    ☕
    Enjoying this site?

    Help keep it running with a small coffee donation. Every bit of support is appreciated!

    Buy us a coffee

    About this tool

    What you will learn

    • The difference between every position value and when to use each one
    • Why static ignores top, left, right, bottom and z-index entirely
    • How relative moves an element without disturbing surrounding content
    • How absolute removes an element from flow and anchors it to a parent
    • Why fixed is viewport-relative and immune to scrolling, and the transform that breaks it
    • How sticky combines relative and fixed with a scroll threshold
    • How z-index controls stacking order and when it does nothing at all
    • What a stacking context is and why it breaks z-index in surprising ways

    The stacking context gotcha

    The most common advanced CSS bug is z-index seemingly refusing to work. An element with z-index: 100 sits behind another with z-index: 1. The reason is almost always a stacking context: a parent element somewhere in the tree has a property like opacity, transform, filter, or will-change applied to it, which creates an isolated z-index layer. The child's z-index only competes within that layer, not the rest of the page. The stacking context section demonstrates this interactively, apply each trigger and watch the order flip.

    The layout debugger

    Abstract examples only go so far. The Layout Debugger shows a realistic mini-page - nav bar, sidebar, tooltip, and footer - each with their correct default position value. You can change any element to any value and immediately see the consequences: the sidebar going absolute removes it from flow so the content expands, the tooltip going relative drops into the text and pushes the words around, the nav going static scrolls away with the page. The status strip tells you what is working and what is broken, so you understand not just what happened but why.

    How to use this tool

    • Use the tabs above the preview to switch between position values and concepts
    • Each scene has a description, its own controls and a CSS snippet that updates as you interact
    • The preview is a small, real browser window: scroll it on the fixed, sticky and layout debugger scenes
    • On the static scene, drag the sliders and nothing moves, then switch Box 3 to relative to compare
    • Try the gotcha switches: a transform that breaks fixed, an overflow that breaks sticky, a static box that ignores z-index
    • On stacking context, pick each trigger and watch the z-index order flip
    • On layout debugger, change any dropdown, break things deliberately, then hit Reset

    CSS Position Values at a Glance

    Value In normal flow? Reference point Scrolls with page? z-index works?
    static ✅ Yes N/A ✅ Yes ❌ No
    relative ✅ Yes Its own original position ✅ Yes ✅ Yes
    absolute ❌ No Nearest non-static ancestor ✅ Yes ✅ Yes
    fixed ❌ No Viewport ❌ No ✅ Yes
    sticky ✅ / ❌ Both Nearest scrolling ancestor ✅ / ❌ Both ✅ Yes

    Frequently Asked Questions

    What is the difference between position: absolute and position: relative in CSS?

    position: relative keeps the element in the document flow and offsets it visually from where it would naturally appear - other elements still behave as if it is in its original spot. position: absolute removes the element from the flow entirely, so surrounding elements collapse as if it does not exist. An absolutely positioned element anchors itself to the nearest ancestor with a non-static position value, or the page root if none exists.

    When should I use position: fixed vs position: sticky?

    Use fixed when you want an element - such as a nav bar or chat button - to remain visible at all times regardless of where the user has scrolled. Use sticky when you want an element to scroll normally at first but then lock into place once it reaches a certain point, such as a table header that sticks to the top of the screen as you scroll through a long table. The key difference is that a sticky element is still bound to its parent container and will scroll away when the parent does; a fixed element never moves at all.

    Why is my z-index not working?

    The most common reason is that the element has position: static, which causes z-index to be completely ignored - it only works on elements with a non-static position value. The second most common reason is a stacking context. If a parent element has a property like opacity (anything less than 1), transform, filter, or will-change applied to it, the browser creates an isolated stacking layer for that subtree. Any z-index on children only competes within that layer, not against the rest of the page - so a child with z-index: 100 can still sit behind an outside element with z-index: 1.

    What does position: static mean in CSS?

    position: static is the default value for every HTML element. It means the element is placed according to the normal document flow - top to bottom, left to right - with no special positioning applied. The top, right, bottom, left, and z-index properties have absolutely no effect on a static element.

    What is a stacking context in CSS?

    A stacking context is an isolated layer in which child elements are stacked and painted relative to each other, independent of elements outside that layer. It is created automatically by certain CSS properties, including opacity values below 1, any transform, filter, or perspective value, will-change, isolation: isolate, a positioned element with a z-index other than auto, and position: fixed or sticky. Once a stacking context exists, a child element's z-index only controls its position within that context - it cannot compete with elements at a higher level of the stacking order.

    Can I use position: sticky without a fixed height on the parent?

    Yes. Sticky does not need a fixed height on the parent: the parent only limits how far the element can travel, so it must be taller than the sticky element itself. The common gotcha is overflow. A sticky element sticks inside its nearest scroll container, which is any ancestor with overflow: hidden, auto or scroll. If that ancestor never scrolls itself, the element never sticks and simply scrolls away as if it were relative. Use overflow: clip when you only need clipping, because it does not create a scroll container. And remember that sticky needs a threshold: top, bottom, left or right.

    What happens if an absolutely positioned element has no positioned ancestor?

    It falls back to the initial containing block, which is effectively the top-left corner of the <html> element (the page root). This is a frequent source of confusion when an absolute element appears to jump unexpectedly to a completely different location - it usually means the intended positioned ancestor is missing a position declaration.

    ☕
    Enjoying this site?

    Help keep it running with a small coffee donation. Every bit of support is appreciated!

    Buy us a coffee