Topic 4: DIV Positioning
📖 5 min read · 🎯 intermediate · 🧭 Prerequisites: iframe-embed-albums-embed-video-embed-maps-input-tag-introduction, javascript-objects
Why this matters
Up until now, every element you've placed on a page has just stacked — one after another, top to bottom, like paragraphs in a Word document. That works fine for simple pages. But the moment you want a navigation bar that stays at the top when you scroll, or a tooltip that appears right next to a button, or a modal that floats over everything else — the default stacking breaks. That's where CSS positioning comes in. It gives you five distinct modes to control exactly where a DIV lives on screen, whether it moves with the scroll or stays fixed, and whether it respects the flow of other elements or steps outside it entirely.
What You'll Learn
- How CSS
position: staticestablishes the default document flow - How
relative,absolute,fixed, andstickypositioning each differ and when to use them - How to combine sticky and absolute positioning to build a real sticky header with a side panel
- How
top,left,bottom, andrightoffset properties interact with each positioning mode
The Analogy
Think of your webpage as an art gallery. In a standard gallery (static flow), every painting hangs on the wall in the order it was delivered — no exceptions, no surprises. Relative positioning is like nudging one painting a few centimetres to the right without disturbing any other frame. Absolute positioning is like floating a spotlight fixture at a precise spot on the ceiling, independent of the paintings below. Fixed positioning is a security camera bolted to the wall: no matter how many visitors walk through and shuffle things around, the camera never moves. Sticky positioning is a docent who walks alongside you but freezes in place the moment they reach the information desk — relative until they hit that threshold, then immovable.
Chapter 1: Static Positioning
Static is the default for every HTML element. Elements render in the order they appear in the document — top to bottom, left to right — and the top, left, bottom, and right properties have no effect.
<div>Standard static positioning — I flow naturally with the document.</div>
There is nothing to configure. If you have not written a position rule, the element is static.
Chapter 2: Relative Positioning
Relative positioning shifts an element from its own normal position without affecting any surrounding elements. The space the element would have occupied is preserved — neighbours do not collapse to fill it.
Use it for fine-tuning a layout, layering decorative accents, or establishing a positioned ancestor for absolutely-positioned children.
<div style="position: relative; left: 20px; top: 10px;">
Nudged 20px right and 10px down from where I would normally sit.
</div>
Key behaviour: offsets are relative to the element's original slot, not the viewport or any parent.
Chapter 3: Absolute Positioning
Absolute positioning removes the element from normal flow entirely. Surrounding elements act as if it does not exist. The element is then placed relative to its nearest positioned ancestor (any ancestor with position set to anything other than static). If no such ancestor exists, it positions relative to the initial containing block (the viewport).
Use it for tooltips, dropdowns, overlays, badges, and decorative shapes layered over a container.
<div style="position: absolute; left: 50px; top: 30px;">
Placed absolutely within its nearest positioned ancestor.
</div>
Tip: Always set
position: relativeon the parent container you want to serve as the anchor — otherwise your absolutely-positioned child will escape all the way up to the viewport.
Chapter 4: Fixed Positioning
Fixed positioning pins the element relative to the viewport. It does not scroll with the page — ever. Use it for persistent navigation bars, floating action buttons, cookie banners, and chat widgets.
<div style="position: fixed; bottom: 0; right: 0;">
I stay at the bottom-right corner, always visible regardless of scroll.
</div>
Because a fixed element is removed from normal flow, the content behind it can be obscured — leave enough margin or padding on the surrounding content to compensate.
Chapter 5: Sticky Positioning
Sticky is a hybrid. An element behaves like relative until the user scrolls to a defined threshold, at which point it "sticks" and behaves like fixed — but only within its parent container's bounds. Once the parent scrolls out of view, the sticky element goes with it.
Use it for section headers in long lists, table column headers, and nav bars that should stay visible while content scrolls.
<div style="position: sticky; top: 0;">
I stick to the top of the viewport when you scroll past my original position.
</div>
Required: you must specify at least one offset (top, left, bottom, or right) for sticky to activate.
Chapter 6: Putting It Together — Sticky Header with Side Panel
Now the class builds. The goal: a page with a sticky header that stays visible on scroll and an absolutely-positioned side panel that sits beside the main content.
Step 1 — HTML structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Positioning Practice</title>
<style>
/* CSS styles added in Step 2 */
</style>
</head>
<body>
<header id="header">I'm a sticky header.</header>
<div id="sidePanel">I'm a side panel, positioned absolutely.</div>
<main id="content">
<p>Here's a lot of content so you can scroll and see the positioning
in action. Add several paragraphs here to ensure the page scrolls.</p>
</main>
</body>
</html>
Step 2 — CSS positioning rules
Replace the empty <style> block with:
body, html {
height: 100%;
margin: 0;
}
#header {
background: #333;
color: white;
padding: 10px;
position: sticky;
top: 0;
width: 100%;
}
#sidePanel {
position: absolute;
top: 50px; /* offset to avoid overlapping the header */
left: 0;
width: 200px;
background: #ccc;
height: 300px; /* adjust based on content */
padding: 15px;
}
#content {
margin-left: 220px; /* clear space for the 200px panel + padding */
padding: 20px;
}
Step 3 — Test
Open the file in a browser. Scroll the page:
- The
#headershould remain pinned to the top of the viewport (position: sticky; top: 0). - The
#sidePanelshould stay at its absolute position in the document (position: absolute; top: 50px; left: 0). - The
#contentshould start 220px from the left, giving the panel room to breathe.
flowchart TD
V[Viewport] --> H[#header — sticky, top: 0]
V --> Body[Document body]
Body --> SP[#sidePanel — absolute, top: 50px, left: 0]
Body --> C[#content — margin-left: 220px]
Experiment with different values — change top: 50px on the side panel, reduce margin-left on #content, or add position: fixed to #header to see how each tweak changes the layout.
🧪 Try It Yourself
Task: Extend the layout above by adding a floating "Back to Top" button that stays pinned to the bottom-right corner of the viewport at all times.
Success criterion: Scroll down the page — the button should remain visible in the bottom-right corner and clicking it should jump the page back to the top.
Starter snippet (add inside <body> and the <style> block):
<a href="#header" id="backToTop">↑ Top</a>
#backToTop {
position: fixed;
bottom: 20px;
right: 20px;
background: #333;
color: white;
padding: 10px 15px;
text-decoration: none;
border-radius: 4px;
}
You should see the button floating in the bottom-right corner while everything else scrolls normally.
🔍 Checkpoint Quiz
Q1. What is the key difference between position: fixed and position: sticky?
A) Fixed stays within its parent container; sticky is always relative to the viewport
B) Sticky stays within its parent container and only "fixes" after a scroll threshold; fixed is always relative to the viewport
C) They behave identically — the names are just aliases
D) Fixed requires a positioned ancestor; sticky does not
Q2. Given this CSS, what happens to the space that .badge originally occupied in the document flow?
.badge {
position: absolute;
top: 0;
right: 0;
}
A) The space is preserved; surrounding elements do not move
B) The space collapses; surrounding elements fill the gap
C) The element is hidden but the space remains
D) The element moves 0px from its original position
Q3. A developer sets position: relative; left: 20px on a paragraph. Which element moves?
A) All siblings shift 20px to the right to make room
B) Only the paragraph shifts 20px right; its original space is preserved and no other element moves
C) The paragraph's parent shifts 20px right
D) Nothing moves because left only works with absolute and fixed
Q4. You are building a data table where column headers should remain visible as users scroll down through hundreds of rows. Which positioning value is the most appropriate for the <thead> row?
A) position: fixed — it locks to the viewport
B) position: absolute — it removes the header from flow
C) position: sticky — it scrolls with content until it hits the threshold, then stays put
D) position: relative — it nudges the header to the correct spot
A1. B — Sticky respects its parent container's bounds and only activates after the scroll threshold is crossed; fixed is always anchored to the viewport regardless of parent or scroll position.
A2. B — position: absolute removes the element from normal flow entirely, so the space it would have occupied collapses and surrounding elements reflow as if it were not there.
A3. B — position: relative shifts only the target element from its own original slot. Siblings are unaware of the shift and do not move; the gap the element left behind remains visible.
A4. C — position: sticky is purpose-built for this pattern. The header scrolls naturally until it reaches top: 0, then pins in place for the remainder of the table, returning to normal flow when the table leaves the viewport.
🪞 Recap
position: staticis the default — elements flow in document order with no offset support.position: relativenudges an element from its own slot without disturbing neighbours; it also establishes a positioning context for absolute children.position: absoluteremoves an element from normal flow and anchors it to its nearest positioned ancestor (or the viewport if none exists).position: fixedpins an element to the viewport permanently — useful for navbars, FABs, and banners that must always be visible.position: stickycombines relative and fixed behaviour, sticking to a threshold only within the bounds of its parent container.
📚 Further Reading
- MDN: CSS position property — the source of truth for every positioning mode with live examples
- CSS Tricks: position — visual diagrams comparing all five values side by side
- MDN: Understanding CSS z-index — essential next step once you start layering positioned elements
- ⬅️ Previous: JavaScript Objects
- ➡️ Next: Form Buttons