Equal Height Columns Height CSS FlexBox [duplicate]
Asked Answered
B

3

0

I'm trying to achieve equal height columns/cards on some flex-items.

When the title or the card product title element does not span more than 1 line
The design acts as it should
Working Example:
Working Example

BUT When the title breaks onto a second line the design breaks.

Broken Example
enter image description here

<div class="card">
  <div class="title">iPhone 14 White Pearl</div>
  <div class="img">&nbsp;</div>
  <div class="desc">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
  <button>Add to Cart</button>
</div>

<div class="card">
  <div class="title">iPhone 14 White Pearl</div>
  <div class="img">&nbsp;</div>
  <div class="desc">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
  <button>Add to Cart</button>
</div>

<div class="card">
  <div class="title">iPhone 14 White Pearl (Unlocked - GSM)</div>
  <div class="img">&nbsp;</div>
  <div class="desc">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
  <button>Add to Cart</button>
</div>

<div class="card">
  <div class="title">iPhone 14 White Pearl</div>
  <div class="img">&nbsp;</div>
  <div class="desc">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
  <button>Add to Cart</button>
</div>

<div class="card">
  <div class="title">iPhone 14 White Pearl</div>
  <div class="img">&nbsp;</div>
  <div class="desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. Lorem ipsum dolor sit amet consectetur Lorem ipsum dolor sit amet consectetur </div>
  <button>Add to Cart</button>
</div>

<div class="card">
  <div class="title">iPhone 14 White Pearl</div>
  <div class="img">&nbsp;</div>
  <div class="desc">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
  <button>Add to Cart</button>
</div>



THE CSS

.container {
  display: grid;
  margin: 30px auto 10px;
  max-width: 1024px; 
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 30px;
}

.card {
  width: 200px;
  display: flex;
  flex-direction: column;
  flex-basis: 1;
  align-items: stretch;
}

.card .title {
  padding: 0 0 10px;
  font-family: 'Avenir Next', sans-serif;
  font-size: 15px;
  /* flex: 1 0 auto; */

}

.card .img {
  width: 100%;
  height: 120px;
  background-color: purple;
}

.card .desc {
  justify-self: flex-start;
  flex: 2 0 auto;
  padding: 10px 0;
}


.card button {
  padding: 10px;
  outline: none;
  border: none;
  color: white;
  background-color: teal;
}

@media screen and (max-width: 768px) {
  .container {
    grid-template-columns: 1fr 1fr;
  }
}

Code Link

It seems like having two flex-grow; properties inside of a flex-item column container doesn't yield the behavior I thought it would.

Edit: As I'm writing this I realized that the heights are infact equal height. What is not happening is even distribution and flush alignment amongst the other sibiling containers when the Card title breaks onto a second line - which is what i'm truly after. Any and all help is appreciated

Boor answered 21/2, 2023 at 16:55 Comment(1)
possible guidance: https://mcmap.net/q/89293/-equal-height-children-of-flex-items/3597276Apia
W
0

Add height according to your need check the value and add the exact value.

.card .title {
  padding: 0 0 10px;
  height: 9%;
  font-family: 'Avenir Next', sans-serif;
  font-size: 15px;
  /* flex: 1 0 auto; */

}

.card .img {
  width: 100%;
  height: 125px;
  background-color: purple;
}

.card .desc {
  justify-self: flex-start;
  flex: 2 0 auto;
  padding: 10px 0;
  height:10%;
}
Walkyrie answered 21/2, 2023 at 17:16 Comment(1)
This was my initial fix for this issue - which I quickly ruled out. It adds unnecessary space to cards with minimal one-line titles. The design then had too much white space.Boor
S
0

As you have mentioned, the height is equal for all cards, so that part of the problem is solved. The second task that you want is to have the same size for all titles. I'm not sure if that can be dynamically adjusted without JavaScript, so I have provided a solution that may fix your problem. Add this to the JS of your fiddle:

// Get all title elements
const allTitles = document.querySelectorAll('.container .card .title');

// Prepare an empty array to store all title heights
const titleHeightArray = [];

// Get the height of each title
allTitles.forEach((titleElement) => {
    titleHeightArray.push(titleElement.offsetHeight);
});

// Get the maximum height of all titles
const titleHeightMax = Math.max(...titleHeightArray);

// Set the maximum height to all titles
allTitles.forEach((titleElement) => {
    titleElement.style.height = titleHeightMax + 'px';
});

In the end, it really depends on where you're applying this. If it is on a site where an administrator can edit the title to be on 5 rows, that would still be considered broken, even if all of them are the same height. A better practice is to define a height and handle overflowing text, for example with overflow and elipsis (it adds a ... to the end of an overflowing title). You can refer the following resource for more information about it: https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow

Stylo answered 21/2, 2023 at 17:17 Comment(0)
N
0

You don't need to use js or set hard heights to have that effect.

You can have it in two main ways:

  1. use grid-template-rows: minmax()
  2. setting a min-height to the cards

here is a example. Sorry for the tailwindplay, it is just more convenient with the intelli.

EDIT: I thought you wanted all rows to have the same height but it seems you need the title to be truncated in 1 line.

is this what you are looking for?

Nonessential answered 21/2, 2023 at 17:50 Comment(6)
hey ricardo. Def appreciate your answer but I don't see a working example even after clicking your linkBoor
I think I misunderstood you then, you probably looking for truncating the title in 1 line? I will edit.Nonessential
take a look now and let me knowNonessential
This is def a possible solution. But i truly wonder is there no way to do this without hacking it with JS or adding fixed height to the title of the card? Thanks for your code!Boor
This is def a possible solution. But i truly wonder is there no way to do this without hacking it with JS or adding fixed height to the title of the card? Thanks for your code!Boor
I did not add any height to the card title neither used js. But you can't let the text wrap if you need the height to be the same over all cards, so you have to decide if it is worth to cut up the title. But this is a common solution, what they do to mitigate is repeat the text in the title attribute so you can see all by hovering on it. But if you need the full title you gonna have to fix the height somewhere, either the card size or the content size and stack it from bottom up so the title will fit and the imgs will be aligned.Nonessential

© 2022 - 2024 — McMap. All rights reserved.