mrClean
mrClean

Reputation: 435

Flexbox odd Behavior on iOS Mobile Browsers and OS X Safari

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 problem is it shows the first card, then for some reason or another, the second card is on the next line... 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:

Then I popped open Safari on OS X and got this: Same issue as on iOS

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

Answers (1)

mrClean
mrClean

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:

  1. Simply putting flex on the parent (to have the children's heights align) was not enough. I read a really great walkthrough on this here.
  2. I was back to square one after I knew I had to keep flex on the parent and the immediate children. It wasn't until I set the widths of the children to 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?
  3. 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

Related Questions