97

我正在尝试<button>使用 flexbox 将 -tag 的内部元素居中justify-content: center。但 Safari 并不以它们为中心。我可以将相同的样式应用于任何其他标签,并且它可以按预期工作(请参阅<p>-tag)。只有按钮是左对齐的。

尝试使用 Firefox 或 Chrome,您会看到不同之处。

我必须覆盖任何用户代理样式吗?或者这个问题的任何其他解决方案?

div {
  display: flex;
  flex-direction: column;
  width: 100%;
}
button, p {
  display: flex;
  flex-direction: row;
  justify-content: center;
}
<div>
  <button>
    <span>Test</span>
    <span>Test</span>
  </button>
  <p>
    <span>Test</span>
    <span>Test</span>
  </p>
</div>

还有一个 jsfiddle:http: //jsfiddle.net/z3sfwtn2/2/

4

3 回答 3

144

问题

在某些浏览器中,除了在和之间切换之外,<button>元素不接受对其值的更改。这意味着元素不能是 flex 或 grid 容器,也不能是 。displayblockinline-block<button><table>

除了<button>元素之外,您可能会发现此约束也适用于<fieldset><legend>元素。

有关更多详细信息,请参阅下面的错误报告。

注意:虽然它们不能是弹性容器,但<button>元素可以是弹性项目。


解决方案

对于这个问题,有一个简单易行的跨浏览器解决方法:

将 的内容包装button在 a 中span,并制作spanflex 容器。

调整后的 HTML(包装button在 a 中的内容span

<div>
    <button>
        <span><!-- using a div also works but is not valid HTML -->
            <span>Test</span>
            <span>Test</span>
        </span>
    </button>
    <p>
        <span>Test</span>
        <span>Test</span>
    </p>
</div>

调整后的 CSS(目标span

button > span, p {
    display: flex;
    flex-direction: row;
    justify-content: center;
}

修改后的演示


参考/错误报告

a 上的<button>Flexbox 会阻止内容,但不建立 flex 格式化上下文

用户(Oriol Brufau):按照<button>flexbox 规范的规定,子节点被阻塞。然而,这<button>似乎建立了一个块格式化上下文而不是一个弹性上下文。

用户 (Daniel Holbert):这实际上是 HTML 规范所要求的。几个 HTML 容器元素是“特殊的”,并且display在 Gecko 中有效地忽略了它们的 CSS 值[除了它是内联级还是块级]。<button>就是其中之一。<fieldset>&<legend>也是。

<button>在元素内添加对 display:flex/grid 和 columnset 布局的支持

用户(丹尼尔·霍尔伯特):

<button>在纯 CSS 中是不可实现的(通过浏览器),所以从 CSS 的角度来看,它们有点像黑盒子。这意味着他们不一定会以与例如 a 相同的方式做出反应<div>

这不是特定于 flexbox 的——例如,如果您放在按钮上,我们不会呈现滚动条,如果您放在overflow:scroll按钮上,我们不会将其呈现为表格display:table

退一步说,这并不是特定于<button>. 考虑<fieldset>并且<table>也有特殊的渲染行为。

老式的 HTML 元素像<button>and<table>并且<fieldset>根本不支持自定义display值,除了为了回答“这个元素是块级还是内联级”这个非常高级的问题,以便在元素周围流动其他内容.

另见:

于 2016-02-17T19:43:51.600 回答
12

这是我最简单的技巧。

button::before,
button::after {
    content: '';
    flex: 1 0 auto;
}
于 2016-11-08T09:39:22.163 回答
1

从 Chrome 83 开始,button现在的工作方式为,您可以在此处inline-grid/grid/inline-flex/flex查看有关此新功能的更多信息

这是一个片段(适用于使用 Chrome 83 及更高版本的用户)

button {
  display: inline-flex;
  height: 2rem;
  align-items: flex-end;
  width: 4rem;
  -webkit-appearance: none;
  justify-content: flex-end;
}
<!-- 

The align-items keyword should fail in Chrome 81 or earlier, but work in Chrome 83 or later. To see the error, the button needs styles that make it more of an extrinsic container. In other words, it needs a height or width set. 
 
-->
<button>Hi</button>
<input type="button" value="Hi">

于 2020-05-31T05:02:56.583 回答