DEV Community

machy44
machy44

Posted on

CSS... I had a problem with positioning

The problem which I had is that I couldn't get the loading spinner in the center of the table element. But in this post, we will play with div elements. I have thought that I understand positioning but it was evident that I don't. It was so frustrating that I decided to share this with you. The Example will be pretty simple. When I say centering an element in the post I think of vertical and horizontal centering.

Let's see how is the positioning defined in CSS theory. There are five different element positioning in CSS (static, relative, fixed, absolute, sticky). But I had a problem with relative and absolute positioning and we will take focus on these two.

Positioning in theory

The default positioning of every HTML element is the static position.

It is always positioned by the normal flow of the page.

source: https://www.w3schools.com/css/css_positioning.asp

What is normal flow?

In normal flow, block boxes are positioned on a page one after the other (in the order they're written in the HTML). They start in the upper left of the containing box and stack from top to bottom. The distance between each box is defined by the margins with top and bottom margins collapsing into one another.

source: https://www.thoughtco.com/normal-flow-definition-3467023

At relative positioning, the element is positioned relative to its normal position.

At absolute positioning element is positioned relative to the nearest positioned ancestor.

source: https://www.w3schools.com/css/css_positioning.asp

Next thing is that I used the bootstrap grid system.
Ok... now when we know theoretically how the listed positions behave we can go to an example.

Let's see a Code

On smashing magazine article I found the code for centering an element with absolute position.

Here's the code:

margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;

But in the link to my Codepen you can see that loading spinner isn't behaving like I thought it would.

Ahh.. It is not centered in my .parent div!

The loading spinner is set up in the middle of .grand-parent. Why?

If you inspect the Bootstrap column you can see that it's position is set to relative, unlike my .parent element.Now, Let's define relative position to .parent element

The element with the absolute position is looking for the first ancestor which position is not static. What? I had no idea about that. The Parent didn't have a position relative and that is the reason for the first behavior. Aha!! That's the point.

Absolute position is looking all the way up in the hierarchy for the first relative ancestor (in this case) and if it doesn't exist it will get the document body which is relatively positioned by default.

If you try to resize the browser window the loading spinner will always be in the middle of the parent element.

Conclusion

I took bootstrap columns for granted and didn't look at anything in the background. We always need to know that there is no magic in the background and we need to try to understand why something behaves the way it does.

Always try to understand what you read and try to learn by doing stuff.

P.S. If I missed something important or showed CSS has some weaknesses or there is a better solution, you are more than welcome to commment or share some links. In the end, we are here to try to teach and to be taught.

Now go hard for the new knowledge!!!

Top comments (4)

Collapse
 
mbtts profile image
mbtts

Nicely written article and well explained.

Apologies if already familiar, but another solution for centring vertically and horizontally is using flex box:
css-tricks.com/snippets/css/a-guid...

One benefit is the loader ruleset does not need to declare any positioning rules - instead it infers its location from the rules defined in the parent (specifically justify-content (vertical in this case) and align-items (horizontal in this case)).

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  height: 80%;
  width: 70%;
  background-color: #E37222;
}

.loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  width: 80px;
  height: 80px;
  -webkit-animation: spin 2s linear infinite; /* Safari */
  animation: spin 2s linear infinite;
}

There is a game here for learning flexbox: flexboxfroggy.com/.

Collapse
 
machy44 profile image
machy44 • Edited

No need for apologies :)..thank you for your solution. I played flexboxfroggy and I think that it's awesome for learning flex. I can't remember why I didn't use it but there must be some reason :D.

Collapse
 
blouzada profile image
Bruno Louzada

Nice post! Another great post is CSS box model

Collapse
 
machy44 profile image
machy44

Thank you..That's a great idea, I will consider it and try to explain on some practical problem