我尝试用display: flex和display: inline-flex样式fieldset元素。

然而,它并没有起作用:flex表现得像块,而内联flex表现得像内联块。

火狐和Chrome浏览器都是这样,但奇怪的是IE浏览器却可以。

是bug吗?我找不到fieldset应该有任何特殊的行为,无论是在HTML5还是在CSS Flexible Box Layout规范。

字段集,div { 显示:flex; 边框:1px实体; } <自定义字段> foo < p > < / p > 酒吧< p > < / p > < /自定义字段> < div > foo < p > < / p > 酒吧< p > < / p > < / div >


<div role="group">
    <p>foo</p>
    <p>bar</p>
</div>
<div>
    <p>foo</p>
    <p>bar</p>
</div>

可能需要使用角色组,因为firefox, chrome和我认为safari有一个bug与字段集明显。那么CSS中的选择器就是

div[role='group'], div {
    display: flex;
    border: 1px solid;
}

编辑:这里有一些其他人也在经历的问题。

发行375693

发行262679


我发现这可能是一个错误在Chrome和Firefox的传说和字段集替换元素。

错误报告:

Bug Chrome(自v86以来修复) Firefox Bug(自v46以来修复)

一个可行的解决方案:

一个可能的解决办法是在HTML中使用<div role="group">,并在CSS中应用div[role='group']作为选择器。


更新

在Chrome 83版按钮可以工作显示:inline-grid/grid/inline-flex/flex,你可以看到下面的演示:

按钮{ 显示:inline-flex; 高度:2快速眼动; 对齐项目:flex-end; 宽度:4快速眼动; -webkit-appearance:没有; justify-content: flex-end; } <!-- align-items关键字应该在Chrome 81或更早版本中失败,但在Chrome 83或更高版本中工作。要查看错误,按钮需要使其更像外部容器的样式。换句话说,它需要一个高度或宽度集。 --> <按钮>你好> < /按钮 <input type="button" value="Hi">


根据Bug 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 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: 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 <table>) as having a specific frame class (and hence, a specific way of laying out the child elements), regardless of the 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 a <table> or a <fieldset>.

因此,该错误被标记为“已解决无效”。

还有Bug 1047590 - display: flex;不工作在<fieldset>,目前“未确认”。


好消息:Firefox 46+实现了<fieldset>的Flexbox。参见bug 1230207。


根据我的经验,我发现无论是<fieldset>,或<button>,或<textarea>都不能正确使用display:flex或继承属性。

正如其他人已经提到的,已经报告了错误。如果你想要使用flexbox来控制排序(例如order:2),那么你需要将元素包装在div中。如果你想要flexbox来控制实际的布局和尺寸,那么你可能会考虑使用div,而不是输入控件(这很糟糕,我知道)。


你可以用下面的道具在<fieldset>中添加额外的div:

flex-inner-wrapper {
  display: inherit;
  flex-flow: inherit;
  justify-content: inherit;
  align-items: inherit;
}

回答最初的问题:是的,这是一个bug,但在提出问题时并没有明确定义。

现在fieldset的呈现有了更好的定义:https://html.spec.whatwg.org/multipage/rendering.html#the-fieldset-and-legend-elements

在Firefox和Safari中,flexbox on fieldset现在工作。在铬中还没有。(见https://bugs.chromium.org/p/chromium/issues/detail?id=375693)

参见https://blog.whatwg.org/the-state-of-fieldset-interoperability了解2018年规范的改进。


请在Chrome bug上加星号以增加bug优先级

这是Chrome的一个bug。请在此问题上添加一个星号,以增加其需要修复的优先级: https://bugs.chromium.org/p/chromium/issues/detail?id=375693

与此同时,我创建了这三个Code Pen示例来展示如何解决这个问题。它们是使用CSS Grid为示例构建的,但同样的技术也可以用于flexbox。

用aria- labeling by代替legend

这是处理这个问题更为恰当的方法。缺点是您必须处理生成应用于每个假图例元素的唯一id。

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>

使用role="group"和aria- labels by代替fieldset和legend

如果你需要flex容器能够拉伸到兄弟元素的高度,然后将拉伸传递给它的子元素,你将需要使用role="group"而不是<fieldset>

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>

为样式目的创建一个假的重复图例

这是一种更俗气的方法。它仍然是可访问的,但当这样做时,你不必处理id。主要的缺点是在真实的传说元素和虚假的传说元素之间会有重复的内容。

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>

传说必须是直系后裔

当你第一次尝试自己修复这个问题时,你可能会尝试这样做:

<!-- DO NOT DO THIS! -->
<fieldset>
    <div class="flex-container">
        <legend class="flex-child">
            Broken semantics legend text
        </legend>

        ...

    </div>
</fieldset>

你会发现它很有效,然后你可能会毫不犹豫地继续前进。

问题是在字段集和图例之间放置一个div包装器破坏了两个元素之间的关系。这打破了fieldset/legend的语义。

这样一来,你就违背了使用fieldset/legend的初衷。

同样,如果您不给字段集一个图例,那么使用字段集也没有多大意义。