iOS移动浏览器和OS X Safari上的Flexbox奇怪行为

时间:2016-08-22 23:03:14

标签: angularjs sass webkit flexbox

我是Flexbox的新手,因为对于我的工作,我必须支持IE8,所以在这个项目之前我从未真正打扰过它。

我想弄清楚如何让“牌”网格具有相同的高度。这些卡片中包含不同数量的文本以及图像。由于我使用的是AngularJS,因此我选择使用Flexbox时,JavaScript解决方案的复杂性超出了我的工作时间。因此我选择了flexbox。

这是我对卡片包装的相关代码(如果您需要更多,请告诉我):

.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+ */

        ...

    }
}

以下是上述选择器的相关角度HTML:

<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>

这是iOS中Chrome和Safari上发生的事情的屏幕截图: The problem is it shows the first card, then for some reason or another, the second card is on the next line... 我面临的问题是,它显示第一张卡片“Axial”然后下一张卡片“Motor Start”应该就在它旁边。

我尝试过的事情:

  • 将wrap属性放在项目本身而不是包装器上,看起来很糟糕
  • 定义宽度,并使用flex-grow,但轴向仅为100%宽度,因此最后(未描绘)的卡片旁边没有任何内容。
  • wrap-reverse,但这只是颠倒了内容并给了我同样的问题。

然后我在OS X上弹出Safari并得到了这个: Same issue as on iOS

适用于:

  • Chrome(桌面)
  • Firefox(桌面)
  • Internet Explorer Edge(桌面)
  • Chrome(Andriod)

它唯一无效的地方是Apple浏览器(即Chrome iOS和Safari Mobile等)

所以我认为这是一个-webkit-的事情,但这很明显。我只是不知道我在代码中做错了什么。我无法发布我的工作代码的小提示,因为该项目正在进行中。

我是否应该使用我不使用的flexbox特殊属性?提前感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

好的,我舔了它。因此,对于你们中的任何一个Google员工,解决这个问题的方法是将CSS更改为:

.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%;
    }
  }
}

这个解决方案在Chrome中仍然很好,即使减去了真实宽度的1%也是如此。我发现的一些事情是:

  1. 简单地将柔性放在父母身上(以达到孩子的身高 对齐)还不够。我读到了一篇非常棒的演练 here
  2. 我知道自己必须继续弯腰后,才回到原点 父母和直接孩子。直到我设定了 将孩子的宽度修改为49%。我还是没有 知道为什么会这样,因为它与没有box-sizing: content-box而不是我使用的box-sizing: border-box一致。我有一个明星选择器,每个都有border-box 元素,但也许我需要在孩子上手动指定它?
  3. 我不需要我添加的所有额外的供应商预修复,因为在 我的情况是,我使用display: inline-block作为后备 flexbox不可用。虽然,如果我想,我可以使用 以下。

    @supports not (flex-wrap: wrap) {
      ...
    }
    

    然后在那里放一些代码。这是CSS Tricks上的另一篇文章 谈谈使用flexbox和fallbacks。虽然,一个 不同的用例比我的,它仍然有用。 This was a good visual reference我想我会留下来。

  4. 希望所有这些信息对某人有帮助。我知道它保存了我的培根。

    更新:向子元素添加box-sizing: border-box没有任何效果。看起来从宽度中减去1%似乎是要走的路,除非有一些我不知道的东西,这是可能的。

    更新2:由于朋友和this article的建议,我稍微更改了代码,开始使用flex属性,其中包含列类HTML作为后备。以mixin的形式重新包含供应商前缀。我还想出了我不得不减去百分比的原因是因为我在父级上面有一个网格容器,它有负边距和明确修正。删除后,下面的CSS工作:

    .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);
    
      }
    }