Reputation: 435
I am new to Flexbox because for my job I have to support back to IE8, so I have never really bothered with it until this project.
I am trying to figure out how to make a grid of "cards" have the same heights. These cards contain varying amounts of text inside of them, as well as an image. Since I am using AngularJS the complexity of JavaScript solutions to make this work is more than I have time for, thus I chose flexbox.
This is my relevant code for the card-wrapper (let me know if you need more):
.card-grid {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-ms-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
...
.data-card {
height: auto;
//IE fallback
display: inline-block;
//Modern Browsers
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
...
}
}
And here is the relevant angular HTML for the above selectors:
<div class="card-group">
<ol class="cards card-grid invisible grid-row">
<li ng-repeat... class="data-card col xs-6 md-4 lg-3">
<a class="card" href="javascript:void(0)" ... >
...
</a>
</li>
</ol>
</div>
This is a screen shot of what is happening on Chrome and Safari in iOS:
The issue I am facing is that, it's showing that first card "Axial" and then the next card "Motor Start" Should be right next to it.
Things I've tried:
flex-grow
but axial just goes to 100% width, and so the does very last (not depicted) card with nothing next to it.wrap-reverse
but that just reversed the content and gave me the same problem.Then I popped open Safari on OS X and got this:
It works on:
The only places it's not working are on Apple browsers (i.e. Chrome iOS, and Safari Mobile, etc.)
So I am thinking it's a -webkit-
thing, but that's sort of obvious. I just don't know what I am doing wrong in my code. I am unable to post a fiddle of my working code, because the project is ongoing.
Is there a special property I should be using in for flexbox that I am not using? Thanks ahead of time for any help.
Upvotes: 5
Views: 2441
Reputation: 435
Okay, I got it licked. So for any of you Googlers out there, the way I fixed this is by changing the CSS to:
.card-grid {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
.data-card {
/**
* Height AUTO is important, because adding flex to the child makes it vertically
* stretch by default. So that means height: 100% won't work.
*/
height: auto;
//IE fallback
display: inline-block;
//Modern Browsers
display: flex;
display: -webkit-flex;
...
/**
* For some unknown reason, it still didn't work until I subracted 1% from
* the width of each breakpoint I was using.
*/
@media screen and (min-width: map_get($grid-breakpoints, 'lg')) {
width: percentage((3 / 12)) - 1%;
}
@media screen and (min-width: map_get($grid-breakpoints, 'md')) {
width: percentage((4 / 12)) - 1%;
}
@media screen and (max-width: map_get($grid-breakpoints, 'sm')) {
width: percentage((6 / 12)) - 1%;
}
}
}
This solution still renders fine in Chrome, even with the 1%
of the true width subracted. A few things that I discovered were:
49%
that it was fixed. I still don't
know why this is, because it's consistent with no box-sizing:
content-box
instead of what I am using which is box-sizing:
border-box
. I have a star selector putting border-box
on every
element, but perhaps I need to manually specify it on the child?I didn't need all the extra vendor pre-fixes I had added, since in
my case, I am using display: inline-block
as a fallback when
flexbox isn't available. Although, if I wanted to I could have used
the below.
@supports not (flex-wrap: wrap) {
...
}
Then put some code in there. Here's another post on CSS Tricks that talks a little about using flexbox and fallbacks. Although, a different use-case than mine, it was still helpful. This was a good visual reference I'm thinking I'll keep around.
Hope all this information was helpful to someone. I know it saved my bacon.
UPDATE: Adding box-sizing: border-box
to the child elements doesn't have any effect. Looks like subracting 1%
from the width is the way to go, unless there's something I don't know, which is more than possible.
UPDATE 2: Due to a suggestion from a friend, and this article, I changed the code a little, started using the flex
property, with column classes on the HTML as a fallback. Re-included the vendor prefixes in the form of a mixin. I also figured out the reason I was having to subtract percentages was because I had a grid container above the parent that had negative margins and clearfixes. Once this was removed the below CSS worked:
.card-grid {
@include displayFlex;
@include flexWrap(wrap);
.data-card {
/**
* Height AUTO is important, because adding flex to the child makes it vertically
* stretch by default. So that means height: 100% won't work.
*/
height: auto;
//IE fallback
display: inline-block;
@include flexboxDisplay;
@include flex(0 0 auto);
}
}
Upvotes: 4