Html 为什么 <fieldset> 不能是弹性容器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28078681/
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
Why can't <fieldset> be flex containers?
提问by Oriol
I tried to style a fieldset
element with display: flex
and display: inline-flex
.
我试图fieldset
用display: flex
和来设计一个元素display: inline-flex
。
However, it didn't work: flex
behaved like block
, and inline-flex
behaved like inline-block
.
但是,它不起作用:flex
表现得像block
,inline-flex
表现得像inline-block
。
This happens both on Firefox and Chrome, but strangely it works on IE.
这在 Firefox 和 Chrome 上都会发生,但奇怪的是它适用于 IE。
Is it a bug? I couldn't find that fieldset
should have any special behavior, neither in HTML5nor in CSS Flexible Box Layoutspecs.
这是一个错误吗?我找不到它fieldset
应该有任何特殊行为,无论是在HTML5还是CSS 弹性框布局规范中。
fieldset, div {
display: flex;
border: 1px solid;
}
<fieldset>
<p>foo</p>
<p>bar</p>
</fieldset>
<div>
<p>foo</p>
<p>bar</p>
</div>
采纳答案by Oriol
According to Bug 984869 - display: flex
doesn't work for button elements,
根据错误 984869 -display: flex
不适用于按钮元素,
<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>
andwhich also have special rendering behavior:<table>
data:text/html,<fieldset style="display:flex"><div>abc</div><div>def</div>
In these cases, Chrome agrees with us and disregards the
flex
display mode. (as revealed by the fact that "abc" and "def" end up being stacked vertically). The fact that they happen to do what you're expecting on<button style="display:flex">
is likely just due to an implementation detail.In Gecko's button implementation, we hardcode
<button>
(and<fieldset>
,and) as having a specific frame class (and hence, a specific way of laying out the child elements), regardless of the<table>
display
property.If you want to reliably have the children reliably arranged in a particular layout mode in a cross-browser fashion, your best bet is to use a wrapper-div inside the button, just as you would need to inside of
aa<table>
or<fieldset>
.
<button>
不能在纯 CSS 中实现(由浏览器),所以从 CSS 的角度来看,它们有点像黑盒子。这意味着它们不一定以与例如 a 相同的方式做出反应<div>
。这不是 flexbox 特有的——例如,如果您放置
overflow:scroll
按钮,我们不会呈现滚动条,如果您放置按钮,我们不会将其呈现为表格display:table
。退一步说,这不是特定于
<button>
. 考虑<fieldset>
和也有特殊的渲染行为:<table>
data:text/html,<fieldset style="display:flex"><div>abc</div><div>def</div>
在这些情况下,Chrome 会同意我们的意见并无视
flex
显示模式。(正如“abc”和“def”最终垂直堆叠的事实所揭示的那样)。他们碰巧按照您的期望执行的事实<button style="display:flex">
可能只是由于实现细节。在壁虎的按钮实现,我们硬编码
<button>
(和<fieldset>
,和) 作为具有特定的框架类(因此,布局子元素的特定方式),而不管<table>
display
属性如何 。如果您想以跨浏览器的方式可靠地以特定布局模式可靠地安排孩子,最好的办法是在按钮内使用包装器 div,就像您需要在按钮内一样
一个一个<table>
或<fieldset>
。
Therefore, that bug was marked as "resolved invalid".
因此,该错误被标记为“已解决无效”。
There is also Bug 1047590 - display: flex;
doesn't work in <fieldset>
, currently "unconfirmed".
还有错误 1047590 -display: flex;
在 中不起作用<fieldset>
,目前“未确认”。
Good news: Firefox 46+ implements Flexbox for <fieldset>
. See bug 1230207.
好消息:Firefox 46+ 为<fieldset>
. 请参阅错误 1230207。
回答by dippas
I find out this might be a bug on Chrome and Firefox where legend
and fieldset
are replaced elements.
我发现这可能是 Chrome 和 Firefox 上的一个错误,其中legend
和fieldset
被替换元素。
Bugs Reported:
报告的错误:
Bug Chrome(still open)
Bug Firefox(fixed since v46)
错误 Chrome(仍然打开)
错误 Firefox(自 v46 以来已修复)
A possible Workaround:
一个可能的解决方法:
A possible workaround would be using <div role="group">
in HTML, and applying in CSS div[role='group']
as selector.
一种可能的解决方法是<div role="group">
在 HTML 中使用,并在 CSS 中div[role='group']
作为选择器应用。
UPDATE
更新
In Chrome version 83button
can work with the display: inline-grid/grid/inline-flex/flex
, you can see the demo below:
在Chrome 83 版本中button
可以使用display: inline-grid/grid/inline-flex/flex
,你可以看到下面的演示:
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">
回答by Daniel Tonon
Please star the Chrome bug to increase bug priority
请为 Chrome 错误加星号以提高错误优先级
This is a bug in Chrome. Please add a star to this issue to increase it's priority to be fixed: https://bugs.chromium.org/p/chromium/issues/detail?id=375693
这是 Chrome 中的一个错误。请在此问题上加星,以提高修复的优先级:https: //bugs.chromium.org/p/chromium/issues/detail?id=375693
In the mean time, I created these three Code Pen examples to show how to work around the issue. They are built using CSS Grid for the examples but the same techniques can be used for flexbox.
同时,我创建了这三个 Code Pen 示例来展示如何解决这个问题。它们是使用 CSS Grid 构建的示例,但相同的技术可用于 flexbox。
Using aria-labelledby instead of legend
使用 aria-labelledby 而不是legend
This is the more propper way to deal with the problem. The downside is that you have to deal with generating unique IDs applied to every fake legend element.
这是处理问题的更合适的方法。缺点是您必须处理生成应用于每个假图例元素的唯一 ID。
https://codepen.io/daniel-tonon/pen/vaaGzZ
https://codepen.io/daniel-tonon/pen/vaaGzZ
<style>
.flex-container {
display: flex;
}
</style>
<fieldset aria-labelledby="fake-legend">
<div class="flex-container">
<div class="flex-child" id="fake-legend">
I am as good accessibilty wise as a real legend
</div>
...
</div>
</fieldset>
Using role="group" and aria-labelledby instead of fieldset and legend
使用 role="group" 和 aria-labelledby 而不是字段集和图例
If you need the flex-container to be able to stretch to the height of a sibling element and then also pass that stretch onto its children, you will need to use role="group"
instead of <fieldset>
如果您需要 flex-container 能够拉伸到同级元素的高度,然后将该拉伸传递给它的子元素,则需要使用role="group"
而不是<fieldset>
https://codepen.io/daniel-tonon/pen/BayRjGz
https://codepen.io/daniel-tonon/pen/BayRjGz
<style>
.flex-container {
display: flex;
}
</style>
<div role="group" class="flex-container" aria-labelledby="fake-legend">
<div class="flex-child" id="fake-legend">
I am as good accessibilty wise as a real legend
</div>
...
</div>
Creating a fake duplicate legend for styling purposes
为造型目的创建一个假的重复图例
This is a far more hacky way to do it. It is still just as accessible but you don't have to deal with IDs when doing it this way. The main down side is that there is going to be duplicate content between the real legend element and the fake legend element.
这是一种更加hacky的方式来做到这一点。它仍然同样易于访问,但在这样做时您不必处理 ID。主要的缺点是真实的图例元素和假的图例元素之间会有重复的内容。
https://codepen.io/daniel-tonon/pen/zLLqjY
https://codepen.io/daniel-tonon/pen/zLLqjY
<style>
.screen-reader-only {
position: absolute;
opacity: 0;
pointer-events: none;
}
.flex-container {
display: flex;
}
</style>
<fieldset>
<legend class="screen-reader-only">
I am a real screen-reader accessible legend element
</legend>
<div class="flex-container">
<div class="flex-child" aria-hidden="true">
I am a fake legend purely for styling purposes
</div>
...
</div>
</fieldset>
Legend MUST be a direct decendent
传奇必须是直系后裔
When you are first trying to fix this yourself, you will probably try doing this:
当您第一次尝试自己解决此问题时,您可能会尝试这样做:
<!-- DO NOT DO THIS! -->
<fieldset>
<div class="flex-container">
<legend class="flex-child">
Broken semantics legend text
</legend>
...
</div>
</fieldset>
You will discover it works, and then you will probably move on without giving it a second thought.
你会发现它有效,然后你可能会毫不犹豫地继续前进。
The problem is that putting a div wrapper between the fieldset and the legend breaks the relationship between the two elements. This breaks the semantics of fieldset/legend.
问题是在字段集和图例之间放置一个 div 包装器会破坏两个元素之间的关系。这打破了字段集/图例的语义。
So by doing this, you have defeated the whole purpose of using fieldset/legend in the first place.
因此,通过这样做,您首先破坏了使用 fieldset/legend 的全部目的。
Also, there isn't much point in using a fieldset if you don't give that fieldset a legend.
此外,如果您不为该字段集提供图例,则使用该字段集没有多大意义。
回答by paceaux
In my experience, I've found that neither <fieldset>
, nor <button>
, nor <textarea>
can properly use display:flex
or inherited properties.
根据我的经验,我发现,无论是<fieldset>
,也不是<button>
,也<textarea>
可以正常使用display:flex
或继承的属性。
As others have already mentioned, bugs have been reported. If you want to use flexbox to control ordering (e.g. order:2
), then you'd need to wrap the element in a div. If you want flexbox to control actual layout and dimensions, then you may want to consider using a div, instead of the input control (Which stinks, I know).
正如其他人已经提到的,已经报告了错误。如果您想使用 flexbox 来控制排序(例如order:2
),那么您需要将元素包装在一个 div 中。如果您希望 flexbox 控制实际布局和尺寸,那么您可能需要考虑使用 div,而不是输入控件(这很糟糕,我知道)。
回答by Jemy
you can put additional div in <fieldset>
with the following props:
您可以<fieldset>
使用以下道具添加额外的 div :
flex-inner-wrapper {
display: inherit;
flex-flow: inherit;
justify-content: inherit;
align-items: inherit;
}
回答by zcorpan
To answer the original question: yes, it is a bug, but it wasn't well-defined at the time the question was asked.
回答最初的问题:是的,这是一个错误,但在提出问题时并没有明确定义。
Now the rendering for fieldset is better defined: https://html.spec.whatwg.org/multipage/rendering.html#the-fieldset-and-legend-elements
现在对 fieldset 的渲染有了更好的定义:https: //html.spec.whatwg.org/multipage/rendering.html#the-fieldset-and-legend-elements
In Firefox and Safari, flexbox
on fieldset
now works. It doesn't yet in Chromium. (See https://bugs.chromium.org/p/chromium/issues/detail?id=375693)
在Firefox和Safari,flexbox
在fieldset
现在的作品。它还没有在 Chromium 中。(参见https://bugs.chromium.org/p/chromium/issues/detail?id=375693)
Also see https://blog.whatwg.org/the-state-of-fieldset-interoperabilityfor improvements made in the specification in 2018.
另请参阅https://blog.whatwg.org/the-state-of-fieldset-interoperability以了解 2018 年规范中所做的改进。
回答by SharpCode
<div role="group">
<p>foo</p>
<p>bar</p>
</div>
<div>
<p>foo</p>
<p>bar</p>
</div>
Might need to use role-group because firefox, chrome and i think safari have a bug with fieldsets apparently. Then the selector in the CSS would simply be
可能需要使用角色组,因为 firefox、chrome 和我认为 safari 显然有一个带有字段集的错误。那么 CSS 中的选择器就是
div[role='group'], div {
display: flex;
border: 1px solid;
}
Edit:Here are some issues that other people are experiencing as well.
编辑:以下是其他人也遇到的一些问题。