1. css
  2. /properties
  3. /position

position

Overview

The position property decides the positioning scheme that's used to calculate the location of an element in the document. Crucially, the property works with the top, right, bottom, and left properties which dictate the final location of the positioned element.

Examples and Usage

In the following sections, we'll explore a series of examples demonstrating the different values of the position property. We'll be working with specific HTML structures and CSS rules which are designed for illustrative purposes.

Our basic HTML structure for the first few examples will be:

<div class="parent-container">
  <div class="box one"></div>
  <div class="box two"></div>
  <div class="box three"></div>
</div>

Relative Positioning

Let's first explore the use of position: relative.

.parent-container {
  /* A flex container to hold child elements. */
  display: inline-flex;
  /* Gap between flex items. */
  gap: 2rem;
  /* Black border around the container. */
  border: 3px solid black;
  /* Padding inside the container. */
  padding: 10px;
}

.box {
  /* The size of each box */
  width: 120px;
  height: 120px;
  /* Black border around the box. */
  border: 3px solid black;
}

.one {
  /* Background color of the first box. */
  background: crimson;
}

.two {
  /* Background color of the second box. */
  background: orange;
  /* Position property set to relative. */
  position: relative;
  /* Offsets from the top and right. */
  top: 30px;
  right: 15px;
}

.three {
  /* Background color of the third box. */
  background: royalblue;
}

In this CSS setup, the position value relative doesn't affect the initial position of the orange box denoted by the class .two. However, when used with the top and right properties, it offsets the box from its original location in the normal document flow, not the edge of its container or the viewport. The key point here is that this doesn't affect the position of any other element in the layout.

Absolute Positioning

Now, we'll change the position of the orange box to absolute.

/* Other CSS rules remain the same. */

.two {
  background: orange;
  /* Position property set to absolute. */
  position: absolute;
  /* Offsets from the top and right. */
  top: 30px;
  right: 15px;
}

With position: absolute, the orange box is removed from the document flow, meaning it doesn't affect the layout of other elements. However, its position is determined not by the .parent-container (which has the default static position), but by the nearest ancestor with a position other than static. In this case, it's the <body>.

To establish a new positioning context for the absolutely positioned element, we'll set the position of the .parent-container to relative.

.parent-container {
  /* Other properties remain the same. */
  /* Position property set to relative. */
  position: relative;
}

/* CSS rules for .box, .one, .two, and .three remain the same. */

With this setup, the orange box with position: absolute is positioned relative to its nearest positioned ancestor, the .parent-container.

Fixed Positioning

Next, we'll alter the position of the orange box to fixed.

.parent-container {
  /* Parent container as an inline flexbox, with a relative positioning context. */
  display: inline-flex;
  position: relative;
  gap: 2rem;
  border: 3px solid black;
  padding: 10px;
}

.box {
  /* Standard size and border for our box elements. */
  width: 120px;
  height: 120px;
  border: 3px solid black;
}

.one {
  /* Giving the first box a crimson background. */
  background: crimson;
}

.two {
  /* The second box is given an orange background and fixed positioning. */
  background: orange;
  position: fixed;
  top: 150px;
  right: 15px;
}

.three {
  /* The third box gets a royal blue background. */
  background: royalblue;
}

Here, the .parent-container is defined with a position: relative to enable absolute or fixed positioning of its child elements relative to itself. However, when the .two class is given a position: fixed, the element is taken out of the normal flow of the document. This means the element is positioned in relation to the viewport, not the .parent-container. The offsets top: 150px and right: 15px are relative to the viewport, not the .parent-container. Thus, even if scrolling was introduced by extending the content of the webpage beyond the viewport, the orange box will stay in the same position relative to the viewport.

Sticky Positioning

Lastly, we'll use position: sticky. For this, we'll need a different HTML structure.

<div class="parent-container">
  <section>
    <span class="box"></span>
  </section>
  <section>
    <span class="box"></span>
  </section>
  <section>
    <span class="box"></span>
  </section>
