Skip to content
Announcing the new Pro Zone. Check it out!

CSS position Property – How to Define an Element's Position

position defines how you want browsers to place the selected HTML element.

The position property accepts the following values:

  • static
  • relative
  • absolute
  • fixed
  • sticky

Let’s discuss the five values below.

What Is position: static in CSS?

static is position’s default value. It positions the selected element following the normal layout flow.

Here’s an example:

section {
background-color: orange;
margin: 50px;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
}
.item3 {
background-color: DarkGreen;
position: static;
}

Try it on StackBlitz

The static value in the snippet above tells browsers to position item3 statically according to the document’s normal layout flow.

What Is position: relative in CSS?

relative positions the selected element relative to its regular position in the document’s normal layout flow.

In other words, suppose you have placed an element according to the page’s normal flow. The position: relative declaration along with the CSS top, right, bottom, and left properties allow you to offset the element relative to its initial position.

Here’s an example:

section {
background-color: orange;
margin: 50px;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
}
.item3 {
background-color: DarkGreen;
position: relative;
top: 25px;
left: 40px;
}

Try it on StackBlitz

We used the position property to offset item3 relative to its initial location in the document’s normal layout flow.

In other words, we offset item3 25px away from its normal top position and 40px from its initial left location.

What Is position: absolute in CSS?

absolute does the following:

  1. It removes the selected element from the document’s normal layout flow.
  2. It positions the removed element absolutely to the specified edge of its container (or the HTML document).

Here’s an example:

section {
background-color: orange;
margin: 50px;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
}
.item3 {
background-color: DarkGreen;
position: absolute;
top: 25px;
left: 40px;
}

Try it on StackBlitz

We used the position property to offset item3 absolutely 25px away from the HTML document’s top edge and 40px from its left side.

Suppose an absolutely positioned element’s parent has a static position property. In that case, browsers will offset the absolute item from the HTML document’s edges.

For instance, the snippet above offsets item3 from the HTML document’s edges because its container’s (the <section> element) position property is static.

If you prefer to offset item3 from its container’s edges, specify a non-static position property for the <section> element.

Here’s an example:

section {
background-color: orange;
margin: 50px;
position: relative;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
}
.item3 {
background-color: DarkGreen;
position: absolute;
top: 25px;
left: 40px;
}

Try it on StackBlitz

We used the position property to offset item3 absolutely 25px away from the <section>’s top edge and 40px from its left side.

What Is position: fixed in CSS?

fixed does the following:

  1. It removes the selected element from the document’s normal layout flow.
  2. It fixes the removed element to the specified region of the viewport.

In other words, browsers will fix a fixed positioned element to the specified area of the viewport. Therefore, the item will remain in the same place even when users scroll the page.

Here’s an example:

section {
background-color: orange;
margin: 50px;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
}
.item3 {
background-color: DarkGreen;
position: fixed;
bottom: 25px;
right: 40px;
}

Try it on StackBlitz

We used the position property to fix item3 to the viewport’s bottom-right region.

What Is position: sticky in CSS?

sticky sticks the selected element to the viewport once it reaches the specified threshold.

Here’s an example:

section {
background-color: orange;
margin: 50px;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
}
.item3 {
background-color: DarkGreen;
position: sticky;
top: 25px;
}

Try it on StackBlitz

We used the position property to stick item3 to the viewport once users scroll it 25px away from the page’s top edge.

Below are three essential pieces of info to remember whenever you use position: sticky.

1. Sticky ends at the end of its container

An element’s sticky behavior ends once you’ve scrolled to its container’s bottom edge. For instance, consider this example:

section {
background-color: orange;
margin: 50px;
padding: 13px;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
margin: 10px;
}
.sticky-item {
background-color: DarkGreen;
position: sticky;
top: 25px;
}

Try it on StackBlitz

In the snippet above, each <section>’s sticky item stops sticking to the viewport once users scroll to the container’s bottom edge.

2. Sticky won’t work if its ancestor has a non-visible overflow property and no set height

Suppose any of the sticky element’s ancestor (parent) has a non-visible overflow value. In that case, the sticky effect will not work—unless you set the overflowing container’s height.

In other words, a position: sticky property has no effect if you use it on an element whose ancestor has any of the following properties and no scrollable height:

  • overflow: auto
  • overflow: hidden
  • overflow: overlay
  • overflow: scroll

Here’s an example:

section {
background-color: orange;
margin: 50px;
padding: 13px;
}
.first-section {
overflow: auto;
}
.second-section {
overflow: hidden;
}
.third-section {
overflow: scroll;
}
.fourth-section {
overflow: visible;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
margin: 10px;
}
.sticky-item {
background-color: DarkGreen;
position: sticky;
top: 25px;
}

Try it on StackBlitz

Only the fourth section’s sticky item worked because it is the only one whose ancestor has an overflow: visible property.

The remaining sticky items did not work because of the following reasons:

  1. The <section> elements containing them are their nearest scrolling element (ancestor).
  2. The <section> elements containing them are their nearest containing block ancestor.
  3. A sticky element sticks to its nearest “scrolling” and “containing block” ancestor. (Note: You must activate the scrolling mechanism to implement the sticky effect).

Therefore, suppose the first <section> has a height that activates its scrolling mechanism. In such a case, its sticky item will stick to it.

Here’s an example:

section {
background-color: orange;
margin: 50px;
padding: 13px;
}
.first-section {
overflow: auto;
height: 300px;
}
.second-section {
overflow: hidden;
}
.third-section {
overflow: scroll;
}
.fourth-section {
overflow: visible;
}
div {
border: 1px solid black;
background-color: purple;
color: white;
padding: 20px;
border-radius: 5px;
margin: 10px;
}
.sticky-item {
background-color: DarkGreen;
position: sticky;
top: 25px;
}

Try it on StackBlitz

Note the following:

  • visible is the overflow property’s default value.
  • A scrolling element is an element with a non-visible overflow value. In other words, an element has a scrolling mechanism if its overflow property is auto, hidden, overlay, or scroll.
  • You can activate a container’s scrolling mechanism by making its height less than the total height of its children.
  • An element’s position property’s value determines its containing block.

3. How to find a sticky element’s ancestors that have a non-visible overflow property

Below is the snippet for finding a sticky element’s ancestors whose overflow property’s value is auto, hidden, overlay, or scroll.

let parentElementOfStickyItem = document.querySelector(
"selectorOfStickyItem"
).parentElement;
while (parentElementOfStickyItem) {
const valueOfOverflowProperty = getComputedStyle(
parentElementOfStickyItem
).overflow;
if (valueOfOverflowProperty !== "visible") {
console.log({
[parentElementOfStickyItem.tagName]: valueOfOverflowProperty,
});
}
parentElementOfStickyItem = parentElementOfStickyItem.parentElement;
}

Try it on StackBlitz