Flex / Grid 布局不适用于按钮或字段集元素
Flex / Grid layouts not working on button or fieldset elements
我正在尝试将 <button>
标签的内部元素与 flexbox 的 justify-content: center
居中。但 Safari 不会将它们居中。我可以将相同的样式应用于任何其他标签,并且它按预期工作(请参阅 <p>
-标签)。只有按钮是左对齐的。
试试 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/
问题
在某些浏览器中,<button>
元素不接受对其 display
值的更改,除了在 block
和 inline-block
之间切换。这意味着 <button>
元素不能是弹性或网格容器,也不能是 <table>
。
除了 <button>
元素之外,您可能会发现此约束也适用于 <fieldset>
和 <legend>
元素。
有关详细信息,请参阅下面的错误报告。
注意:虽然它们不能是弹性容器,但 <button>
个元素可以是弹性项目。
解决方案
这个问题有一个简单易行的跨浏览器解决方法:
将 button
的内容包装在 span
中,并使 span
成为 flex 容器。
已调整 HTML(将 button
内容包装在 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;
}
参考资料/错误报告
Flexbox on a <button>
blockifies the contents but doesn't establish a flex formatting context
User (Oriol Brufau): The children of the <button>
are blockified, as dictates the flexbox spec. However, the <button>
seems to establish a block formatting context instead of a flex one.
User (Daniel Holbert): That is effectively what the HTML spec requires. Several HTML container-elements are "special" and effectively ignore their CSS display
value in Gecko [aside from whether it's inline-level vs. block-level]. <button>
is one of these. <fieldset>
& <legend>
are as well.
Add support for display:flex/grid and columnset layout inside <button>
elements
User (Daniel Holbert):
<button>
is not implementable (by browsers) in pure CSS, so they are a bit of a black box, from the perspective of CSS. This means that
they don't necessarily react in the same way that e.g. a <div>
would.
This isn't specific to flexbox -- e.g. we don't render scrollbars if you put overflow:scroll
on a button, and we don't render it as a
table if you put display:table
on it.
Stepping back even further, this isn't specific to <button>
. Consider <fieldset>
and <table>
which also have special rendering
behavior.
And old-timey HTML elements like <button>
and <table>
and <fieldset>
simply do not support custom display
values, other than
for the purposes of answering the very high-level question of "is this
element block-level or inline-level", for flowing other content around
the element.
另见:
这是我最简单的技巧。
button::before,
button::after {
content: '';
flex: 1 0 auto;
}
从 Chrome 83 开始,button
现在作为 inline-grid/grid/inline-flex/flex
使用,您可以查看有关此新功能的更多信息 here
这是一个片段(对于使用 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">
我正在尝试将 <button>
标签的内部元素与 flexbox 的 justify-content: center
居中。但 Safari 不会将它们居中。我可以将相同的样式应用于任何其他标签,并且它按预期工作(请参阅 <p>
-标签)。只有按钮是左对齐的。
试试 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/
问题
在某些浏览器中,<button>
元素不接受对其 display
值的更改,除了在 block
和 inline-block
之间切换。这意味着 <button>
元素不能是弹性或网格容器,也不能是 <table>
。
除了 <button>
元素之外,您可能会发现此约束也适用于 <fieldset>
和 <legend>
元素。
有关详细信息,请参阅下面的错误报告。
注意:虽然它们不能是弹性容器,但 <button>
个元素可以是弹性项目。
解决方案
这个问题有一个简单易行的跨浏览器解决方法:
将 button
的内容包装在 span
中,并使 span
成为 flex 容器。
已调整 HTML(将 button
内容包装在 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;
}
参考资料/错误报告
Flexbox on a <button>
blockifies the contents but doesn't establish a flex formatting context
User (Oriol Brufau): The children of the
<button>
are blockified, as dictates the flexbox spec. However, the<button>
seems to establish a block formatting context instead of a flex one.User (Daniel Holbert): That is effectively what the HTML spec requires. Several HTML container-elements are "special" and effectively ignore their CSS
display
value in Gecko [aside from whether it's inline-level vs. block-level].<button>
is one of these.<fieldset>
&<legend>
are as well.
Add support for display:flex/grid and columnset layout inside <button>
elements
User (Daniel Holbert):
<button>
is not implementable (by browsers) in pure CSS, so they are a bit of a black box, from the perspective of CSS. This means that they don't necessarily react in the same way that e.g. a<div>
would.This isn't specific to flexbox -- e.g. we don't render scrollbars if you put
overflow:scroll
on a button, and we don't render it as a table if you putdisplay:table
on it.Stepping back even further, this isn't specific to
<button>
. Consider<fieldset>
and<table>
which also have special rendering behavior.And old-timey HTML elements like
<button>
and<table>
and<fieldset>
simply do not support customdisplay
values, other than for the purposes of answering the very high-level question of "is this element block-level or inline-level", for flowing other content around the element.
另见:
这是我最简单的技巧。
button::before,
button::after {
content: '';
flex: 1 0 auto;
}
从 Chrome 83 开始,button
现在作为 inline-grid/grid/inline-flex/flex
使用,您可以查看有关此新功能的更多信息 here
这是一个片段(对于使用 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">