CSS positioning Properties 🤔

September 10, 2022

What You See Is What You Get – is a competing model for authoring documents. These applications constantly update a final form presentation. As the author types, the screen is updated to reflect the page layout that would result should the document be printed at that point. A successful style sheet language for the web had to be compelling enough both for browser developers to implement, and for authors to use.

Style sheet languages and structured document formats are mutually dependent on each other. Without style sheets, structured documents cannot be presented, and without structured documents there is nothing for style sheets to present. Due to the strong relationship between the two, it is important to understand structured documents when studying style sheet languages.

One of the most attractive features of structured documents is that the content can be used in many contexts and presented in various ways. A variety of different stylesheets can be attached to the logical structure to serve different needs. However, theflexibility that structured documents offer comes at a price since some kind of stylesheet mechanism is needed to make the content available for users.

Elements of a website’s user interface (UI) can interact with and overlay on top of one another in many different ways, making CSS layout challenging to control. One way to set the placement of an element and how it overlays other elements is with a combination of the position property, z-index property, and the direction properties, which apply spacing values with top, right, bottom, and left. Experience with these CSS properties will enable you to create UI elements like dropdown navigation bars and figure captions efficiently and quickly.

The position CSS property

The position property tells the browser how an element should be positioned on the page. By default the value of position is static, but we can modify it to be any of the following values: relative, absolute, fixed, sticky. In this post I will go over each of them. The CSS position property is used to set position for an element. it is also used to place an element behind another and also useful for scripted animation effect.

You can position an element using the top, bottom, left and right properties. These properties can be used only after position property is set first. A position element's computed position property is relative, absolute, fixed or sticky.