</div>

Here's the corresponding CSS:

.parent-container {
  /* Maximum width and center alignment. */
  width: 90%;
  max-width: 1000px;
  margin: 0 auto;
}

.box {
  /* Size of the box. */
  width: 120px;
  height: 120px;
  /* Position property set to sticky. */
  position: sticky;
  /* Offset from the top. */
  top: 0;
  /* Background color. */
  background: crimson;
}

section {
  /* Section height larger than viewport to create scrolling. */
  height: 150vh;
  /* Centering the box. */
  display: flex;
  justify-content: center;
  /* Border around the section. */
  border: 3px solid black;
  margin-bottom: 6px;
}

With position: sticky, the crimson box behaves like position: relative within its parent until a given offset (in our case, top: 0) within the viewport is met. At this point, as we start scrolling and the parent <section> begins to leave the viewport, the crimson box starts behaving as if it's position: fixed — it "sticks" to the top of the viewport and remains there until the entire parent <section> has scrolled out of view. Once the parent is out of the viewport, the box returns to behave like position: relative and scrolls with the rest of the document.

As a reminder, by default, all elements have the position: static, and they don't react to top, right, bottom, left, or z-index properties. That said, z-index could come in handy when working with positioned elements. For instance, in the third example, we could have added z-index: 1 to the .three class to bring the royal blue box in front of the orange one. This is because the z-index property controls the stack order of specific elements, allowing you to dictate which elements appear above others on the page.

Values

ValueDescription
staticThe default value. The element is positioned based on the normal flow of the document. top, right, bottom, left, and z-index properties don't affect it.
relativeThe element is positioned relative to its original position in the normal flow of the document. top, right, bottom, and left cause offsets from this original position, but without affecting the position of other elements in the page layout.
absoluteThe element is removed from the normal document flow with no space reserved for it in the layout. It's positioned relative to its closest positioned ancestor (or the document's initial containing block if no positioned ancestor is found). The final position is determined by top, right, bottom, and left values.
fixedSimilar to absolute, but the element is positioned relative to the viewport. It won't move even when the page is scrolled.
stickyThe element is positioned as relative until a certain scroll threshold is met, at which point it behaves like fixed and "sticks" to a set position within its containing block.

Associated Properties

  • top
  • right
  • bottom
  • left
  • inset
  • inset-inline
  • inset-inline-start
  • inset-inline-end
  • inset-block
  • inset-block-start
  • inset-block-end
  • z-index

Tips and Tricks

  • An element is deemed positioned if its position value is set to relative, absolute, fixed, or sticky, which is essentially anything other than static.

  • For relative positioning, the top, bottom, left, and right properties cause offsets from the element's original position in the document's flow.

  • absolute and fixed positioned elements are removed from the normal document flow and are placed relative to their nearest positioned ancestor or the initial containing block. The top, right, bottom, and left properties then determine their final location.

  • A sticky positioned element acts like a relative positioned element until its containing block crosses a defined threshold (e.g., top: 10px), after which it behaves as fixed.

  • Be cautious with accessibility when using absolute or fixed positioning. Make sure elements don't block other content when zooming or increasing text size.

  • Scrolling elements containing fixed or sticky content can cause performance issues and affect accessibility. The browser must repaint the content in a new location while scrolling, which can reduce the frame rate.

Browser Compatibility

For a detailed breakdown of the respective values, vendor prefix usage, and partial support in older browser versions, refer to the first link in the Useful Resources below.

BrowserChromeEdgeSafariFirefoxOperaInternet Explorer
SupportYesYes*YesYes*Yes*Yes*

Caution: Internet Explorer support data may be incorrect since MDN browser-compat-data no longer updates it. Also, early Edge versions used EdgeHTML, leading to mismatched version numbers. From version 79, Edge uses Chromium with matching version numbers.

Useful Resources

Can I use: position

W3C's Editor's Draft of CSS Positioned Layout Module Level 3: position