# Positioning: fixed and sticky

Keep a "chat with us" button on screen with position fixed, keep a header or a table's headings in reach with position sticky, and choose the right one of the five position values for any part of a page.

Apprentice · CSS · Updated November 1, 2026

## After this lesson you can

- Keep an element in one spot on screen while the page scrolls with position: fixed
- Make a header or table heading stick while its section scrolls with position: sticky and a top value
- Choose static, relative, absolute, fixed or sticky positioning for a part of a page

## Key takeaways

- position: fixed places an element relative to the viewport, the visible part of the browser window, so it stays in the same spot on screen while the page scrolls.
- A fixed element gives up its space in the page, so leave room for it, or it covers the content behind it.
- position: sticky keeps an element in normal flow until scrolling brings it to its top value, then holds it there while its parent is on screen.
- Sticky needs a top value and room to scroll. An ancestor with overflow set to hidden, auto or scroll can stop it from sticking.
- To choose a position value, ask whether the element keeps its space, whether it scrolls with the page, and what it's measured from.

Scroll down a long page on almost any site you use. The "Chat with us" bubble stays in the bottom corner the whole way. The site's header with its menu stays at the top. In a long spreadsheet-style table, the row of column names stays in view, so you never lose track of which column is which. Some apps do this with JavaScript, but CSS does all three with one property and no JavaScript at all.

Paws & Whiskers' adoption list is long, and the shelter wants two things: an **Adopt today** button that never leaves the screen, and a header that stays at the top while the pets scroll by.

## fixed: stuck to the window

Picture a sticky note on your computer screen. Whatever you scroll through behind it, the note stays in the same spot on the glass.

That's **fixed positioning**. A fixed element is placed relative to the **viewport**, the part of the page you can see in the browser window right now, and it stays there while the page scrolls underneath it:

```css
.adopt-button {
  position: fixed;
  bottom: 24px;
  right: 24px;
}
```

The button sits 24 pixels up from the bottom of the window and 24 pixels in from the right, and it stays there however far the visitor scrolls. Like `absolute`, `fixed` takes the element out of normal flow, so its space closes up.

That means it can cover content: whatever scrolls behind the button is hidden while it's there. Leave room for it, for example with `padding-bottom: 96px;` on the `<body>`, so the last pet on the list can scroll up above the button. Keep a fixed element small, too: on a phone, a big one covers a lot of a small screen.

![The adoption list, scrolled to the top and then halfway down: in both, the orange Adopt today button sits in the same bottom right corner of the window while the pet cards have moved up behind it](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/10/e9bab4f38a90448a82a90abc242a441c.webp)

**Try it.** In your `adoption-list` folder, make `fixed.html` with a page skeleton, a `<style>` element and an `<a class="adopt-button" href="#apply">Adopt today</a>`. Put twenty paragraphs of pet names after it, so the page has room to scroll. Add the rule above and a background color, and scroll.

## sticky: in the flow, until it isn't

Now picture the "Now Boarding" sign on a moving walkway at an airport. It rides along with you, and then, at the end, it stops while you walk on past it.

That's **sticky positioning**, and it's a mix of two others. A sticky element starts in normal flow, keeping its space, like `relative`. When scrolling brings it to its `top` value, it stops there and stays, like `fixed`:

```css
.site-header {
  position: sticky;
  top: 0;
  background-color: #1d3557;
}
```

The header starts at the top of the page. When the visitor scrolls, the header's top edge reaches 0 pixels from the top of the window, and it stays there while the pet cards scroll up underneath. It needs a background color: without one, it's see-through, and the cards show through it as they pass.

The sticky element stays only while its parent is on screen. This header is a child of the `<body>`, so it sticks for the whole page. A sticky heading inside one `<section>` lets go when that section scrolls away, and the next section's heading takes over.

