Topic 4: DIV Positioning
📖 12 min read · 🎯 beginner · 🧭 Prerequisites: javascript-objects, php-with-select-fetch
Why this matters
Picture this: you've built a navbar, a sidebar, and a main content area — but they all stack on top of each other in one long column. Frustrating, right? That's every beginner's wall. CSS position is what breaks you out of that column. It lets you pin an element to the top of the screen so it never scrolls away, layer one element over another, or nudge something just a few pixels off its natural spot. Once you understand position, you stop fighting the browser and start telling it exactly where things go.
What You'll Learn
- The five CSS
positionvalues and when to use each one - How
top,right,bottom, andleftoffsets interact with each positioning mode - The difference between viewport-relative (fixed) and ancestor-relative (absolute) placement
- How to build a sticky header with an absolutely positioned side panel from scratch
The Analogy
Think of your webpage as a theater stage. By default, actors walk on from stage left and stand in line — that is static flow. relative lets an actor shuffle a few steps from their marked spot without bumping anyone else. absolute yanks an actor off the main stage and pins them to an exact spot on the set, relative to the nearest piece of scenery that has its own mark. fixed glues an actor to the audience's field of view — they move with the camera, never off-screen, no matter how far the scene scrolls. sticky is the understudying trick: the actor follows normal blocking until they hit the edge of the frame, then they freeze and stay visible until the scene catches up.
Chapter 1: Static Positioning
static is the browser's factory default. Every element that has no explicit position property set is static. Elements render in the order they appear in the HTML — top to bottom, left to right — and the top, right, bottom, and left offset properties do nothing.
<div>Standard static positioning — I just flow with the document.</div>
You rarely write position: static explicitly; it exists mainly so you can reset a positioned element back to normal flow.
Chapter 2: Relative Positioning
relative keeps the element in the normal document flow, but lets you nudge it away from where it would naturally land. Crucially, the space the element would have occupied is still reserved — surrounding elements do not collapse to fill it.
<div style="position: relative; left: 20px; top: 10px;">
Nudged 20px right and 10px down from my natural position.
</div>
Use relative when you need fine-grained micro-adjustments or when you want to establish a positioning context for an absolute child (more on that next).
Key properties used with relative:
| Property | Effect |
|---|---|
top | Moves element down from its natural top edge |
left | Moves element right from its natural left edge |
bottom | Moves element up from its natural bottom edge |
right | Moves element left from its natural right edge |
Chapter 3: Absolute Positioning
absolute pulls the element entirely out of normal flow. No space is reserved. The element is placed relative to its nearest positioned ancestor — any ancestor that has position set to anything other than static. If no such ancestor exists, the element positions itself relative to the initial containing block (effectively the <html> element).
<div style="position: absolute; left: 50px; top: 30px;">
Placed absolutely within its nearest positioned parent.
</div>
This mode is ideal for:
- Dropdown menus that float over content
- Tooltips and popovers
- Overlay badges on images
- Side panels anchored inside a wrapper
A common pattern: set position: relative on a parent container, then use position: absolute on the child. The child will now position itself relative to that parent rather than the whole page.
Chapter 4: Fixed Positioning
fixed positions an element relative to the browser viewport. It stays in exactly the same visual spot even as the user scrolls — the rest of the page moves underneath it.
<div style="position: fixed; bottom: 0; right: 0;">
I stay at the bottom right, always visible.
</div>
Common use cases:
- Sticky navigation bars
- Cookie consent banners
- Floating action buttons (FABs)
- Chat widgets
Fixed elements are removed from the normal document flow, so you typically need to add margin or padding to the main content to prevent it from being hidden underneath.
Chapter 5: Sticky Positioning
sticky is a hybrid. An element behaves as relative until the user scrolls it to a defined threshold, at which point it "sticks" and behaves like fixed — remaining visible — until its parent scrolls entirely off screen.
<div style="position: sticky; top: 0;">
I stick to the top when you scroll past me.
</div>
sticky requires at least one threshold offset (top, bottom, left, or right) to be set. Without it, the element simply behaves as relative and never sticks.
Common use cases:
- Section headers in a long document
- Table headers that stay visible when scrolling rows
- Navigation that starts below a hero banner but then sticks
flowchart TD
A[position: static] -->|nudge from natural spot| B[position: relative]
B -->|establish context for children| C[position: absolute]
A -->|viewport-locked| D[position: fixed]
A -->|relative until scroll threshold| E[position: sticky]
C -->|"nearest positioned ancestor (not static)"| F[Ancestor with position ≠ static]
D -->|"always relative to"| G[Browser Viewport]
E -->|"sticks when offset threshold is crossed"| H[Scroll Position]
Chapter 6: Putting It Together — Sticky Header with Side Panel
The following task combines sticky and absolute in one realistic page layout.
HTML structure:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Positioning Practice</title>
<style>
/* CSS styles added in Step 1 */
</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 1 — Add CSS to style and position the elements:
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 not overlap the header */
left: 0;
width: 200px;
background: #ccc;
height: 300px; /* Adjust based on content */
padding: 15px;
}
#content {
margin-left: 220px; /* Make space for the side panel */
padding: 20px;
}
Step 2 — Test your layout:
Open the HTML file in a browser. Scroll the page and verify:
- The
#headerremains pinned to the top of the viewport while everything else scrolls beneath it (position: sticky; top: 0). - The
#sidePanelappears 50 px below the top of the page, avoiding overlap with the header (position: absolute; top: 50px). - The
#contentarea is pushed 220 px from the left so text does not flow under the side panel (margin-left: 220px).
🧪 Try It Yourself
Task: Extend the sticky-header-and-side-panel page with a "back to top" button that is always visible in the bottom-right corner.
Success criterion: After scrolling down past 300 px of content, the button stays anchored at bottom: 20px; right: 20px — it never scrolls off screen.
Starter snippet (add inside <body> and expand the <style> block):
<button id="backToTop">↑ Top</button>
#backToTop {
position: fixed;
bottom: 20px;
right: 20px;
background: #333;
color: white;
border: none;
padding: 10px 16px;
cursor: pointer;
border-radius: 4px;
}
Add a <p> tag repeated 20 times inside #content so the page is actually scrollable, then open in your browser and scroll. The button should stay glued to the bottom-right corner.
🔍 Checkpoint Quiz
Q1. Which CSS position value removes an element from the normal document flow and positions it relative to the browser viewport (not any ancestor)?
A) relative
B) absolute
C) fixed
D) sticky
Q2. Given this snippet, where will the <div> appear on screen?
<div style="position: relative; left: 20px; top: 10px;">Hello</div>
A) Exactly 20 px from the left edge and 10 px from the top edge of the page
B) 20 px to the right and 10 px below where it would normally sit, with its original space still reserved
C) 20 px to the right and 10 px below its normal spot, and the surrounding elements collapse into the gap
D) No change — relative ignores left and top
Q3. In the sticky-header task, #content uses margin-left: 220px. What problem does this solve?
A) It prevents the content from scrolling behind the header B) It stops the side panel from overlapping the main text area C) It centres the content on wide screens D) It creates a gap below the sticky header
Q4. You want a section heading to scroll normally at first, but then freeze at the top of the screen once the user scrolls past it — staying visible until the parent section leaves the viewport. Which position value should you use?
A) fixed
B) absolute
C) sticky
D) relative
A1. C — fixed places an element relative to the viewport and it stays there regardless of scrolling. absolute is relative to the nearest positioned ancestor, not the viewport.
A2. B — relative keeps the element's reserved space in flow and simply shifts the rendered box by the specified offsets. Surrounding elements do not move to fill the original spot.
A3. B — the #sidePanel is 200 px wide with 15 px padding (215 px total), and margin-left: 220px on #content ensures text starts after the panel rather than rendering underneath it.
A4. C — sticky behaves as relative until its offset threshold is crossed, then it behaves like fixed within the bounds of its parent container. fixed would never stop sticking even after the section leaves the viewport.
🪞 Recap
staticis the default: elements stack in document order, offset properties are ignored.relativenudges an element from its natural position while keeping its space reserved in the flow.absoluteremoves an element from flow and pins it to its nearest non-static ancestor (or the page root).fixedlocks an element to the viewport — it never scrolls away, ideal for nav bars and FABs.stickyhybridizes relative and fixed, freezing an element at a scroll threshold until its parent leaves the screen.
📚 Further Reading
- MDN: CSS position property — the source of truth on every
positionvalue with live demos - CSS Tricks: position — practical patterns and browser gotchas for all five modes
- ⬅️ Previous: PHP with Select, Fetch
- ➡️ Next: Form, Buttons