Position Questions

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .heart {
          position: absolute;
          margin: auto;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          background-color: pink;
          height: 50px;
          width: 50px;
          transform: rotate(-45deg) ;
        }
        .heart::after {
          background-color: pink;
          content: "";
          border-radius: 50%;
          position: absolute;
          width: 50px;
          height: 50px;
          top: 0px;
          left: 25px;
        }
        .heart::before {
          content:"" ;
          background-color: pink;
          border-radius: 50%;
          position: absolute;
          width: 50px;
          height: 50px;
          top: -25px;
          left: 0px;
        }
      </style>
</head>
<body>
    <div class="heart"></div>
</body>
</html>

What are the parameters that place the heart at the center of the page in the vertical dimension? Is it the margin: auto line? We also have 3 position: absolute lines. I thought that whenever these are used, there has to be something with position: relative to position the absolute entities against

@ttibsen What is your problem?

Hi @ttibsen!

I have edited your post to move your question out of the comments in the html to the body of your post.

Absolute positioning and setting both top and bottom to 0.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .heart {
          position: absolute;
          margin: auto;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          background-color: pink;
          height: 50px;
          width: 50px;
        }

        
      </style>
</head>
<body>
    <div class="heart"></div>
</body>
</html>

I have reduced the previous code to this one which contains only 1 element because I am clueless as to the positioning concept presented here and perhaps with the simplicity of only dealing with a single element, I may get enlightened.
I am having a lot of difficulty in sorting out what does what in this code.
I realize that the code, as written, places the square in the center of the page - in both the H and V dimensions.
I thought that margin: auto by itself would do this but no - with margin: auto the square is centered at the top of the page.
So I guess the question becomes - how do
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
act to get the square into the middle of the browser window? Are the top, right, bottom, left margin values? If they are, why are they needed if margin is already set to auto? I need to get straightened out with this stuff. Thanks.

An absolutely positioned element means it behaves individually regardless how the others do. So “margin: auto” set to them will be naturally ignored.

You are not the first to ask about how it actually works. Here is an old smashing magazine article which talks about it.


It’s in my opinion a slightly confusing way of doing centering and I might prefer if it was using a more traditional method (top/left offset + transform: translate).

.heart {
  position: absolute;
  top: 50%;
  left: 50%;
  background-color: pink;
  height: 50px;
  width: 50px;
  transform: translate(-50%, -50%) rotate(-45deg);
}

One guess I might make as to why it was picked is to avoid having to “chain” transform functions as that might be confusing as well (translate() has to happen before rotate() and adding it might make it less clear what the transform is doing, i.e. the rotation part).

Also, just as an aside, this technique is not even posted in the css-tricks article on centering (as far as i can tell).

I don’t think I understand your response - are you saying that
these 2 lines of code
position: absolute;
margin: auto;
are incompatible?

This is tricky and a very good question.

  1. when you give position: absolute; its position is relative. In this case to body tag.
  2. when you set top: 0, right: 0, bottom: 0, left: 0, than it automatically had width and height as big as the screen.
  3. when you set the width and height, than it is automatically will be place at the center.

I suggest you play with dev console or codepen.io
I learn something from this too.
Thanks.

1 Like

Great article in Smashing Magazine - I just coded for a very simple schematic to test out their path to perfectly centering the blue div and it doesn’t seem to work. Why not? Here is the code -

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Stephen Shaw introduces a technique for perfect horizontal and vertical centering in CSS</title>
  <style>
    body  {
      width: 500px;
      height: 700px;
      border: black 4px solid;
    }
    div {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50px;
      height: 70px;
      background-color: rgb(36, 139, 230);
    }
    h1   {
      text-align: center;
    }
  </style>
</head>
<body>
  <h1>The Blue Box</h1>
  <div></div>
</body>
</html>

You are centering the content inside the div, not the div itself. To center the div you have to make its parent container a flex container and set the properties for centering on the container.

Centering using flex/grid depends on the dimensions of the container. The child will be centered inside the parent relative to the parent dimensions.

For block-level elements centering horizontally is simple enough because they are already full width. In fact, for centering horizontally you can just set a left/right auto margin on the child and it will center horizontally without using flex/grid.

For vertical centering, the height of the container will determine where the center is and the height of containers is usually governed by the content. You can explicitly set the height using viewport units, or when using percentages, propagate the height down through all elements starting from the root element.


<div class="container">
  <div class="box"></div>
</div>

Centering horizontally (without flex/grid):

.box {
  height: 80px;
  width: 80px;
  background: orange;
  margin: 0 auto;
}

Centering horizontal/vertical using viewport units to set the height.

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.box {
  height: 80px;
  width: 80px;
  background: orange;
}

Centering horizontal/vertical by propogating the height down:

html, body {
  height: 100%;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.box {
  height: 80px;
  width: 80px;
  background: orange;
}

In both cases using justify-content: center on the parent container or an auto margin on the child element works for horizontal centering.

Thank you for taking the time to go through such a detailed explanation and I certainly intend to spend a couple of hours going through the examples provided. I was testing out the very first example and see what using different margin commands and values would do on this very basic example and got stuck right away with this code -

    <style>
        .box {
            height: 80px;
            width: 80px;
            background: orange;
            margin-left: 60 px;
        }
    </style>

I thought I would get a 60px gap on the LS of the box but no, it didn’t move. So that is kind of discouraging as I think it should have.

It looks like you have a space between 60 and px.

Thanks for pointing that out - I didn’t think the space made any difference - now I know that it does🙃

Yes, as a best practice, you should never mix position: absolute with <some-property>: auto. Because the value auto implies that it’s calculated “auto”-matically based on the “environment” it belongs to, while absolute suggests the opposite way, which is to ignore anything that could possibly cause any effect to it.