如何在 Safari 中将 flex 容器的绝对定位子项居中?

How to center absolutely positioned children of a flex container in Safari?

我有一个包含图像和一些文本的容器。我希望文本在图像中间垂直和水平居中。

看来最简单的前瞻性方法是使用 Flexbox 和文本的绝对定位:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.text {
  position: absolute;
}
<div class='container'>
  <div class='text'>
    This should be centered
  </div>
  <img src="https://placehold.it/250x250" />
</div>

文本在两个轴上都居中。这似乎适用于所有现代浏览器..... 除了 Safari。

Safari 似乎根本不使文本居中。它只是位于容器的 top/left 处,就像一个普通的绝对定位元素在非 flexbox 布局中一样。

Safari(错误):

所有其他浏览器(正确):

我认为 Flexbox 真的已经准备好迎接黄金时段,但考虑到有多少人在 iOS 上使用 Safari,这似乎是一个交易破坏者。将内容水平和垂直居中是 Flexbox 应该擅长的。

我唯一真正的选择是不使用 Flexbox 然后使用:

.text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
}

但出于进步的原因,我更愿意使用 Flexbox。

这里有什么我遗漏的吗?尽管我不愿意提出要求,但这里是否有一些仅适用于 Safari 的解决方法?除了 "not using flexbox" 之外还有其他解决方案吗,因为如果这是 2017 年年中的答案,那将令人失望。

JSFiddle 供参考:https://jsfiddle.net/z7kh5Laz/4/

关于 Flexbox 和绝对定位,有一些该做的和不该做的,在这种情况下,Safari 不会像其他浏览器那样将绝对定位元素居中。

您可以将 Flexbox 和 transform: translate 结合使用,因为后者不会影响前者,并且当时机成熟时,它们与单独使用 Flexbox 的行为相同,您可以删除 transform /left/top部分。

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
}
<div class='container'>
  <div class='text'>
    This should be centered
  </div>
  <img src="https://placehold.it/250x250"/>
</div>

敬请见谅,您的问题中有几个错误的假设:

  • "Safari (wrong): [image]" - Safari 不一定是错误的。
  • "All other browsers (correct): [image]" - 其他浏览器不一定正确。
  • "I thought Flexbox was really ready for primetime.." - 是的。 98% of browsers support flexbox.
  • "Centering content horizontally and vertically is something Flexbox should be great at." - 是。

Is there anything I'm missing here?

是的,规范中提到绝对定位的 flex 项目忽略 flex 属性的部分。

4.1. Absolutely-Positioned Flex Children

An absolutely-positioned child of a flex container does not participate in flex layout.

如果某些浏览器选择将 flex 属性应用于绝对定位的 flex 项目,那是他们的选择。但是,如果浏览器忽略此类元素的 flex 属性,那并不一定意味着它们违反了规范。

在阅读规范中的整个部分时,似乎没有明确的对错。

为了更稳定可靠的解决方案,请不要使用 flex 属性来定位流外元素。请改用 CSS 定位属性: