Why is my element joining its sibling? aka overflow: hidden on parent breaks left: 50% on children

Here's a quick explanation of my diagram (shown below): The
yellow box is the parent.
The black and blue boxes are the children of the yellow box.
The excessive blue box is hidden from him by the parent throughoverflow: hidden

Since the overflow: hidden

breaks margin: auto

, I tried to center the black box to its parent (i.e. yellow box) with left: 50%

. However, the black box is aligned to the width of the blue rectangle.

Can anyone please explain another way so that I can align the black box with the width of my parent? I would accept an answer that fixes it margin: auto

.

Here is my code:

.yellow-box {
    display:table-cell;
    height:498px;
    width:33.33333333%;
    overflow:hidden;
    position:relative;
}

.cyan-box {
    display:block;
    height:auto;
    position:absolute;
    z-index:1;
    top:0;
    left:0;
    width:654px;
    height:654px;
}

.black-box {
    width:144px;
    height:84px;
    position:absolute;
    z-index:2;
}

      

http://i.imgur.com/EDhFtEU.png

+3


source to share


1 answer


What a fantastic optical illusion you accidentally created!

Indeed, it left: 50%

works great. While it .black-box

does matter .cyan-box

, it actually left: 50%

moves the left side .black-box

- and not the center, as you would expect, to the middle .yellow-box

. The fix is ​​easy by adding transform: translate(-50%);

to .black-box

. This moves it .black-box

back 50% of its width, which really centers it on its parent.

.black-box {
  width: 144px;
  height: 84px;
  position: absolute;
  z-index: 2;
  background: black;
  left: 50%;
  transform: translate(-50%);
}
.yellow-box {
  height: 498px;
  width: 33.33333333%;
  position: relative;
  background: yellow;
  margin-bottom: 20px;
}
.cyan-box {
  display: block;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 654px;
  height: 654px;
  background: cyan;
}
.half {
  width: 50%;
  border-right: 1px black solid;
  height: 100%;
}
      

<div class="yellow-box">
  <div class="black-box">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
      

Run codeHide result


The illusion is broken when the page is resized. I added a line down the center so you can see the middle .yellow-box

.

Here's an example comparing the difference.

.yellow-box {
  height: 100px;
  width: 33.33333333%;
  position: relative;
  background: yellow;
  margin-bottom: 20px;
}
.cyan-box {
  display: block;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 654px;
  height: 100px;
  background: cyan;
}
.black-box {
  width: 144px;
  height: 84px;
  position: absolute;
  z-index: 2;
  background: black;
  left: 50%;
}
.black-box-two {
  width: 144px;
  height: 84px;
  position: absolute;
  z-index: 2;
  background: black;
  left: 50%;
  transform: translate(-50%);
}
.half {
  width: 50%;
  border-right: 1px black solid;
  height: 100%;
}
* {
  margin: 0;
  padding: 0;
}
      

<div class="yellow-box">
  <div class="black-box">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
<div class="yellow-box">
  <div class="black-box-two">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
      

Run codeHide result




So .black-box

it doesn't really match it, it looks like this.

If you want to use margin: 0 auto

, you need to use position: relative

on .black-box

. Absolutely positioned items are not affected by margin.

.yellow-box {
  height: 498px;
  width: 33.33333333%;
  position: relative;
  background: yellow;
  margin-bottom: 20px;
  overflow: hidden;
}
.cyan-box {
  display: block;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 654px;
  height: 654px;
  background: cyan;
}
.black-box {
  width: 144px;
  height: 84px;
  position: relative;
  z-index: 2;
  background: black;
  margin: 0 auto;
}
.half {
  width: 50%;
  border-right: 1px black solid;
  height: 100%;
}
      

<div class="yellow-box">
  <div class="black-box">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
      

Run codeHide result


If you use position: relative

instead position: absolute

, the fields take effect again. You can even use the top

, right

, bottom

and left

if you want it.

Here's an example contrasting with the two working solutions with the code you provided (left is used transform: translate(-50%)

, middle is source and right is uses margin: 0 auto

).

.yellow-box {
  height: 100px;
  width: 30%;
  position: relative;
  background: yellow;
  margin-bottom: 20px;
  overflow: hidden;
}
.cyan-box {
  display: block;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 654px;
  height: 100px;
  background: cyan;
}
.black-box {
  width: 144px;
  height: 84px;
  position: relative;
  z-index: 2;
  background: black;
  margin: 0 auto;
}
.black-box-two {
  width: 144px;
  height: 84px;
  position: absolute;
  z-index: 2;
  background: black;
  left: 50%;
  margin: 0 auto;
}
.black-box-three {
  width: 144px;
  height: 84px;
  position: absolute;
  z-index: 2;
  background: black;
  left: 50%;
  transform: translate(-50%);
}
.half {
  width: 50%;
  border-right: 1px black solid;
  height: 100%;
}
* {
  margin: 0;
  padding: 0;
}
body {
  display: flex;
  justify-content: space-between;
}
      

<div class="yellow-box">
  <div class="black-box">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
<div class="yellow-box">
  <div class="black-box-two">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
<div class="yellow-box">
  <div class="black-box-three">
  </div>
  <div class="cyan-box">
  </div>
  <div class="half"></div>
</div>
      

Run codeHide result


+1


source







All Articles