iOS 移动浏览器和 OS X Safari 上的 Flexbox 奇怪行为
Flexbox odd Behavior on iOS Mobile Browsers and OS X Safari
我是 Flexbox 的新手,因为我的工作需要支持 IE8,所以在这个项目之前我从来没有真正为它烦恼过。
我想弄清楚如何使 "cards" 的网格具有相同的高度。这些卡片内部包含不同数量的文本以及图像。由于我正在使用 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>
这是 Chrome 和 iOS 中的 Safari 上发生的情况的屏幕截图:
我面临的问题是,它显示第一张卡片 "Axial" 和下一张卡片 "Motor Start" 应该就在它旁边。
我尝试过的事情:
- 将包装纸 属性 放在物品本身上,而不是包装纸上,这看起来很糟糕
- 定义宽度,并使用
flex-grow
但轴向刚好达到 100% 宽度,因此最后一张(未描绘)卡片旁边没有任何内容。
- 正在做
wrap-reverse
但这只是颠倒了内容并给了我同样的问题。
然后我在 OS X 上打开 Safari 并得到了这个:
适用于:
- Chrome(桌面)
- Firefox(桌面)
- Internet Explorer Edge(桌面)
- Chrome(安卓)
它唯一不起作用的地方是在 Apple 浏览器上(即 Chrome iOS 和 Safari Mobile 等)
所以我认为这是 -webkit-
的事情,但这很明显。我只是不知道我的代码做错了什么。我无法 post 我的工作代码 fiddle,因为该项目正在进行中。
是否有一个特殊的 属性 我应该在我没有使用的 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%;
}
}
}
此解决方案在 Chrome 中仍然呈现良好,即使减去了 1%
的真实宽度。我发现的一些事情是:
- 简单地在 parent 上放置 flex(以获得 children 的高度
对齐)是不够的。我读了一个非常棒的演练
here.
- 在我知道我必须保持灵活性后,我又回到了原点
parent和立即child任。直到我设置了
children 到
49%
的宽度是固定的。我还是不
知道这是为什么,因为它符合没有 box-sizing:
content-box
而不是我使用的是 box-sizing:
border-box
。我有一个星号选择器,将 border-box
放在每个
元素,但也许我需要在 child? 上手动指定它
我不需要我添加的所有额外供应商 pre-fixes,因为在
我的情况是,我使用 display: inline-block
作为备用
弹性盒不可用。虽然,如果我愿意,我可以使用
下面。
@supports not (flex-wrap: wrap) {
...
}
然后把一些代码放在那里。这是 CSS Tricks 上的另一个 post
那谈了一点关于使用 flexbox 和回退。虽然,一个
use-case 与我的不同,它仍然很有帮助。 This was a good visual reference我想我会留下来。
希望所有这些信息对某人有所帮助。我知道它救了我的培根。
更新: 添加 box-sizing: border-box
到 child 元素没有任何效果。看起来从宽度中减去 1%
是可行的方法,除非有一些我不知道的东西,这是不可能的。
更新 2: 由于朋友的建议和 this article,我稍微更改了代码,开始使用 flex
属性,HTML 上的列 类 作为后备。 Re-included mixin 形式的供应商前缀。我还弄清楚我不得不减去百分比的原因是因为我在 parent 上方有一个网格容器,它有负边距和 clearfixes。删除后,下面的 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);
}
}
我是 Flexbox 的新手,因为我的工作需要支持 IE8,所以在这个项目之前我从来没有真正为它烦恼过。
我想弄清楚如何使 "cards" 的网格具有相同的高度。这些卡片内部包含不同数量的文本以及图像。由于我正在使用 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>
这是 Chrome 和 iOS 中的 Safari 上发生的情况的屏幕截图:
我尝试过的事情:
- 将包装纸 属性 放在物品本身上,而不是包装纸上,这看起来很糟糕
- 定义宽度,并使用
flex-grow
但轴向刚好达到 100% 宽度,因此最后一张(未描绘)卡片旁边没有任何内容。 - 正在做
wrap-reverse
但这只是颠倒了内容并给了我同样的问题。
然后我在 OS X 上打开 Safari 并得到了这个:
适用于:
- Chrome(桌面)
- Firefox(桌面)
- Internet Explorer Edge(桌面)
- Chrome(安卓)
它唯一不起作用的地方是在 Apple 浏览器上(即 Chrome iOS 和 Safari Mobile 等)
所以我认为这是 -webkit-
的事情,但这很明显。我只是不知道我的代码做错了什么。我无法 post 我的工作代码 fiddle,因为该项目正在进行中。
是否有一个特殊的 属性 我应该在我没有使用的 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%;
}
}
}
此解决方案在 Chrome 中仍然呈现良好,即使减去了 1%
的真实宽度。我发现的一些事情是:
- 简单地在 parent 上放置 flex(以获得 children 的高度 对齐)是不够的。我读了一个非常棒的演练 here.
- 在我知道我必须保持灵活性后,我又回到了原点
parent和立即child任。直到我设置了
children 到
49%
的宽度是固定的。我还是不 知道这是为什么,因为它符合没有box-sizing: content-box
而不是我使用的是box-sizing: border-box
。我有一个星号选择器,将border-box
放在每个 元素,但也许我需要在 child? 上手动指定它
我不需要我添加的所有额外供应商 pre-fixes,因为在 我的情况是,我使用
display: inline-block
作为备用 弹性盒不可用。虽然,如果我愿意,我可以使用 下面。@supports not (flex-wrap: wrap) { ... }
然后把一些代码放在那里。这是 CSS Tricks 上的另一个 post 那谈了一点关于使用 flexbox 和回退。虽然,一个 use-case 与我的不同,它仍然很有帮助。 This was a good visual reference我想我会留下来。
希望所有这些信息对某人有所帮助。我知道它救了我的培根。
更新: 添加 box-sizing: border-box
到 child 元素没有任何效果。看起来从宽度中减去 1%
是可行的方法,除非有一些我不知道的东西,这是不可能的。
更新 2: 由于朋友的建议和 this article,我稍微更改了代码,开始使用 flex
属性,HTML 上的列 类 作为后备。 Re-included mixin 形式的供应商前缀。我还弄清楚我不得不减去百分比的原因是因为我在 parent 上方有一个网格容器,它有负边距和 clearfixes。删除后,下面的 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);
}
}