Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to apply dynamic height on div - Timeline view

I'm trying to build an horizontal timeline. There can be many events on any given day of a month.

So, when the events are more, the list items are unable to accommodate the available height(from: min-height) and a vertical scroll is appearing.

If I try removing the min-height whole content is distorted. I want the container to occupy the list with any number of items without vertical scroll.

Also, there is one more issue, when the window is small(can be seen on codepen), the horizontal scroll appears(expected and needed). But, the connector is not occupying the whole scroll width.

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

.timeline__container {
  background: #c0ffee;
  overflow-x: auto;
  display: flex;
  position: relative;
}
.timeline__connector {
  position: absolute;
  width: 100%;
  left: 0;
  top: calc(50% - 4px);
  height: 8px;
  background: #ccc;
}
.timeline__item {
  background: gold;
  min-width: 85px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.timeline__item:nth-child(2n) {
  flex-direction: column-reverse;
}
.timeline__up {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.timeline__down {
  height: 100%;
  display: flex;
}
.timeline__month {
  -webkit-transform: rotate(-90deg);
          transform: rotate(-90deg);
  display: inline-block;
}
.timeline__month-up {
  margin-bottom: 20px;
  align-self: flex-end;
}
.timeline__month-down {
  align-self: flex-start;
  margin-top: 20px;
}
.timeline__count {
  margin: auto;
}
.timeline__count-up {
  margin-bottom: 20px;
}
.timeline__count-down {
  margin-top: 20px;
}
.timeline__item-event {
  min-width: 180px;
}
.timeline__event__list {
  height: 100%;
}
.timeline__event__list ul {
  margin-left: 20px;
}
<div class="timeline__container">
  <div class="timeline__connector"></div>
  <div class="timeline__item">
    <div class="timeline__up">
      <div class="timeline__month timeline__month-down">JAN</div>
    </div>
    <div class="timeline__down">
      <div class="timeline__count timeline__count-up">5</div>
    </div>
  </div>
  <div class="timeline__item">
    <div class="timeline__up">
      <div class="timeline__month timeline__month-up">FEB</div>
    </div>
    <div class="timeline__down">
      <div class="timeline__count timeline__count-down">15</div>
    </div>
  </div>
  <div class="timeline__item timeline__item-event">
    <div class="timeline__up">
      <div class="timeline__event__list">
        <div class="timeline__date">5th</div>
        <ul>
          <li>Lorem ipsum</li>
          <li>Lorem ipsum</li>
          <li>inventore nihil sint est.</li>
          <li>Lorem ipsum dolor sit</li>
          <li>dolor sit</li>
        </ul>
      </div>
    </div>
    <div class="timeline__down">
<!--       <div class="timeline__count timeline__count-up">5</div> -->
    </div>
  </div>
  <div class="timeline__item timeline__item-event">
    <div class="timeline__up">
      <div class="timeline__event__list">
        <div class="timeline__date">15th</div>
        <ul>
          <li>Lorem ipsum</li>
          <li>Lorem ipsum</li>
          <li>inventore nihil sint est.</li>
          <li>Lorem ipsum dolor sit</li>
          <li>dolor sit</li>
        </ul>
      </div>
    </div>
    <div class="timeline__down">
      
    </div>
  </div>
  <div class="timeline__item timeline__item-event">
    <div class="timeline__up">
      <div class="timeline__event__list">
        <div class="timeline__date">25th</div>
        <ul>
          <li>Lorem ipsum</li>
          <li>Lorem ipsum</li>
          <li>dolor sit</li>
        </ul>
      </div>
    </div>
    <div class="timeline__down">      
    </div>
  </div>
</div>

Codepen for the same

like image 448
Raviteja Avatar asked Apr 16 '19 10:04

Raviteja


People also ask

Why does my div have no height?

The reason why the height or the containers is 0 is because you are floating all the content inside them and floated elements don't expand the height (or width) of their parents.

How set dynamic width and height in CSS?

Top header with 100% width and 50px height. Left navigation bar with 200px width and dynamic height to fill the screen. A container on the right of the nav bar and under the header with dynamic width and height to fill the screen.


1 Answers

I have come up with an idea to combine flex and grid to achieve what you are looking for.

There is a snipped added and I tried to keep the code as clean as possible, added comments on some of them so the code can talk for itself. Didn't change the DOM structure at all. But wait, look at this:

Also, there is one more issue, when the window is small(can be seen on codepen), the horizontal scroll appears(expected and needed). But, the connector is not occupying the whole scroll width.

To solve the above, I wrapped the .timeline__container into a .timeline__wrapper. removed position: relative; from .timeline__container. And added position: relative; to .timeline__wrapper.

There are enough comments on the code, so when you go through this, you should be able to understand. You can research the grid properties used here to understand actually how this was accomplished.

Also I added a little padding on the timeline up/down classes to ignore the visual conflict with the connector (or the grey line)

Feel free to add/remove list items so that the height of the timeline items increase/decrease, and you can check if this is what was expected.

Almost forgot to mention, this works fine on safari too.

Snippet finally:

* {
  /* you can ignore the pseudo elements here */
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.timeline__wrapper {
  position: relative;
  /* to fix the timeline connector */
}

.timeline__container {
  background: #c0ffee;
  overflow-x: auto;
  /* element with an overflow can't display an absolute positioned element, that's why the wrapper up there */
  display: flex;
}

.timeline__connector {
  position: absolute;
  width: 100%;
  left: 0;
  top: calc(50% - 4px);
  height: 8px;
  background: #ccc;
}

.timeline__item {
  background: gold;
  min-width: 85px;
  justify-content: center;
  display: grid;
  grid-auto-flow: row;
  grid-auto-rows: 1fr;
  /* this keeps the upper and lower portion same height */
}

.timeline__item:nth-child(2n) .timeline__down {
  /* these styles reverses the expected rows */
  grid-row-start: 2;
  grid-row-end: 1;
}

.timeline__up {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 10px;
}

.timeline__item:nth-child(2n) .timeline__up {
  align-items: flex-start;
}

.timeline__down {
  display: flex;
  align-items: flex-start;
  padding: 10px;
}

.timeline__month {
  -webkit-transform: rotate(-90deg);
  transform: rotate(-90deg);
  display: inline-block;
}

.timeline__month-up {
  margin-bottom: 20px;
  align-self: flex-end;
}

.timeline__month-down {
  align-self: flex-start;
  margin-top: 20px;
}

.timeline__count {
  margin: auto;
}

.timeline__count-up {
  margin-bottom: 20px;
}

.timeline__count-down {
  margin-top: 20px;
}

.timeline__item-event {
  min-width: 180px;
}

.timeline__event__list ul {
  margin-left: 20px;
}
<div class="timeline__wrapper">
  <div class="timeline__container">
    <div class="timeline__connector"></div>
    <div class="timeline__item">
      <div class="timeline__up">
        <div class="timeline__month timeline__month-down">JAN</div>
      </div>
      <div class="timeline__down">
        <div class="timeline__count timeline__count-up">5</div>
      </div>
    </div>
    <div class="timeline__item">
      <div class="timeline__up">
        <div class="timeline__month timeline__month-up">FEB</div>
      </div>
      <div class="timeline__down">
        <div class="timeline__count timeline__count-down">15</div>
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">5th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>inventore nihil sint est.</li>
            <li>Lorem ipsum dolor sit</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
        <!--       <div class="timeline__count timeline__count-up">5</div> -->
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">15th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>inventore nihil sint est.</li>
            <li>Lorem ipsum dolor sit</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">

      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
    <div class="timeline__item timeline__item-event">
      <div class="timeline__up">
        <div class="timeline__event__list">
          <div class="timeline__date">25th</div>
          <ul>
            <li>Lorem ipsum</li>
            <li>Lorem ipsum</li>
            <li>dolor sit</li>
          </ul>
        </div>
      </div>
      <div class="timeline__down">
      </div>
    </div>
  </div>
</div>

Update: Added more items to the view according to comments.

like image 126
Towkir Avatar answered Oct 27 '22 08:10

Towkir