为什么<fieldset>不能成为flex容器?

Ori*_*iol 166 html css css3 flexbox

我尝试fieldsetdisplay: flex和设置元素的样式display: inline-flex.

但是,它不起作用:flex表现得像block,inline-flex表现得像inline-block.

这在Firefox和Chrome上都会发生,但奇怪的是它适用于IE.

这是一个错误吗?我无法fieldsetHTML5CSS Flexible Box Layout规范中找到任何特殊行为.

fieldset, div {
    display: flex;
    border: 1px solid;
}
Run Code Online (Sandbox Code Playgroud)
<fieldset>
    <p>foo</p>
    <p>bar</p>
</fieldset>
<div>
    <p>foo</p>
    <p>bar</p>
</div>
Run Code Online (Sandbox Code Playgroud)

Ori*_*iol 123

根据Bug 984869 - display: flex对按钮元素不起作用,

<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>
Run Code Online (Sandbox Code Playgroud)

在这些情况下,Chrome同意我们并忽略flex 显示模式.(正如"abc"和"def"最终被垂直堆叠的事实所揭示的那样).事实上,他们碰巧做了你期望的事情<button style="display:flex">可能只是由于实施细节.

在Gecko的按钮实现中,我们硬编码<button>(和 <fieldset>,<table>)具有特定的框架类(因此,布置子元素的特定方式),无论display属性如何 .

如果你想让孩子们以跨浏览器的方式可靠地安排在特定的布局模式中,最好的办法就是在按钮内部使用一个包装器div,就像你需要的一样. 一个<table>a <fieldset>.

因此,该错误被标记为"已解决无效".

还有Bug 1047590 - display: flex;不起作用<fieldset>,目前"未经证实".


好消息:Firefox 46+实现了Flexbox <fieldset>.见错误1230207.

  • 2017年确实.我在哪里指出我的愤怒?多年等待安全地实施flexbox,无数文章,tutes,试验/错误,我得到98%和... fieldsets.这就像让电工连接我的房子,却发现一个电源插座没有接地."不要夸大"我听到人们的想法,夸大我不这样做.我明天必须回答这个问题.Flex是我需要解决的几个遗留表错误的答案.Flex现在是少数非传统错误的原因.我在哪里指出我的愤怒? (5认同)
  • @BoltClock不确定你的意思是什么.自2015年以来,所有主流浏览器都支持语法的第三次和最后一次修订; 我认为,互操作性非常好.我们现在甚至得到了对Grid的广泛支持! (4认同)
  • `<button>在纯CSS中无法实现(通过浏览器) - 这是错误的.浏览器可以自由地实现一个`<button>`,但是他们并没有"合同义务"使用系统小部件库或其他任何东西来渲染它,这会削弱使用CSS或其他自定义行为来设置这些样式的能力.同样适用于任何其他元素. (3认同)

Dan*_*non 19

请为 Chrome 错误加星号以提高错误优先级

这是 Chrome 中的一个错误。请在此问题上加星,以提高修复的优先级:https : //bugs.chromium.org/p/chromium/issues/detail?id=375693

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

使用 aria-labelledby 而不是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>
Run Code Online (Sandbox Code Playgroud)

使用 role="group" 和 aria-labelledby 而不是字段集和图例

如果您需要 flex-container 能够拉伸到同级元素的高度,然后将该拉伸传递给它的子元素,则需要使用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>
Run Code Online (Sandbox Code Playgroud)

为造型目的创建一个假的重复图例

这是一种更加hacky的方式来做到这一点。它仍然同样易于访问,但在这样做时您不必处理 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>
Run Code Online (Sandbox Code Playgroud)

传奇必须是直系后裔

当您第一次尝试自己解决此问题时,您可能会尝试这样做:

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

        ...

    </div>
</fieldset>
Run Code Online (Sandbox Code Playgroud)

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

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

因此,通过这样做,您首先破坏了使用 fieldset/legend 的全部目的。

此外,如果您不为该字段集提供图例,则使用该字段集没有多大意义。


dip*_*pas 16

我发现这可能是Chrome和Firefox上的一个错误,其中legendfieldset替换的元素.

臭虫报道:

Bug Chrome
Bug Firefox

可能的解决方法:

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


pac*_*aux 9

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

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