Home  >  Q&A  >  body text

CSS - anchor point move display:flex and position:absolute

I have a Flex element and three child elements. The second child should overlap the first child using absolute positioning like this:

expected:

Note that the second child should be above the first child, not next to it.

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

actual results:

Putting the second child element inside the first or third element is not an option because they have overflow:scroll. The same goes for using any other display properties on the parent, since my layout relies on display: flex. I know these solutions have been suggested in other posts, however, I haven't found a question/answer that addresses these limitations.

Using something other than display:absolute on the second child also works, like negative margins, but I can't get it to work either.

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

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

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>

P粉252116587P粉252116587202 days ago466

reply all(2)I'll reply

  • P粉426906369

    P粉4269063692024-03-30 21:42:53

    Add position:relative; to the parent

    When an element is given the position:absolute; attribute, it will be targeted via relative, absolute, or fixed positioning The closest parent element is positioned. If not found, it will target body. In this case, you may want to add position:relative; to the .wrapper element since it is the reference point for absolute positioning.

    Add positioning value to element

    By definition, position:absolute; elements will be positioned absolutely using a specific set of values ​​. That is, how far away from the top, right, bottom, or/and left edge. When you don't provide any value, it just sticks to the top left corner, which is what's happening here.

    Need to set a positioning value

    position:absolute; Get an element from the normal content flow. That is, the elements surrounding it do not affect its size or position; therefore absolute positioning. To achieve the effect shown in the image, you need to specify the width of the .c element and position the .b element from the right edge using the same exact value.

    See the code snippet below for reference.

    body{
      color: white;
      --width: 80px;
    }
    .wrapper{
      display: flex;
      position: relative;
    }
    .wrapper .a{
      background-color: blue;
      flex-grow: 1;
    }
    .wrapper .b{
      position: absolute;
      right: var(--width);
      background-color: rgba(255, 0, 0, 0.5);
      min-width: 40px;
    }
    .wrapper .c{
      background-color: green;
      width: var(--width);
    }
    A
    B
    C

    reply
    0
  • P粉451614834

    P粉4516148342024-03-30 20:39:34

    It appears on the left side of the div because it has been taken out of the flow of the document. In fact, it's actually positioned relative to the viewport rather than the parent wrapper. To position it to the wrapper, set position:relative to the wrapper class to create a new containing block

    To make sure it overlaps the end of the div 'a', I used the 'right' property to move the right hand edge to the left by the value I set Custom property that I set to that property and div 'c'. See the 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);
    }
    A
    B
    C

    reply
    0
  • Cancelreply