Safari中flex-wrap不像预期的那样工作

56

http://www.shopifyexperte.de/ 的主页上有两个 flex-box 模块,一个位于“Kundenstimmen”下面,另一个位于“Neueste Beiträge...”下面。当宽度小于 220px 时,内部的盒子应该换行,且不超过30%的宽度。这在最新版本的 Chrome、FF 和 Opera(都在 Mac 上)中有效,但在 Safari 8.0.5(Mac)和任何 iOS 浏览器中,即使有足够的空间,盒子也从未形成一行,总是每个盒子占据一行。

容器的 CSS:

.homepage-testimonial-container {
 display: flex;
 display: -webkit-flex;
 -webkit-flex: 1;
 flex: 1;
 -webkit-flex-direction: row;
 flex-direction: row;
 -webkit-flex-wrap: wrap;
 flex-wrap: wrap;
 -webkit-justify-content: space-between;
 justify-content: space-between;
 -webkit-align-items: flex-start;
 align-items: flex-start;
 margin-top: 1em;
}

容器内部盒子的CSS:

.homepage-testimonial {
 margin-bottom: 1em;
 min-width: 220px;
 max-width: 30%;
 -webkit-flex: 1 1 auto;
 flex: 1 1 auto;
}

如果我禁用-webkit-flex-wrap(实际上将其设置为nowrap),所有的盒子都会排成一行,但当浏览器窗口变得太窄时,它们最终会溢出容器。这是Safari / Webkit的某种bug还是我的操作有问题?
10个回答

37

看起来这是Safari的一个漏洞。在另一个问题中,我测试了使用min-width替换你说类似于-webkit-flex: 1 1 auto;的那一行中的auto。

这个问题有一些信息:https://dev59.com/cF8e5IYBdhLWcg3wyM7N#30792851


1
这个错误似乎是在几天前关闭的(https://bugs.webkit.org/show_bug.cgi?id=136041),因此我们可以期待在下一个Safari版本中修复。 - joepio
5
@JoepMeindertsma - 这并不太重要,因为您仍需要支持两年以上的浏览器版本。 - vsync

36

这样设置子元素对我来说似乎有效

flex: 1 0 auto;

这可能是因为 Safari 的最近更新终于使其正常工作了。 - Joseph Hansen
是的,Safari 9 的弹性盒子基本上与 Chrome 的工作方式相同。但在 Safari 8 中情况并非如此。 - Dave
7
@Dave 别急着下结论。现在是2017年,Safari浏览器还有很长的路要走才能赶上它的任何竞争对手。 - DreamTeK
1
到了2023年,Safari 仍然存在此问题。请参考 https://codepen.io/tedmcdo/pen/dygjPX。 - user3450906

33

在Safari(9.1.3)中,我遇到了与Bootstrap 3网格系统(例如col-md-4)以及flex结合使用的类似问题。我通过将margin: 0 -1px;设置为col元素和在包装器上设置flex-wrap: wrap;来解决它。


7
这就是它,一行代码解决了iOS下的所有问题。在我看来,这个解决方案是最好的,因为它保持了弹性属性和其他所有内容的完整性,而不需要修改你的整体设计,全部只用min-width等属性完成。 - David
我认为这与Safari在计算时将像素四舍五入到整数有关。 - eye-wonder
1
这解决了!非常感谢。 - Keith Pickering
2
2020年了,这个问题仍然存在,而这个hack仍然可以解决它! - James Ellis-Jones
这并没有解决我在Safari v. 10.1.2 (2017)上的问题,这是截至2020年9月21日Yosemite 10.10.5上运行MacBook Pro的当前版本(作为购买时的本机安装和自然更新)。至少它没有破坏所有其他浏览器/操作系统。 - AppDreamer
显示剩余2条评论

14

我正在使用 Safari 11.0.1,但该错误仍然存在。我在 Bootstrap 3 中使用 display: flex 来配合我的 .row 元素。我添加了以下样式来针对列元素进行定位。在 Safari 中,似乎有关宽度百分比的某些内容没有被正确地遵守。

.row [class*=col-]{
    margin:0 -.3px;
}

2
我刚遇到了这个确切的问题(Safari 11,Bootstrap 3)。当我在一个有四列的行上使用 display: flexflex-wrap: wrap 时,Safari 每行只显示三列而不是四列。如上所示设置负左/右边距可以解决它。 - daGUY

10

设置 flex-basis: 20em 是有效的,min-width: 20em 不是。


谢谢!那是我想要回来的4个小时!我尝试了这里的所有其他方法,但是将flex-basis添加到我的三个子对象中使我能够保持wrap-reverse,并且现在在所有浏览器中都可以正常工作。谢谢! - AppDreamer

6
这确实是Safari的一个bug。详细信息可在flexbugs页面找到,但引用一下:

Safari使用min/max宽度/高度声明来实际呈现flex项目的大小,但在计算多行flex容器的单行上应有多少项时,它会忽略这些值。相反,它仅使用项目的flex-basis值或其宽度(如果flex基础设置为auto)。

因此,修复/解决方法 - 如其他答案所建议的 - 是将flex-basis设置为显式宽度,而不是auto

4

我又遇到了这个问题,并使用了'flex-flow'。效果很棒。

.row {
    @include flex();
    @include flex-wrap();
    flex-flow: row;
}

最佳解决方案,我认为 :) - user1597594
那只是因为你正在覆盖 flex-wrap。Flex-flow 是 flex-direction 和 flex-wrap 的缩写。 - nomadoda

1

我有其他适合我的解决方案。

.row容器中,使用以下属性添加了beforeafter

row:before, .row:after {
 content: " ";
 display: table;
}

因此,设置display: none或display: inline将解决问题,或者设置content: none也可以解决问题。

.row:before, .row:after {
   display: none;
}
or
.row:before, .row:after {
   display: inline;
}

or
.row:before, .row:after {
   content: none
}

虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。来自审核 - double-beep

0

我已经编辑了 col-md-6 {flex: 0 0 49.9%}。在 Safari 上可以工作。 flex: 0 0 49.9%


0

如果您有,请删除 display: -webkit-box。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接