← Back to CSS Course | Chapter 5: Layout & Display | Lesson 5 of 14

CSS Position Offsets

Imagine sticky notes on a corkboard. A note with no pin just sits in the flow of other notes. A pinned note can be nudged left, right, up, or down from wherever it would normally sit, or pinned to an exact spot on the board itself. top, right, bottom, and left are those nudge instructions, and what they actually measure from depends entirely on which position value the element uses.
Syntax
css
selector {
  position: relative | absolute | fixed | sticky;
  top: length;
  right: length;
  bottom: length;
  left: length;
}

Offsets Require a Position Value

top/right/bottom/left do nothing on an element with the default position: static -- they only take effect once position is set to relative, absolute, fixed, or sticky. This is the single most common reason a developer's offset appears to be ignored.

Note:
  • Accepted values:
  • top | right | bottom | left — offsets such as 10px, 5%, or auto
  • inset — shorthand for all four sides
  • length — distance from the reference edge
  • percentage — relative to the containing block
  • auto — no offset set (default)
  • Only applies when position is not static
  • inherit | initial | unset | revert — CSS-wide keywords accepted by every property

Example: Offsets Require a Position Value

css
<style>
.ignored {
  top: 20px;
  background: gray;
  color: white;
  padding: 10px;
  margin-bottom: 10px;
}
.works {
  position: relative;
  top: 20px;
  background: crimson;
  color: white;
  padding: 10px;
}
</style>
<div class="ignored">top: 20px is ignored (position: static)</div>
<div class="works">top: 20px works (position: relative)</div>

Offsets on Relatively Positioned Elements

On position: relative, offsets shift the element visually from where it would normally sit in the flow, but the space it originally occupied stays reserved -- other elements don't reflow to fill the gap. Positive values move it away from that edge; there's no true centering via offsets alone here.

Note:
  • Accepted values:
  • length — e.g. 20px or 2rem
  • percentage — relative to the containing block
  • auto — the browser decides (initial value)
  • negative length — moves the edge outward
  • only applied when position is not static
  • inherit | initial | unset | revert — CSS-wide keywords accepted by every property

Example: Offsets on Relatively Positioned Elements

css
<style>
.box {
  position: relative;
  top: 20px;
  left: 20px;
  background: crimson;
  color: white;
  padding: 10px;
}
</style>
<div class="box">Shifted, but its original space stays reserved</div>
<div style="background: #ddd; padding: 10px;">Not moved up to fill the gap</div>

Offsets on Absolutely Positioned Elements

On position: absolute, offsets are measured from the edges of the nearest ancestor that has position set to anything other than static (its positioned containing block) -- not from the viewport, and not from its normal flow position, which is removed entirely.

Note:
  • Accepted values:
  • length — e.g. 20px or 2rem
  • percentage — relative to the containing block
  • auto — the browser decides (initial value)
  • negative length — moves the edge outward
  • only applied when position is not static
  • inherit | initial | unset | revert — CSS-wide keywords accepted by every property

Example: Offsets on Absolutely Positioned Elements

css
<style>
.parent {
  position: relative;
  min-height: 100px;
  background: #eef;
  border: 2px solid #99a;
}
.child {
  position: absolute;
  top: 10px;
  right: 10px;
  background: crimson;
  color: white;
  padding: 8px;
}
</style>
<div class="parent">
  <div class="child">Measured from the parent's edges</div>
</div>

Offsets on Fixed and Sticky Elements

position: fixed measures offsets from the browser viewport itself and ignores scrolling entirely, while position: sticky measures offsets from the nearest scrolling ancestor but only kicks in once the element would otherwise scroll past that offset threshold.

Note:
  • Accepted values:
  • length — e.g. 20px or 2rem
  • percentage — relative to the reference box (the viewport for fixed)
  • auto — the browser decides (initial value)
  • negative length — moves the edge outward
  • only applied when position is not static
  • inherit | initial | unset | revert — CSS-wide keywords accepted by every property

Example: Offsets on Fixed and Sticky Elements

css
<style>
.fixed {
  position: fixed;
  top: 0;
  right: 0;
  background: darkorange;
  color: white;
  padding: 10px;
}
.sticky {
  position: sticky;
  top: 0;
  background: seagreen;
  color: white;
  padding: 10px;
}
.content p {
  background: #f0f0f0;
  padding: 12px;
  margin-bottom: 10px;
}
</style>
<div class="fixed">Measured from the viewport</div>
<div class="sticky">Measured from the scrolling ancestor</div>
<div class="content">
  <p>Scroll down to compare fixed vs sticky. Paragraph 1.</p>
  <p>Paragraph 2.</p>
  <p>Paragraph 3.</p>
  <p>Paragraph 4.</p>
  <p>Paragraph 5.</p>
  <p>Paragraph 6.</p>
  <p>Paragraph 7.</p>
  <p>Paragraph 8.</p>
</div>

Setting Opposite Offsets Together

Setting both left and right (or both top and bottom) on an element without an explicit width stretches it to fill the distance between those two edges -- a common technique for full-width absolutely positioned overlays without hardcoding a width value.

Note:
  • Accepted values:
  • length — e.g. 20px or 2rem
  • percentage — relative to the containing block
  • auto — the browser decides (initial value)
  • negative length — moves the edge outward
  • only applied when position is not static
  • inherit | initial | unset | revert — CSS-wide keywords accepted by every property

Example: Setting Opposite Offsets Together

css
<style>
.parent {
  position: relative;
  height: 100px;
  background: #eef;
  border: 2px solid #99a;
}
.overlay {
  position: absolute;
  left: 0;
  right: 0;
  background: crimson;
  color: white;
  padding: 8px;
}
</style>
<div class="parent">
  <div class="overlay">Stretched to fill the width, no width set</div>
</div>
Live Example
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Setting top or left on an element with position: static, which has no effect.
  2. Using offsets on an absolute element whose parent has no position, so it is placed relative to the page.
  3. Setting both top and bottom on a relative element and expecting both to apply, when top wins.
Browser Support

Supported in all modern browsers: Chrome, Firefox, Safari, Edge and Opera.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.