We will use a simple HTML markup which is really simple for better understanding. It contains a container div, and 3 child divs, that we will position throughout the examples. I also added different colors to these child divs, so it will be easier to see the difference.

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="./styles.css" />
    <title>CSS positions</title>
    <style>
      .container {
        background-color: blue;
        padding: 20px;
      }

      .container > div {
        padding: 15px;
      }

      .container span {
        margin-bottom: 20px;
      }

      .first {
        background-color: green;
      }

      .second {
        background-color: red;
      }

      .third {
        background-color: lightyellow;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <span>Container</span>
      <div class="first">First</div>
      <div class="second">Second</div>
      <div class="third">Third</div>
    </div>
  </body>
</html>

Let's have a look at following CSS positioning:

👉  Static Positioning
👉  Fixed Positioning
👉  Relative Positioning
👉  Absolute Positioning

Static

This is the default value of the position property. If the position of an element is static, the element will render in order, based on the position of it in the original document flow.

Relative

If we set the position of an element to relative, it will appear in the document as it would by default using static. The trick is that by setting position relative, we gain access to the following CSS properties: top, left, right, bottom. With these we can add an offset to the specific direction. So for example if we set left: 20px. The element will be placed 20 pixel to the right. If we would have provided -20px it would push the content to the left with 20px.

Make the following changes:

.second {
        background-color red;
        position: relative;
        left: 20px;
      }

🛑 If you set position: relative on an element, you are now able to position it with an offset, using the properties

top
right
bottom
left

which are called offset properties. They accept a length value or a percentage. Let's have a look at the example bellow which is a parent container, a child container, and an inner box with some text:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>Test</p>
    </div>
  </div>
</div>

CSS to give some colors and padding, but does not affect positioning:

.parent {
  background-color: #af47ff;
  padding: 30px;
  width: 300px;
}

.child {
  background-color: #ff4797;
  padding: 30px;
}

.box {
  background-color: #f3ff47;
  padding: 30px;
  border: 2px dotted #333;
  font-family: courier;
  text-align: center;
  font-size: 2rem;
}

here’s the result:

You can play around and try to add any of the properties that I mentioned before (top, right, bottom, left) to .box, and `you will see that nothing will happen. The position is static.

But if we set position: relative to the box, at first apparently nothing changes. But the element is now able to move using the top, right, bottom, left properties, and now you can alter the position of it relatively to the element containing it.

For example:

.box {
  /* ... */
  position: relative;
  top: -60px;
}

Fixed

With fixed positioning we also have access to top, left, right, bottom properties. In this case the element is positioned relative to the browser window's viewport.

So if we set top 70px and left 20px on a fixed positioned element it will appear 70 pixels from the top of the viewport and 20px from the left edge of the viewport. Fixed positioning also removes the document from the normal document flow.

Modify the CSS:

.second {
        background-color: red;
        position: fixed;
        left: 20px;
        top: 70px;
      }

Like with absolute positioning, when an element is assigned position: fixed it’s removed from the flow of the page.

The difference with absolute positioning is this: elements are now always positioned relative to the window, instead of the first non-static container.

.box {
  /* ... */
  position: fixed;
}
.box {
  /* ... */
  position: fixed;
  top: 0;
  left: 0;
}

Absolute

Absolute positioning is the one which can trick developers. It is working like the fixed positioning, but it is not positioned relatively to the viewport, but instead it is positioned based on the closest positioned element (which has position other than static). If there are no positioned parents it will be positioned relative to the viewport (Same result as it would be with fixed).

Make these changes to the CSS:

.second {
        background-color: red;
        position: absolute;
        left: 20px;
        top: 70px;
      }

If we add a position value to a parent, in this case we will add it to the container div, the absolutely positioned child will be positioned relatively to that. We often use relative position for the parent as it won't remove it from the standard document flow, and the parent will be placed in the site where it would have been without position: relative.

Add position relative to the container:

.container {
        background-color: blue;
        padding: 20px;
        position: relative;
      }

Sticky

Using sticky will position our element based on the user's scroll position. It toggles between position relative and fixed. We can provide the offsets using top, left, right, bottom. Until the specified offsets are met the element acts like a relatively psoitioned element, but when the scroll position is greater than the offset it "swithces" to position fixed and be positioned relatively to the viewport. It stays fixed until the user scrolls back to the opposite direction and the distance will be less than the offset, then it goes back to act like a relative positioned element again.

To be able to scroll add 3 times the height of the viewport to our container:

.container {
        background-color: blue;
        padding: 20px;
        height: 300vh;
      }

Add the sticky position and the top offset to the element:

.second {
        background-color: red;
        position: sticky;
        top: 0;
      }

Z-Index

The Z-Index property is used to specify the stacking order of the elements that overlap. The stack level refers to the element’s position on the Z-axis. 👉 Elements with a higher z-index value are displayed in front of those with a lower z-index value.

Default stacking order

Let’s first mention the default order the browser stacks elements in, when no z-index is applied:

Root element (the element)

Non-positioned elements in the order they are defined

Positioned elements in the order they are defined

A non-positioned element is an element with the default position value static. A positioned element is an element with any other position value. Examples of other values are: absolute, relative, sticky or fixed.

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”green”></div>
.blue, .pink, .orange {
  position: absolute;
}

We defined the green box last in the document. Still, it appears behind the others because it is non-positioned. Stacking with z-index

If we now want to change the stacking order of these elements, we can use the property z-index. An element with a higher z-index will be displayed in front of an element with a lower z-index. One thing to note is that z-index only works with positioned elements.

.blue, .pink, .orange {
  position: absolute;
}

.blue {
  z-index: 2;
}

.orange {
  z-index: 3;
}

.green {
  z-index: 100; // it has no effect since the green box is non-positioned
}

The orange box with a higher z-index is displayed in front of the blue box.

By using z-index on positioned elements, we can change the default stacking order. When applying certain CSS properties, an element can form a stacking context. Z-index values only have a meaning within the same stacking context.

Stacking Context

Let’s say that we add another positioned box to the layout which we want to position behind the pink box. We update our code to the following:

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”purple”></div>
<div class=”green”></div>
.blue, .pink, .orange, .purple {
  position: absolute;
}

.purple {
  z-index: 0;
}

.pink {
  z-index: 1;
}

.blue {
  z-index: 2;
}

.orange {
  z-index: 3;
}

.green {
  z-index: 100;
}

The pink box is displayed in front of the purple box as expected, but what happened to the orange box? Why is it all of a sudden behind the blue one even though it has a higher z-index? This is because adding a z-index value to an element forms what is called a stacking context.

The pink box has a z-index value other than auto, which forms a new stacking context. The fact that it forms a stacking context affects how its child elements are being displayed.

It is possible to change the stacking order of the pink box child elements. However, their z-index only has a meaning within that stacking context. This means that, we won’t be able to move the orange box in front of the blue box, because they are not within the same stacking context anymore.

If you want the blue box and the orange box to be part of the same stacking context, we can define the blue box as a child element of the pink box. This will make the blue box appear behind the orange one.

<div class=”pink”>
  <div class=”orange”></div>
  <div class=”blue”></div>
</div>
<div class=”purple”></div>
<div class=”green”></div>

Stacking contexts are not only formed when applying z-index to an element. There are several other properties that cause elements to form stacking contexts. Some examples are: filter, opacity, and transform.

let's apply a filter to the box

<div class=”pink”>
  <div class=”orange”></div>
</div>
<div class=”blue”></div>
<div class=”green”></div>
.blue, .pink, .orange {
  position: absolute;
}

.pink {
  filter: hue-rotate(20deg);
}

.blue {
  z-index: 2;
}

.orange {
  z-index: 3;
}

.green {
  z-index: 100;
}

The orange box still has a higher z-index than the blue one, but is still displayed behind it. This is because the filter value caused the pink box to form a new stacking context. 🛑 About z-index: 0 it's important to note the following:

z-index: 0creates a stacking context while z-index: auto do not In most cases this won't affect the rendered elements.

🛑 Note: z-index only works on positioned elements (position: absolute, position: relative, position: fixed, or position: sticky) and flex items (elements that are direct children of display:flex elements).

🛑 Note: If two positioned elements overlap without a z-index specified, the element positioned last in the HTML code will be shown on top.

Simply in CSS, you can position 2 or more objects to overlap each other. Their z-indexes determine which objects are "in front of" or "behind" other objects that they overlap. The higher an object's z-index, the "higher in the stack" of objects it will display.

z-index:0 is always the "default layer" (the layer in which all elements without an explicit z-index reside), and z-index:auto means: "Sets the stack order equal to its parent". Since all the children of a parent by default start in the "z-layer 0" - relative to their parent, then, in-affect, z-index:auto and z-index:0means the same thing: they will both be in the same "layer", and their stacking order will be according to the default stacking rules`
Stacking with floated blocks

<div id="example-auto">
  <div class="box red">
    <div class="box green" style="z-index: 1"></div>
  </div>
  <div class="box blue"></div>
</div>

<div id="example-0">
  <div class="box red" style="z-index: 0">
    <div class="box green" style="z-index: 1"></div>
  </div>
  <div class="box blue"></div>
</div>
.box {
  position: relative;
  width: 64px;
  height: 64px;
  top: 32px;
  left: 32px;
}

.red {
  background: red;
}

.green {
  background: green;
}

.blue {
  background: blue;
}

#example-0 {
  margin-top: 32px;
}

In both examples, red and blue are siblings with a position: relative and green is a child of red with position: relative and z-index: 1:

Root
    Red: position: relative
        Green: position: relative; z-index: 1
    Blue: position: relative

In the first example, green will be positioned above red and blue. This is because it has a z-index: 1, so a stacking context is created and put above the root context.

In the second example, green will be positioned above red, but below blue. This is because red has z-index: 0, so it creates a stacking context at the same level of blue. So green will be above red (because green also creates a stacking context), but below blue because it's trapped in the context of red.

The stacking context

If you have any questions regarding the CSS Positioning lesson, let me know in the comments section. I will get back to you as soon as possible.

Happy learning! 💻

Up next