![The adoption list before and after scrolling: before, the dark blue header is at the top of the page above the first row of cards; after, the header is still at the top of the window while the third row of cards scrolls up underneath it](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/10/54b41915c5a74a4883c63eb2000029de.webp)

## Sticky table headings

A long table is where sticky shines. The shelter has a table of every pet, their age and their adoption fee. The HTML is ready: `<th>` is a heading cell, and the headings sit in the table's first row, inside `<thead>`:

```html
<table class="pet-table">
  <thead>
    <tr><th>Pet</th><th>Age</th><th>Fee</th></tr>
  </thead>
  <tbody>
    <tr><td>Biscuit</td><td>3 years</td><td>$150</td></tr>
    <tr><td>Mango</td><td>10 weeks</td><td>$95</td></tr>
  </tbody>
</table>
```

```css
.pet-table th {
  position: sticky;
  top: 0;
  background-color: #ffffff;
}
```

Scroll down a table of fifty pets, and the row of headings stays at the top of the window, so "Fee" is always in sight. Each heading cell sticks on its own, which is why the rule goes on the `th` elements.

## Why sticky sometimes doesn't stick

Sticky is the position value that most often seems to do nothing. When it doesn't stick, check these three things:

1. **A `top` value.** Without `top` (or `bottom`), the browser doesn't know where to stop the element, so it scrolls away like a relative element.
2. **Room to scroll.** The element sticks only inside its parent. If the parent is no taller than the sticky element, as when a header is wrapped in a `<div>` that holds nothing else, there's no room for it to stick in.
3. **No `overflow` on an ancestor.** An element around it with `overflow: hidden`, `auto` or `scroll` becomes the box it sticks inside, instead of the window. If that box doesn't scroll, the element never sticks. The developer tools help here: select each ancestor in the Elements panel (Inspector in Firefox) and look for `overflow` in its styles.

## Choosing a position value

To choose, ask three questions about the element: does it keep its space in the page, does it scroll with the page, and what is it measured from?

| Value | Keeps its space? | Scrolls with the page? | Measured from | A typical job |
|---|---|---|---|---|
| `static` | Yes | Yes | Nothing: offsets do nothing | Almost everything: the default |
| `relative` | Yes | Yes | Its own normal place | A small nudge; a frame for absolute children |
| `absolute` | No | Yes | Its nearest positioned ancestor, or the page | A badge, a close button, an overlay |
| `fixed` | No | No, it stays on screen | The viewport | A chat button, a cookie notice |
| `sticky` | Yes | Until it reaches its `top`, then it stays while its parent is on screen | Its normal place, then the viewport's edge | A header, table headings |

**Try it.** Open a site you use every day and scroll. Find something that stays on screen. Right-click it, choose **Inspect**, and look in the Styles pane (Rules in Firefox): is it `fixed` or `sticky`?

## Check yourself

2 questions to try on the lesson page.

## So what

Fixed and sticky keep the important things in reach (a menu, a button, the names of a table's columns) while everything else scrolls, and they do it with one line of CSS.

## Key terms

- [Fixed positioning](https://www.ask-codey.com/glossary/fixed-positioning)
- [Sticky positioning](https://www.ask-codey.com/glossary/sticky-positioning)
- [Viewport](https://www.ask-codey.com/glossary/viewport)
- [Positioning scheme](https://www.ask-codey.com/glossary/positioning-scheme)

## Cheat sheets

- [Positioning: fixed and sticky](https://www.ask-codey.com/cheat-sheets/css-position-fixed-and-sticky-cheat-sheet)

## Related

- [Positioning: relative and absolute](https://www.ask-codey.com/lessons/css-position-relative-and-absolute)
- [Stacking: z-index and What Sits on Top](https://www.ask-codey.com/lessons/css-z-index-and-stacking)
- [Normal Flow and the display Property](https://www.ask-codey.com/lessons/css-normal-flow-and-display)

Source: https://www.ask-codey.com/lessons/css-position-fixed-and-sticky
