Search code examples
htmlcssflexboxvertical-alignmenttext-alignment

Vertically aligning multi-line text using flexbox


I'm using flexbox to align items and am struggling with top-aligning multiline text to the bottom of its parent div. I've seen examples where a button has been aligned to the bottom of its parent, but not achieving the same effect with multiple lines of text in each item.

Here is what I'm trying to accomplish:

desired layout

Here's what I have accomplished with the code below:

current layout

Here's my code:

.team {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.li {
  width: 25%;
  padding: 10px;
  display: flex;
  flex-direction: column;
}

.expert-wrap {
  margin-top: auto;
}
<ul class="team">
  <li>
    <div class="thumb">Image</div>
    <div class="excerpt">Some text</div>
    <div class="expert-wrap">
      <div class="expertise-keywords">Expertise:
        <?php the_field('expertise'); ?>
      </div>
      <?php } ?>
    </div>
  </li>

</ul>

Ideally, I want to align the text at the top, but everything I've tried - including applying align-self: flex-end on that expert-wrap div - aligns the bottom line of text vs the top line of text. Any ideas on how I can get the items inside that bottom div aligned at the top, while also being aligned to the bottom of the parent?

I'm so stumped on this. Appreciate any advice. -Nat


Solution

  • One option is to give .expert-wrap a height while adding flex: 1 to the .excerpt so it fills the space given and pushes the the expertise text to the bottom.

    .team {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      padding: 0;
    }
    
    
    li {
      background: cornsilk;
      width: 25%;
      padding: 10px;
      display: flex;
      flex-direction: column;
      font-size: 12px;
    }
    
    .title {
      color: maroon;
    }
    
    .thumb img {
      width: 100%;
    }
    
    
    .excerpt {
      flex: 1;
      margin-bottom: 20px;
    }
    
    .expert-wrap {
      height: 40px;
    }
    <ul class="team">
      <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
           Velit esse cillum.
          </div>
        </div>
      </li>
        <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
            Duis aute irure dolor in reprehenderit.
          </div>
        </div>
      </li>
        <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
            Vuptate velit esse cillum dolore eu fugiat nulla pariatur.
          </div>
        </div>
      </li>
    </ul>

    If this text is very dynamic, you could use javascript to find the .expert-wrap with the largest height, and apply that height to the rest of the .expert-wraps or .expertise-keywords.

    That would look something like:

    const expertiseText = document.querySelectorAll('.expert-wrap');
    
    const heights = [];
    
    expertiseText.forEach(entry => {
      heights.push(entry.clientHeight)
    })
    
    const largestHeight = Math.max.apply(Math, heights);
    
    expertiseText.forEach(entry => {
      entry.style.height = `${largestHeight}px`;
    })
    .team {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      padding: 0;
    }
    
    
    li {
      background: cornsilk;
      width: 25%;
      padding: 10px;
      display: flex;
      flex-direction: column;
      font-size: 12px;
    }
    
    .title {
      color: maroon;
    }
    
    .thumb img {
      width: 100%;
    }
    
    
    .excerpt {
      flex: 1;
      margin-bottom: 20px;
    }
    <ul class="team">
      <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
           Velit esse cillum.
          </div>
        </div>
      </li>
        <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
            Duis aute irure dolor in reprehenderit.
          </div>
        </div>
      </li>
        <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
            Vuptate velit esse cillum dolore eu fugiat nulla pariatur.
          </div>
        </div>
      </li>
    </ul>

    But you'd probably want to put a resize handler on an applyHeights() function to make sure it recalculates when the browser width is bigger or smaller.

    That would look something like:

    const expertiseText = document.querySelectorAll('.expert-wrap');
    
    function applyHeights() {
    
      const heights = [];
    
      expertiseText.forEach(entry => {
        heights.push(entry.clientHeight)
      })
    
      const largestHeight = Math.max.apply(Math, heights);
    
      expertiseText.forEach(entry => {
        entry.style.height = `${largestHeight}px`;
      })
    }
    
    applyHeights();
    
    window.addEventListener('resize', function(event) {
    
      // Reset heights to auto so largest height can be recalculated
      expertiseText.forEach(entry => {
        entry.style.height = "auto";
      })
    
      applyHeights();
    }, true);
    .team {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      padding: 0;
    }
    
    
    li {
      background: cornsilk;
      width: 25%;
      padding: 10px;
      display: flex;
      flex-direction: column;
      font-size: 12px;
    }
    
    .title {
      color: maroon;
    }
    
    .thumb img {
      width: 100%;
    }
    
    
    .excerpt {
      flex: 1;
      margin-bottom: 20px;
    }
    <ul class="team">
      <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
           Velit esse cillum.
          </div>
        </div>
      </li>
        <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
            Duis aute irure dolor in reprehenderit.
          </div>
        </div>
      </li>
        <li>
        <div class="thumb">
          <img src="https://images.unsplash.com/photo-1620057604592-ceccf0143ee8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" alt=""/>
        </div>
        <h3 class="title">Labore et dolore </h3>
        <div class="excerpt">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,.</div>
        <div class="expert-wrap">
          <div class="expertise-keywords">Expertise:
            Vuptate velit esse cillum dolore eu fugiat nulla pariatur.
          </div>
        </div>
      </li>
    </ul>