CSS – display: flex and position: absoulte moves anchor point

I have a flex element and three children. The second child should overlap the first using position absolute, like this:

Expected:

Expected

Note that the second child should be on top of the first child, not next to it.

However, setting display: flex on the parent seems to shift the anchor or reference point of the absolute element to start of the div. The actual outcome is this:

Actual result:

Actual

Putting the second child in the first or third element is not an option, because they have overflow: scroll. So is using any other display property on the parent, because my layout relies on display: flex. I know these solutions have been suggested on other posts, however, I have not found a question/answer that addresses the problem with these constraints.

It would be okay to use something else but display: absolute on the second child, like a negative margin, but I couldn’t get this to work either.

If anyone knows if this is even possible or has any suggestions it would be greatly appreciated.

To see it in action here is my code, simplified to demonstrate the issue:

body{
  color: white;
}
.wrapper{
  display: flex;
}
.wrapper .a{
  background-color: blue;
  flex-grow: 1;
}
.wrapper .b{
  position: absolute;
  background-color: rgba(255, 0, 0, 0.5);
  min-width: 40px;
}
.wrapper .c{
  background-color: green;
  min-width: 40px;
}
<div class="wrapper">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</div>

>Solution :

It appears to the left of your div because it’s been taken out of the flow of the document. In fact, it’s actually positioned relative to the viewport and not the parent wrapper. To make it positioned to the wrapper, set position: relative to the wrapper class to create a new containing block

To ensure it overlaps the end of div ‘a’ I’ve used the ‘right’ property to move the right hand edge leftwards by a value that I’ve set usnig a custom property that I’ve set to both that and div ‘c’. See annotated example below.

.wrapper {
  position: relative;
  display: flex;
  color: white;
  --element-c-width: 40px; /* set this to both set the width of div 'c' and how far we move div 'b' leftwards */
}

.a {
  background-color: blue;
  flex-grow: 1;
}

.b {
  position: absolute;
  background-color: rgba(255, 0, 0, 0.5);
  min-width: 40px;
  right: var(--element-c-width); /* from the right hand side of the wrapper div, move it leftwards by this value */
}

.c {
  background-color: green;
  min-width: var(--element-c-width);
}
<div class="wrapper">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c">C</div>
</div>

Leave a Reply