CSS Position in 5 Mins

When I was trying to follow the tutorial to clone the linkedin.com I got stuck by some simple CSS concepts. Therefore, I spent some time dig into the detail. In this blog I summarize the effects of "Position" attribute in CSS.

Environment Setup

We define one parent and three children.

<div class="parent">
      Parent
      <div class="child child1">
        Child1
      </div>
      <div class="child child2">
        Child2
      </div>
      <div class="child child3">
        Child3
      </div>
</div>
.parent {
  background-color: #0fa9f8;
  padding: 20px;
}

.child1 {
  background-color: #76fe77;
}

.child2 {
  background-color: #f37574;
}

.child3 {
  background-color: #f575e7;
}

image.png

Experiments

Let's start the experiments by trying different values.

Static

The static element is positioned according to the normal flow of the document. The top, right, bottom, left, and z-index properties have no effect. This is the default value.

Relative

The relative element is positioned according to the normal flow of the document, and then offset relative to itself based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements; thus, the space given for the element in the page layout is the same as if position were static.

Let's put the "relative" to the three children, and we see there is no effect at all. Simply because if we don't set "top, right, bottom, and left", it is equivalent to "static".

.parent {
  background-color: #0fa9f8;
  padding: 20px;
  margin-top: 50px;
}

.child1 {
  background-color: #76fe77;
  position: relative;
}

.child2 {
  background-color: #f37574;
  position: relative;
}

.child3 {
  background-color: #f575e7;
  position: relative;
}

image.png

If we set the margion-top to 70px in the child1, we will see all the children go down accordingly.

.child1 {
  background-color: #76fe77;
  position: relative;
  margin-top: 70px;
}

CleanShot 2022-05-29 at 18.24.04@2x.png

Absolute

The absolute element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to its closest positioned ancestor, if any; otherwise, it is placed relative to the initial containing block. Its final position is determined by the values of top, right, bottom, and left.

The containing block in which the root element () resides is a rectangle called the initial containing block.

This value creates a new stacking context when the value of z-index is not auto. The margins of absolutely positioned boxes do not collapse with other margins.

If we put the put the "absolute" to the child1, it does not generate any space that it disappears immediately.

.parent {
  background-color: #0fa9f8;
  padding: 20px;
}

.child1 {
  background-color: #76fe77;
  position: absolute;
}

.child2 {
  background-color: #f37574;
  position: relative;
}

.child3 {
  background-color: #f575e7;
  position: relative;
}

image.png

If we add the set top to 0 we see the following.

.child1 {
  background-color: #76fe77;
  position: absolute;
  top: 0px;
}

image.png The child1 appears as 0 distance from its Nearest Relative Positioned Ancestor. In this case, it's the initial containing block . The size of child1 is changed because child1 as the block element its size was determined by its parent. After it jumps out of the control of its parent its size is determined by its content

More on Absolute

How about if we add another parent and put it as absolute positioned? Here is the effect.

  <body>
   <div class="parent">
      Parent
      <div class="child child1">
        Child1
      </div>
      <div class="child child2">
        Child2
      </div>
      <div class="child child3">
        Child3
      </div>
    </div>

    <div class="parent2">Parent2</div>

  </body>
.parent2 {
  position: absolute;
  background-color: #f3d574;
  border-style: solid;
  padding: 20px;
  margin-top: 50px;
}

image.png

The parent2 looks for its Nearest Relative Positioned Ancestor, in this case it is the element. If we do not set the top, right, bottom, and left, it has the similar effect to "static" except the size is changed. If we add "right: 20px" we see it moves to the top right corner.

.parent2 {
  position: absolute;
  background-color: #f3d574;
  border-style: solid;
  padding: 20px;
  margin-top: 50px;

  top: 0px;
  right: 20px;
}

image.png

There is a good article describing the concept Nearest Relative Positioned Ancestor clearly.

Fixed

The fixed element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none (see the CSS Transforms Spec), in which case that ancestor behaves as the containing block. (Note that there are browser inconsistencies with perspective and filter contributing to containing block formation.) Its final position is determined by the values of top, right, bottom, and left.

The fixed is set to be fixed to the viewpoint. To illustrate the effect, we enlarge the parent to 2 times of screen size. And set the child1 to be in the fixed position.

.parent {
  background-color: #0fa9f8;
  border-style: solid;
  padding: 20px;
  margin-top: 50px;
  height: 200vh;
}
.child1 {
  background-color: #76fe77;
  position: fixed;
  top: 0px;
  z-index: 100;
}

CleanShot%202022-05-29%20at%2017.04.56.gif

Sticky

The sticky element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), including table-related elements, based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements.

The sticky element is the similar to "fixed" except it retain in the "relative" position and when users scroll the screen bar it is sticky to the view point. Here is the effect.

.child1 {
  background-color: #76fe77;
  position: sticky;
  top: 0px;
  z-index: 100;
}

CleanShot%202022-05-29%20at%2017.17.49.gif

Conclusion

To summarize it, we discussed the different effects of different values in the "position" attribute. Once I have this in my mind I could continue the web development learning journey. And hopefully it can help others.

Reference