CSS · Lesson 5

Positioning

Placing things on the page

So far, every element has taken its turn from top to bottom. Now let's put things side by side, pin them to corners and stack them on top of each other.

What you'll learn

  • How display decides if an element sits on its own line, inside a line, or is hidden.
  • How to move elements and pin them to a spot with position, and which one is in front with z-index.
  • What to do with content that does not fit, and how to wrap text around a picture.

Let's move things around

The browser places elements one after another, from top to bottom, in the same order as the HTML. This is called the normal flow. The properties in this lesson change that: they put elements in a row, move them, pin them to a spot, or put one on top of another.

Think of a school bulletin board. Most notes are pinned in order, one after another (static). Someone bumps one note a little, and its empty spot is still there (relative). An urgent notice is pinned to an exact corner of the board (absolute). When two notes overlap, the one pinned last is on top, unless you choose otherwise (z-index).

The dashed outline shows the spot the "Lost" note came from. With relative, that space stays empty. With absolute, the "Urgent" note leaves no empty space behind.

A closer look

display: block, inline, inline-block and none

Every element has a display value. Block elements, like <div>, <p>, <h1> and <li>, start on a new line and take the full width. Inline elements, like <a> and <span>, sit inside a line of text, and they skip width and height. inline-block mixes the two: the element sits in a row, but width, height and padding all work. none hides the element completely. CSS Lessons 7 and 9 add two more values, flex and grid.

position and its four helpers

position decides how an element is placed. static is the default: the element stays in the normal flow. The other values use four helpers, top, right, bottom and left, to say where it goes:

  • relative moves the element from its usual spot. The space it came from stays empty.
  • absolute takes the element out of the flow and places it inside the nearest parent that has a position, usually one with position: relative.
  • fixed places the element on the screen itself, so it stays put while you scroll, like a chat button.

z-index: who is in front

When positioned elements overlap, the one that comes later in the HTML is drawn on top. z-index changes that: a higher number sits in front of a lower one. It works on elements that have a position other than static.

overflow: content that doesn't fit

When a box has a set height and its content needs more room, overflow decides what happens: visible lets it spill out (the default), hidden cuts it off, and auto adds a scroll bar only when needed.

float: wrapping text around a picture

float: left; pushes an element to the left side of its box, and the text that comes after it wraps around its right side, like a photo in a newspaper story. Floats were once used to build whole page layouts. Today, flexbox and grid (CSS Lessons 7 to 10) do that job, and float is mostly used for pictures in text.

Let's build it

Let's arrange a Front Page Bytes page with a menu and a story. The starting CSS uses only what you learned in CSS Lessons 1 to 4. Each code box opens on the CSS tab with the new lines highlighted. Click HTML to see the page being styled.

Step 1: Put the menu in a row

