Html Flex / Grid 布局不适用于按钮或字段集元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35464067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Flex / Grid layouts not working on button or fieldset elements
提问by Ingemar
I'm trying to center inner elements of a <button>
-tag with flexbox's justify-content: center
. But Safari does not center them. I can apply the same style to any other tags and it works as intended (see the <p>
-tag). Only the button is left-aligned.
我试图将<button>
-tag 的内部元素与 flexbox 的justify-content: center
. 但是 Safari 不会将它们居中。我可以将相同的样式应用于任何其他标签,并且它按预期工作(请参阅<p>
-tag)。只有按钮是左对齐的。
Try Firefox or Chrome and you can see the difference.
尝试使用 Firefox 或 Chrome,您会看到不同之处。
Is there any user agent style I have to overwrite? Or any other solution to this problem?
是否有我必须覆盖的用户代理样式?或者这个问题的任何其他解决方案?
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>
And a jsfiddle: http://jsfiddle.net/z3sfwtn2/2/
还有一个 jsfiddle:http: //jsfiddle.net/z3sfwtn2/2/
回答by Michael Benjamin
The Problem
问题
In some browsers the <button>
element doesn't accept changes to its display
value, beyond switching between block
and inline-block
. This means that a <button>
element cannot be a flex or grid container, or a <table>
, either.
在某些浏览器中,除了在和之间切换之外,<button>
元素不接受对其display
值的更改。这意味着元素不能是 flex 或 grid 容器,也不能是 。block
inline-block
<button>
<table>
In addition to <button>
elements, you may find this constraint applying to <fieldset>
and <legend>
elements, as well.
除了<button>
元素之外,您可能会发现此约束也适用于<fieldset>
和<legend>
元素。
See the bug reports below for more details.
有关更多详细信息,请参阅下面的错误报告。
Note: Although they cannot be flex containers, <button>
elements can be flex items.
注意:虽然它们不能是弹性容器,但<button>
元素可以是弹性项目。
The Solution
解决方案
There is a simple and easy cross-browser workaround to this problem:
这个问题有一个简单易行的跨浏览器解决方法:
Wrap the content of the button
in a span
, and make the span
the flex container.
将 的内容包裹button
在 a 中span
,并制作span
flex 容器。
Adjusted HTML (wrapped button
content in a span
)
调整后的 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>
Adjusted CSS (targeted span
)
调整后的 CSS(有针对性span
)
button > span, p {
display: flex;
flex-direction: row;
justify-content: center;
}
References / Bug Reports
参考资料/错误报告
Flexbox on a <button>
blockifies the contents but doesn't establish a flex formatting context
a 上的<button>
Flexbox 会阻塞内容,但不会建立 flex 格式上下文
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.
用户(Oriol Brufau):按照 flexbox 规范的规定,的孩子
<button>
被封锁了。然而,<button>
似乎建立了一个块格式上下文而不是一个 flex 上下文。用户 (Daniel Holbert):这实际上是 HTML 规范所要求的。几个 HTML 容器元素是“特殊的”,并且
display
在 Gecko 中有效地忽略了它们的 CSS值[除了它是内联级还是块级]。<button>
是其中之一。<fieldset>
&<legend>
也是。
Add support for display:flex/grid and columnset layout inside <button>
elements
在<button>
元素内添加对 display:flex/grid 和 columnset 布局的支持
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>
不能在纯 CSS 中实现(由浏览器),所以从 CSS 的角度来看,它们有点像黑盒子。这意味着它们不一定以与例如 a 相同的方式做出反应<div>
。这不是 flexbox 特有的——例如,如果您放置
overflow:scroll
按钮,我们不会呈现滚动条,如果您放置按钮,我们不会将其呈现为表格display:table
。退一步说,这不是特定于
<button>
. 考虑<fieldset>
和<table>
也有特殊的渲染行为。老式的 HTML 元素,例如
<button>
and<table>
和<fieldset>
根本不支持自定义display
值,除了为了回答“这个元素是块级还是内联级”这个非常高级的问题,以便在元素周围流动其他内容.
Also see:
另见:
回答by Igari Takeharu
Here is my simplest hack.
这是我最简单的黑客。
button::before,
button::after {
content: '';
flex: 1 0 auto;
}
回答by dippas
Starting Chrome 83, the button
now works as inline-grid/grid/inline-flex/flex
, you can see more about this new feature here
从 Chrome 83 开始,button
现在可以用作inline-grid/grid/inline-flex/flex
,您可以在此处查看有关此新功能的更多信息
Here is a snippet(for those using Chrome 83 and up)
这是一个片段(适用于使用 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">