Alexander Solonik Alexander Solonik - 5 months ago 11
CSS Question

Absolute positioning :after and transforming it not aligning it in center

Hey guys I had to create simple dots on a carousel like so:

enter image description here

And hence I used the following method:

.banner-nav-dots > li > a {
position: relative;
}

.banner-nav-dots > li.active > a:after {
content: '';
background: #6e2c91;
height: 5px;
width: 5px;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
-o-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
border-radius: 50%;
}


Now that should have really centered the dot , but as can be seen on THIS LINK, they are not exactly aligning in the center. Why? Why are they not aligning in the center?

Below is a MVCE:



.circle {
position: relative;
box-sizing: border-box;
display: inline-block;
border: 2px solid #6e2c91;
border-radius: 50%;
height: 15px;
width: 15px;
}
.circle:after {
position: absolute;
content: '';
display: inline-block;
height: 5px;
width: 5px;
top: 50%;
left: 50%;
border-radius: 50%;
background: #6e2c91;
transform: translate(-50%, -50%);
}

<div class='circle odd-numbered'></div>





I am more interested in the WHY part. Can somebody explain please?

P.S. this absolute position method combined with transform has always worked for me, but just on this instance its caused this issue and I don't know why. Checked both in FF and Chrome.

Answer

The problem seems to be due to a combination of odd numbered dimensions for parent container (height: 15px, width: 15px) and the 50% value for positioning attributes on child (top: 50%, left: 50%). This means that the actual calculated value will be 5.5px ((15px - 4px) / 2) for left and top (15px - 4px due to box-sizing: border-box also being applied on the parent).

When such fractional values are encountered, it looks like the browsers round-off the value. I couldn't find anything about this in the specs (whether it should be a round-up or down) and there aren't many recent articles on the net also about this particular thing. However, I did manage to find this old article which says that each browser treats them differently. Some round it down whereas others round it up. Either ways, the child element is not going to at the exact center.

The fix for this case seems to be to set an even-numbered value for the parent's dimensions.

.circle {
  position: relative;
  box-sizing: border-box;
  display: inline-block;
  border: 2px solid #6e2c91;
  border-radius: 50%;
}
.odd-numbered {
  height: 15px;
  width: 15px;
}
.even-numbered {
  height: 16px;
  width: 16px;
}
.circle:after {
  position: absolute;
  content: '';
  display: inline-block;
  height: 5px;
  width: 5px;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  background: #6e2c91;
  transform: translate(-50%, -50%);
}
<h4>Odd Numbered Dimensions - PROBLEM </h4>

<div class='circle odd-numbered'></div>

<h4>Even  Numbered Dimensions - NO PROBLEM </h4>

<div class='circle even-numbered'></div>

Comments