Home > Software engineering >  Position a dynamically sized div at the bottom of another dynamically sized div
Position a dynamically sized div at the bottom of another dynamically sized div

Time:10-25

I'm trying to create a UL that will have LI items added to it dynamically.

The goal is for the list to have zero height when empty, then expand up to a certain height as items are added to the list, and have a max-height set so that if the list grows beyond a certain height then all the older items get hidden by overflow: hidden.

So the most recent items, at the bottom of the list, should always be visible, while the older items get bumped upwards and eventually out of visibility.

I can get most of the way there by wrapping the UL in a container DIV, setting a fixed height for the div, and then setting the UL to position: absolute and the container div to position: relative.

But if I set a fixed height for the container div, then when the list has no items it still has a big empty gap between the interface items that go above and below the list.

In order to not look weird I'll need the list (and its container div) to size the height dynamically as the list grows, and then cap the growth at a max-height setting.

But if I remove the fixed height for the container div, it sets the height for that div to zero pixels because the UL is set to position: absolute, and as such the list doesn't display at all (as the entire list is considered to be overflow within a zero-height div).

This seems like a fairly common thing for people to try to achieve, but I can't seem to find any solution that doesn't involve setting a fixed height.

Code example...

HTML:

<div id="above_list">This should be touching the below_list div when the list is empty</div>
<div id="list_container">
    <ul>
        <li>Item 1
        <li>Item 2
        <li>Item 3
        <li>Item 4
        <li>Item 5
    </ul>
</div>
<div id="below_list">This should be touching the above_list div when the list is empty, and should get farther away from the above_list div as <li> items are added to the list

CSS:

#list_container {
    position: relative;
    max-height: 100px;
    overflow: hidden;
}

ul {
    position: absolute;
    bottom: 0;
}

In the above code example the container div displays with zero height even if the list has a bunch of list items.

I'll need the container div to display with zero height only when the list has no items. Then the container div should grow in height as items are added to the list, and should stop growing if the list gets above a certain height.

The list needs to be positioned at the bottom of the container div, so that if the list starts to overflow beyond the container div's max-height then instead of hiding the newer list items below the bottom of the div, it should push the older list items up above the top of the div. (So the top of the UL is treated as overflow, instead of the bottom of the UL being treated as overflow.)

CodePudding user response:

Use a flex column and the justify the content to the flex end.

No need to a wrapping div at all unless required for other reasons.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

 ::before,
 ::after {
  box-sizing: inherit;
}

ul {
  max-height: 150px;
  overflow: hidden;
  border: 1px solid grey;
  list-style: none;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
<div id="above_list">This should be touching the below_list div when the list is empty</div>
<div id="list_container">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
    <li>11</li>
    <li>12</li>
  </ul>
</div>
<div id="below_list">This should be touching the above_list div when the list is empty, and should get farther away from the above_list div as items are added to the list
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Example with no list items : https://codepen.io/Paulie-D/pen/vYJgPEY

  • Related