Position

Position refers to how an element is laid out in an HTML document. The CSS property position works in relationship the following CSS properties to determine an element’s final position:

There are five valid values for position and they are described and demonstrated below.

Default value

The default value of the position property is static.

div {
  position: static;
}

Since this is the browser default for all HTML elements, you would only write this CSS if you needed to override a previous custom setting.

Elements with static positioning ignore the effects of top, right, bottom, left and z-index. This means that, by default, these properties have no effect when used on most HTML elements unless their position value has been changed. As a result, it would be meaningless to write the following CSS:

Don’t do this

div {
  top: 30px;
  z-index: 10;
}

Any element that has a position value other than static is referred to as a positioned element.

Relative positioning

Using relative positioning allows you to position an element relative to its original or starting position. This is the simplest form of positioning to understand and does not effect the position of other elements.

The yellow box above has the following CSS applied to it, which causes it to be 20 pixels lower and to the right than the other boxes:

div {
  position: relative;
  top: 20px;
  left: 20px;
}

You can compare the original position by clicking the toggle button in the Glitch demo.

💡 You can remix any of the embedded Glitch projects if you want to update or experiment with the CSS.

Absolute positioning

Using absolute positioning is far more dramatic than relative positioning because it removes an element from the normal flow of a document. Additionally, the space that element would take up is removed from the document.

The yellow box above has the following CSS applied to it:

div {
  position: absolute;
  top: 0;
  right: 0;
}

In the first row, this CSS causes the box to be positioned in the top right corner of the HTML document because none of its parent elements are positioned (that is, they are the default of position: static).

In the second row, the section element (with the grey background) wraps around all the boxes and is itself a positioned element. It has the CSS position: relative added to it, and this causes any absolutely positioned children to be positioned relative to it.

Using the toggle button in this demo, you can also see how the space taken up by the box is lost when it is positioned absolutely. In both rows, the remaining green boxes are positioned as if the absolutely positioned box doesn’t exist at all.

🤔 Did you notice the little bit of white space on the right side of the absolutely positioned box? This is my stylesheet adds 12 pixels of margin to the left and right of each box. Those styles carry through, even when the element is absolutely positioned. There is no top margin on the box, so it appears flush with the body or section element it is positioned relative to.

Fixed positioning

Fixed elements are positioned relative to the viewport, not the document, and do not scroll with the document.

Viewport is used to describe the area of an HTML document that is currently visible. Take this page as an example: it has a lot of content and examples, so it requires scrolling to see everything. The space that you’re currently able to see is the viewport.

In this example, the yellow box has the following CSS applied to it:

div {
  position: fixed;
  bottom: 12px;
}

This takes the box out of the normal document flow and locks it in at 12 pixels from the bottom of the viewport.

If you’ve ever encountered an ad or video that stubbornly sticks to your web browser, even when you scroll, that element was likely created using position: fixed.

Fixed and absolutely positioned elements have a lot in common; both are:

Sticky positioning

Sticky elements change their behavior based on a user’s scrolling behavior. They start out acting as if relatively positioned and then act more like a fixed element as its parent element leaves the viewport.

Scroll inside the following Glitch window to see a demonstration of this behavior:

In this example, the yellow box has the following CSS applied:

div {
  position: sticky;
  top: 0;
}

As the containing section element (with the grey background) moves out of the viewport, the yellow box locks in at the top of the viewport.

Layering elements

Positioned elements, in addition to respecting values of top, right, bottom and left, also can be layered, much like layers in a PhotoShop file. This is done via a property named z-index.

This property uses number values where higher/larger numbers get stacked on top of elements with lower or no numbers.

Clicking the “make relative” button sets all the boxes to be position: relative and updates their left values to force them to overlap. By default, they stack so that the last element in the HTML is on top (so, in this case, the third box covers the second box).

The z-index buttons add a z-index value of 2 to the box of your choice, like so:

div {
  z-index: 2;
}

If you reset this demo and then press “make relative” followed by “third box,” you’ll see that adding a z-index value to the final box doesn’t initially do anything; it’s stacked on top by default.

If you remix this project, you can experiment with using different z-index values on these boxes.

Some final thoughts

CSS positioning is very powerful and has many uses, but it is also often over used by beginning developers. Keep the following in mind:

This example shows how overusing the position property can break your layout. When you click the “make absolute” button, all the boxes are absolutely positioned. As before, the first row is positioned relative to the entire HTML document and the second is relative to the parent section element.

A couple of not great things happen here:

Similarly, it’s possible for an element with sticky or fixed positioning to cover up other content and make it difficult or impossible for users to complete actions on your site.

None of this means you can’t or shouldn’t absolutely position elements, but you should think through the potential consequences and not overuse these properties in your layout.