Shinji-san
Shinji-san

Reputation: 1001

Vertical centering with relative and absolute positioning in flexbox

I'm using absolute and relative positioning for my .box, but as you can see the text doesn't seem like it's top: 100%.

Can someone explain why this is?

Like why is the text (some text is going here) spilling into the child element when top: 100% was specified?

.box {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  height: 200px;
  margin: 0 auto;
  width: 90%;
  border: 1px solid red;
}
.child {
  position: relative;
  width: 100px;
  height: 100px;
  border: 1px solid orange;
}
.childschild {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<div class="box">
  <div class="child">
    <img src="dog1.jpg" alt="Picture of a dog" width="250" height="250">
    <div class="childschild">
      some text is going here
    </div>
  </div>
  <div class="child">dfd</div>
  <div class="child">dfd</div>
</div>

Upvotes: 1

Views: 154

Answers (3)

dippas
dippas

Reputation: 60603

The problem is because in your transform you are applying -50% to Y-axis , which means will subtract that 50% from top:100%, So it will be has it you stated just top:50% with no transform

Either you only apply the transform to X-axis removing the Y-axis, as stated by @Michael_B, or you can use this code below to vertically/horizontally center the text just below the box:

position: absolute;
top: 100%;
right: 0;
left: 0;
margin: auto

Note: I changed your img to background-img (optional)

.box {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  height: 200px;
  margin: 0 auto;
  width: 90%;
  border: 1px solid red;
}
.child {
  width: 100px;
  height: 100px;
  border: 1px solid orange;
}
.box > div:first-of-type {
  background: url("//dummyimage.com/100x100");
  position: relative
}
.box > div:first-of-type div {
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  margin: auto;
  width: 50px;
  text-align:center;
  background:red
}
<div class="box">
  <div class="child">
    <div>some text is going here</div>
  </div>
  <div class="child">dfd</div>
  <div class="child">dfd</div>
</div>

Upvotes: 1

Michael Benjamin
Michael Benjamin

Reputation: 372244

.. why is the text ('some text is going here' text) spilling into the child element when 100% was specified?

Because you've applied the transform property to the element:

.childschild { transform: translate(-50%, -50%); }

This tells the element to shift backward 50% of its width along the x-axis and 50% of its height along the y-axis.

So first you're telling it to be top: 100%. Then you're telling it to backtrack 50% of its height, which puts it back over the .child element. You can remove the transform and it will work as intended.

Try this instead: transform: translateX(-50%); (demo)

A more complete explanation with illustrations can be found here:

Upvotes: 1

Stefan Đorđević
Stefan Đorđević

Reputation: 595

If i understood you correctly, this could help you..

Try using margin-top: -10px;, it will reduce top's space by 10px. You can also try marign-left,margin-right and margin-bottom.

Upvotes: 0

Related Questions