How to position-absolute a div only vertically?

Viewed 219

I have a flex-row of elements (e.g. two lines with flex-wrapped). When I click one of those elements a popup (green box) should be opened directly under this element (that's why I need an absolute positioning) and those popups should all have the same width (independent of which element is clicked).

The problem is since this absolute positioned div starts just under the clicked element, the starting point of this popup also varies on the x-axis. But I want all the popups start at the same point horizontally.

https://jsfiddle.net/h8f73Lpm/24/

This is what I currently have: enter image description here

This is what I want to achieve, when I click on an element in the first row: enter image description here

.. and when i click on an element on the second row: enter image description here

This is a simplified version of my situation. Since we also have to consider the responsiveness the actual number of rows and elements vary. I would prefer a css-only solution.

.flexlist {
  display: flex;
  flex-wrap: wrap;
  max-width: 700px;
}

.entry {
  position: relative;
  min-width: 96px;
  height: 100px;
  border: 1px solid red;
  margin: 1px;
}

.selected {
  background: red;
}

.absolute {
  position: absolute;
  left: 0;
  top: 100%;
  width: 300px;
  background: green;
  z-index: 1;
  height: 80px;
}
<div class="flexlist">
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry selected">
    <div class="absolute"></div>
  </div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
</div>

1 Answers

should be opened directly under this element (that's why I need an absolute positioning)

Can be achieve without position:absolute

Here is an idea using CSS grid where you add the pop-up element after the selected one not inside it:

.flexlist {
  display: grid;
  grid-template-columns:repeat(auto-fit,minmax(96px,1fr));
  grid-auto-flow:dense; /* this is important for the trick and will give the correct placement */
  max-width: 700px;
  margin:20px;
}

.entry {
  height: 100px;
  border: 1px solid red;
  margin: 1px;
}

.selected {
  background: red;
}

.pop-up {
  z-index:2;
  grid-column:1/-1; /* full width */
  height: 0; /* take 0 height similar to position:absolute */
}
.pop-up > div {
  background: rgba(0,128,0,0.8);
  height:80px;
}
<div class="flexlist">
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry selected"></div>
    <div class="pop-up">
      <div></div>
    </div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
</div>

<div class="flexlist">
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry "></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry selected"></div>
    <div class="pop-up">
      <div></div>
    </div>
  <div class="entry"></div>
  <div class="entry"></div>
</div>

<div class="flexlist">
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry "></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry selected"></div>
    <div class="pop-up">
      <div></div>
    </div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
  <div class="entry"></div>
</div>

Related