Your code
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.menu {  background-color: #11141A;  padding: 8px;}.menu li {  color: white;  padding: 4px 8px;  display: inline-block;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;}.badge {  background-color: #FF4B4B;  color: white;  padding: 2px 8px;}.photo {  width: 80px;}
What you see

List items are block elements, so each one starts on a new line. display: inline-block; lets them sit side by side, while their padding still works. Scroll the HTML tab to see the list.

Step 2: Wrap the story around the picture

Your code
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.menu {  background-color: #11141A;  padding: 8px;}.menu li {  color: white;  padding: 4px 8px;  display: inline-block;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;}.badge {  background-color: #FF4B4B;  color: white;  padding: 2px 8px;}.photo {  width: 80px;  float: left;  margin-right: 12px;}
What you see

float: left; moves the photo to the left side of the story, and the headline and text wrap around it. margin-right keeps the text from touching the photo.

Step 3: Pin the badge to the corner

Your code
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.menu {  background-color: #11141A;  padding: 8px;}.menu li {  color: white;  padding: 4px 8px;  display: inline-block;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;  position: relative;}.badge {  background-color: #FF4B4B;  color: white;  padding: 2px 8px;  position: absolute;  top: 8px;  right: 8px;}.photo {  width: 80px;  float: left;  margin-right: 12px;}
What you see

position: absolute; lifts the "NEW" badge out of the flow and places it 8 pixels from the top and 8 pixels from the right.

Measured from where? From the nearest parent with a position. That's why .story gets position: relative;: it becomes the frame the badge is pinned to.

Step 4: Keep a long story in a small box

Your code
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.menu {  background-color: #11141A;  padding: 8px;}.menu li {  color: white;  padding: 4px 8px;  display: inline-block;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;  position: relative;  max-height: 130px;  overflow: auto;}.badge {  background-color: #FF4B4B;  color: white;  padding: 2px 8px;  position: absolute;  top: 8px;  right: 8px;}.photo {  width: 80px;  float: left;  margin-right: 12px;}
What you see

max-height: 130px; limits how tall the story can get, and overflow: auto; adds a scroll bar for the rest. Scroll inside the story in the mini browser to read it all.

Quick notes

display How an element sits
.menu li { display: inline-block; }

How to use

  • block Starts on a new line and takes the full width. Like <div>, <p> and <h1>.
  • inline Sits inside a line of text. Width and height are skipped. Like <a> and <span>.
  • inline-block Sits in a line, but width, height and padding all work.
  • none Hides the element. It takes up no space at all.

Examples

  1. A menu with its items in one row.

    .menu li {  display: inline-block;}
  2. A link that fills its whole line, so it is easy to tap.

    .menu a {  display: block;}
  3. Hide an old notice.

    .old {  display: none;}
position Move or pin an element
.badge { position: absolute; top: 8px; right: 8px; }

How to use

  • static The usual spot in the page. This is the default.
  • relative Moves from its usual spot. Its old space stays empty.
  • absolute Placed inside the nearest parent that has a position. Other elements act as if it isn't there.
  • fixed Stays in the same spot on the screen, even when you scroll.
  • top / right / bottom / left How far to move it. They work only with relative, absolute or fixed.

Examples

  1. A badge pinned to the corner of a card.

    .card {  position: relative;}.badge {  position: absolute;  top: 8px;  right: 8px;}
  2. Nudge an icon 2 pixels down.

    .icon {  position: relative;  top: 2px;}
  3. A chat button that stays in the corner of the screen.

    .chat-button {  position: fixed;  bottom: 16px;  right: 16px;}
z-index Which one is in front
.badge { z-index: 2; }

How to use

  • 1, 2, 10 … A higher number sits in front of a lower one.
  • -1 Goes behind the others.
  • Works only on elements that have a position like relative or absolute.

Examples

  1. A pop-up box in front of the page.

    .popup {  position: fixed;  z-index: 10;}
  2. A badge in front of a photo.

    .badge {  position: absolute;  z-index: 2;}
overflow When content doesn't fit
.story { overflow: auto; }

How to use

  • visible Extra content spills out of the box. This is the default.
  • hidden Extra content is cut off.
  • auto A scroll bar appears only when the content doesn't fit.
  • scroll A scroll bar is always there.

Examples

  1. A long story inside a small box, with a scroll bar.

    .story {  max-height: 200px;  overflow: auto;}
  2. Crop a big picture so it stays inside its frame.

    .frame {  height: 150px;  overflow: hidden;}
float Wrap text around it
.photo { float: left; }

How to use

  • left The element moves to the left, and text wraps around its right side.
  • right The element moves to the right, and text wraps around its left side.
  • none No float. This is the default.

Examples

  1. A photo with the story text wrapping around it.

    .photo {  float: left;  margin-right: 12px;}
  2. A small note box on the right side of a story.

    .side-note {  float: right;  width: 150px;}

Common mistakes

These are mistakes many beginners make. Each mini browser shows what really happens.

Absolute with no positioned parent

The mistake
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;}.badge {  background-color: #FF4B4B;  color: white;  padding: 2px 8px;  position: absolute;  top: 8px;  right: 8px;}.photo {  width: 80px;  float: left;  margin-right: 12px;}
What you see

.story has no position, so the badge looks further up for a positioned parent and finds none. It ends up pinned to the corner of the whole page, far from its story.

Tip: Add position: relative; to the box the badge belongs in, here .story.

z-index on an element with no position

The mistake
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;  position: relative;}.badge {  background-color: #FF4B4B;  color: white;  padding: 2px 8px;  position: absolute;  top: 8px;  left: 8px;}.photo {  width: 80px;  float: left;  margin-right: 12px;  z-index: 5;}
What you see

The plan was to bring the photo in front of the badge. But the photo has no position, so z-index: 5; does nothing, and the badge still covers its corner.

Tip: Give the photo a position too: position: relative; z-index: 5;

Cutting off content with overflow: hidden

The mistake
body {  background-color: #F0F7FF;  font-family: Arial, Helvetica, sans-serif;}.story {  background-color: white;  border: 3px solid #11141A;  padding: 16px;  height: 90px;  overflow: hidden;}.photo {  width: 80px;  float: left;  margin-right: 12px;}
What you see

The story is only 90 pixels tall, and overflow: hidden; cuts off everything below that. Most of the story disappears, with no way to read it.

Tip: Use overflow: auto; so readers can scroll, or leave the height out.

Test your knowledge

Edit the CSS on the left. Open the HTML tab to see the class names you can use. The mini browser updates as you type, and each goal gets a check mark when it's done.

No clicking needed. Each goal gets a check mark by itself once your code does it.

  1. Put the .menu li items in a row with display: inline-block. not done yet
  2. Float the .photo to the left. not done yet
  3. Pin the .badge with position: absolute. not done yet
  4. Hide the .old paragraph. not done yet
Your code
What you see

Try an exercise

Recap

  • display decides how an element sits: block (own line), inline (inside a line), inline-block (in a row, with sizes) or none (hidden).
  • position with top, right, bottom and left moves or pins an element. An absolute element is placed inside the nearest positioned parent, and z-index decides which one is in front.
  • overflow handles content that doesn't fit, and float lets text wrap around a picture.

References

Lesson content prepared by the WebCore F.E. team for beginner learners. The following references were used in preparing this lesson.

  • W3C. CSS Display Module Level 3 (official specification). Open reference
  • W3C. CSS Positioned Layout Module Level 3 (official specification). Open reference
  • W3C. CSS Overflow Module Level 3 (official specification). Open reference
  • W3C. CSS 2.2: Floats (official specification). Open reference
  • LibreTexts. Web Site Design (2022, open textbook). Open reference