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

标签 angularjs sass webkit flexbox

我是 Flexbox 新手,因为我的工作需要支持 IE8,所以在这个项目之前我从来没有真正关心过它。

我试图弄清楚如何使“卡片”网格具有相同的高度。这些卡片内部包含不同数量的文本以及图像。由于我使用 AngularJS,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+ */

        ...

    }
}

这是上述选择器的相关 Angular 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”应该就在它旁边。

我尝试过的事情:

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

然后我在 OS X 上打开 Safari 并得到以下信息: Same issue as on iOS

它适用于:

  • Chrome(桌面版)
  • Firefox(桌面版)
  • Internet Explorer Edge(桌面版)
  • Chrome(安卓)

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

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

是否有一个我应该在 Flexbox 中使用但我没有使用的特殊属性?提前感谢您的帮助。

最佳答案

好吧,我已经搞定了。因此,对于任何 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%;
    }
  }
}

即使减去真实宽度的 1%,该解决方案在 Chrome 中仍然可以正常呈现。我发现的一些事情是:

  1. 只需在父级上施加弹性(以获得 child 的高度 对齐)还不够。我读了一篇关于此的非常精彩的演练 here .
  2. 在我知道我必须保持灵 active 之后,我又回到了原点 父级和直系子级。直到我设置了 将子项的宽度调整为已修复的 49%。我还是不知道 知道为什么会这样,因为它与 no box-sizing 一致: content-box 而不是我正在使用的 box-sizing: 边框框。我有一个星形选择器,将 border-box 放在每个 元素,但也许我需要在子元素上手动指定它?
  3. 我不需要添加的所有额外供应商前缀,因为 我的情况是,我使用 display: inline-block 作为后备 弹性盒不可用。不过,如果我愿意的话我可以使用 下面。

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

    然后在其中放入一些代码。这是关于 CSS Tricks 的另一篇文章 这讨论了一些关于使用弹性盒和后备的问题。虽然,一个 与我的用例不同,它仍然很有帮助。 This was a good visual reference我想我会留下来。

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

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

更新2:由于 friend 的建议,以及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);

  }
}

关于angularjs - Flexbox 在 iOS 移动浏览器和 OS X Safari 上的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39090003/

相关文章:

ios - 在 iOS 10 + Swift 3 中以编程方式在我的 WKWebView 上方添加一个 UILabel

javascript - AngularJS 过滤器唯一删除 ng-options 中的重复项

javascript - 如何在 promise 后填充 Angular ui-select 选项?

ruby-on-rails - rails : Bootstrap Editing Forms CSS

css - SCSS 中的背景转换不起作用

css - 无法在 Webkit 中设置屏幕的 div 填充宽度(chrome 和 safari)

javascript - 如何访问 angularJS 中服务工厂函数的返回值

javascript - 如何 Hook ng-if 更改?

html - 在我的 index.html 中直接使用 SCSS/SASS

css - 从检查器(webkit、firebug 等)导出 CSS 更改