I got the following use case:
You can see three identical boxes:
Each box beginns with a big rectangle box, that has a picture and variable content and thus has variable height.
the rest consists of a list, that is vertical aligned bottom, so that they should get the same height.
My goal is to "synchronize" the height of the < li >'s in each of these boxes. So it should not be important how many text you enter in such a < li > tag, the design should automatically handle the word-break and align the content like it was a row.
In other words, like Abhitalks stated, I want to align list-items to their peers in other content columns depending on the mutual heights.
Now, I used display flex in order to vertical align the list to bottom of the element.
You can find my used solution here:
Vertical alignment of floating divs
But now I got the problem, that if the list has no identical content (e.x. more than two rows per listitem, the whole thing shifts to the top.
However, is it somehow possible to simulate a row behavior with flexbox, but actually having a column structure?
I need a column structure, so I can easily get a responsive layout.
hope you understand my problem
thanks in advance!
UPDATE:
Here is the fiddle:
http://jsfiddle.net/a1yr4u84/3/
You can see, that I made < br / >'s inside the li's content, in order to make the content fit.
<li>one <br /> two</li>
<li>one <br /> two <br /> three</li>
<li>one<br /><br /></li>
However, I can't control how many text there is going to be in the li's. And I don't want the user to hack with < br / >s but let the design handle the content, so I want the list inside the columns to behave like a row
...three identical boxes: first big rectangle part has
variable content and thus variable height. the rest consists of a
list, that is vertical aligned bottom, so that they should get the
same height.
You need nested flex
here. Given this markup:
<div class="wrap">
<div class="col left">
<img src="..." />
<div class="content">
<p>...</p>
</div>
</div>
<div class="col middle">
<img src="" />
<ul class="content">
<li>...</li>
<li>...</li>
</ul>
</div>
<div class="col right">
<img src="..." />
<ul class="content">
<li>...</li>
</ul>
</div>
</div>
First flex
the wrapper which will layout the columns in a row, and give a flex-basis
of 33%
(approx) to the columns to allow for variable content in first columns to space out.:
.wrap { display: flex; }
.wrap .col { flex: 1 0 33%; }
Next, flex
the columns to layout the image and content list in columns. This time flex-basis
is not required:
.wrap .col { flex: 1 0 33%; display: flex; flex-direction: column; }
.col img, .col .content { flex: 0 0 auto; }
In order to keep the lists vertically aligned to the bottom, just provide a margin-top:auto
to the list content:
.col .content { margin-top: auto; }
Here is a complete example..
Fiddle: http://jsfiddle.net/abhitalks/a1yr4u84/1/
Snippet:
* { box-sizing: border-box; }
.wrap {
width: 80%; margin: 16px auto; padding: 12px; border: 1px solid grey;
display: flex;
}
.wrap .col {
flex: 1 0 33%; display: flex; flex-direction: column;
}
.col img, .col .content { flex: 0 0 auto; }
.col img { width: 128px; display: block; margin: 2px auto; }
.col .content { margin: auto 12px 0px 12px; }
<div class="wrap">
<div class="col left">
<img src="//lorempixel.com/128/128" />
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab, impedit. Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
</div>
<div class="col middle">
<img src="//lorempixel.com/128/128" />
<ul class="content">
<li>one</li>
<li>one</li>
<li>one</li>
<li>one</li>
</ul>
</div>
<div class="col right">
<img src="//lorempixel.com/128/128" />
<ul class="content">
<li>one</li>
<li>one</li>
</ul>
</div>
</div>
Edit:
(based on op's comment)
If you want the list-items to align to their peers in other content columns depending on the mutual heights, then you cannot do this with CSS. I see that you have tagged the question with jQuery
, so I am proposing a quick-and-dirty solution using jQuery.
Calculate the height
of the list items, and apply that height to all the corresponding items in other columns:
Fiddle 2: http://jsfiddle.net/abhitalks/a1yr4u84/4/
Snippet 2:
var $lists = $('ul.content');
for (i=0; i < 10; i++) {
var highest = 0;
$lists.each(function(idx, elem) {
var h = $(elem).children().eq(i).outerHeight();
if (h > highest) highest = h;
});
$lists.each(function(idx, elem) {
$(elem).children().eq(i).outerHeight(highest);
});
}
* { box-sizing: border-box; }
.wrap {
width: 80%; margin: 16px auto; padding: 12px; border: 1px solid grey;
display: flex;
}
.wrap .col {
flex: 1 0 33%; display: flex; flex-direction: column;
}
.col img, .col .content { flex: 0 0 auto; }
.col img { width: 128px; display: block; margin: 2px auto; }
.col .content { margin: 0px 12px 0px 12px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="col left">
<img src="//lorempixel.com/128/128" />
<ul class="content">
<li>one <br /> two</li>
<li>one <br /> two <br /> three</li>
<li>one</li>
<li>one</li>
</ul>
</div>
<div class="col middle">
<img src="//lorempixel.com/128/128" />
<ul class="content">
<li>one</li>
<li>one</li>
<li>one</li>
<li>one</li>
</ul>
</div>
<div class="col right">
<img src="//lorempixel.com/128/128" />
<ul class="content">
<li>one <br /> two</li>
<li>one</li>
</ul>
</div>
</div>
Note: I have used an arbitrary number of 10
to loop thru the list-items. In production code, you must calculate the number of the list items in the largest list.
Set css line-height
to the row objects. All need to be set of the same height.