← 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.

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.

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.

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.

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.

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.

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>

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.