Skip to content
Topic 12 of 15
Theory

Display and positioning

Why you need this

So far elements have gone one after another from top to bottom — this is the document's normal flow. But on real sites the menu stands in a line, a «−20%» badge hangs in the corner of a card, the chat button doesn't move when you scroll, and the sign-in window appears on top of the page. All of this is done with the display and position properties.

display: how an element enters the flow

.a { display: block; }
.b { display: inline; }
.c { display: inline-block; }
.d { display: none; }
Value How it behaves Default for
block on a new line, full width; width, height, margin work div, p, h1, ul, li
inline inside a line, like a word; width and height don't work span, a, strong, img
inline-block in a line like a word, but sizes and spacing work button, input
none the element is gone: not visible and takes no space head, script
<style>
  a { display: inline-block; padding: 10px 20px; background: gold; }
</style>
<a href="#">Buy</a> <a href="#">Add to cart</a>

Result: two yellow buttons side by side. With plain inline, the top and bottom padding would overlap the neighbouring lines.

display: none is used to hide elements (the menu on a phone, a window until a button is pressed). visibility: hidden hides an element but keeps empty space for it.

position: where an element stands

Value Measured from Leaves the flow?
static the normal position (the default) no
relative its own normal place no, the space stays
absolute the nearest ancestor whose position isn't static yes
fixed the browser window; doesn't move when scrolling yes
sticky normal, but "sticks" while scrolling no

The position is set with top, right, bottom, left — the distance from the matching edge.

relative

.shift { position: relative; top: 10px; left: 20px; }

Result: the element is shifted 10px down and 20px right, and a "hole" stays in its old place. On its own relative is rarely needed — it's usually set on a parent so that absolute works inside.

absolute

<style>
  .photo { position: relative; width: 200px; height: 150px; background: #ddd; }
  .sale { position: absolute; top: 0; left: 0; background: red; color: white; }
</style>
<div class="photo">
  <span class="sale">−20%</span>
</div>

Result: a red «−20%» badge in the top left corner of the grey block.

Important: absolute looks for the nearest ancestor with position: relative (or absolute, fixed, sticky). If there is none, it's measured from the whole page, and the badge flies off to a corner of the screen.

fixed

.up { position: fixed; right: 20px; bottom: 20px; }

Result: the button is always in the bottom right corner of the window, whatever the user scrolls. This is how «Back to top» buttons, support chats and cookie banners are made.

sticky

.header { position: sticky; top: 0; background: white; }

Result: the header moves with the page, but when it reaches the top of the window it "sticks" and stays there. Without top, sticky doesn't work: the browser needs to know where to stick.

z-index: who is on top

When elements overlap, the one with the larger z-index is on top (it works only on positioned elements — not static):

.modal { position: fixed; z-index: 100; }
.chat { position: fixed; z-index: 10; }

Result: the window covers the chat button. Picture a stack of sheets: z-index is the number of the sheet from the top.

How it works inside

The browser first lays out all normal-flow elements from top to bottom. It "takes out" absolute and fixed elements from the flow — the neighbours don't see them and move into the freed space. Then the taken-out elements are drawn at their own coordinates on top of the rest, in z-index order.

Common mistakes

  1. width on inline. Sizes don't work on <span> and <a> — you need inline-block or block.
  2. Forgot relative on the parent. The absolute badge flies to a corner of the page.
  3. z-index "doesn't work". The element has position: static — z-index has no effect. Add position: relative.
  4. sticky without top. Nothing sticks.
  5. A whole layout built on absolute. On another screen size everything overlaps. Use Flexbox and Grid (the next topics) for layout, and absolute for small things like badges.

Cheat sheet

Code What it does
display: block / inline / inline-block how it enters the flow
display: none remove the element completely
visibility: hidden hide it, keeping the space
position: relative a shift from its own place; an "anchor" for absolute
position: absolute from the nearest positioned ancestor
position: fixed from the window, doesn't move when scrolling
position: sticky; top: 0 sticks while scrolling
top / right / bottom / left coordinates
z-index who is on top

A menu in one line

Easy+10 XP

List items li go one under another by default. Put them in one line: give li the value display: inline-block, and remove the bullets from the ul list itself (list-style: none).

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.