<fieldset>をフレックスコンテナーにできないのはなぜですか?


201

私はスタイルにしようとしたfieldsetとの要素をdisplay: flexdisplay: inline-flex

ただし、機能しませんでした。のflexようblockに動作し、のようにinline-flex動作しましたinline-block

これはFirefoxとChromeの両方で発生しますが、不思議なことにIEでは機能します。

バグですか?HTML5でも、CSSフレキシブルボックスレイアウトの仕様fieldsetでも、特別な動作があるはずです。

fieldset, div {
    display: flex;
    border: 1px solid;
}
<fieldset>
    <p>foo</p>
    <p>bar</p>
</fieldset>
<div>
    <p>foo</p>
    <p>bar</p>
</div>


2
はい、それはバグです。単純な修正:別の要素を使用します。code.google.com/p/chromium/issues/detail?id=262679
Adam

回答:


145

バグ984869にdisplay: flexよると、ボタン要素は機能しません

<button>は純粋なCSSでは(ブラウザでは)実装できないため、CSSの観点からすると、これらは少しブラックボックスです。これは、彼らが必ずしも同じように反応するわけではないことを意味し<div>ます。

これはフレックスボックスに固有のものではありません。たとえばoverflow:scroll、ボタンを配置した場合はスクロールバーをレンダリングせず、ボタンを配置した場合はテーブルとしてレンダリングしませんdisplay:table

さらに後退し<button>ますが、これはに固有のものではありません。検討する <fieldset> そして <table> 特別なレンダリング動作もあります:

data:text/html,<fieldset style="display:flex"><div>abc</div><div>def</div>

このような場合、ChromeはGoogleに同意し、flex 表示モードを無視します。(「abc」と「def」が最終的に垂直にスタックされるという事実によって明らかにされるように)。彼らがあなたが期待していることを偶然に行っているという事実<button style="display:flex">は、おそらく実装の詳細が原因である可能性があります。

Geckoのボタン実装では、ハードコーディングします<button>(そして <fieldset>そして <table>displayプロパティに関係なく、特定のフレームクラス(したがって、子要素をレイアウトする特定の方法)を持つものとして 。

特定のレイアウトモードでクロスブラウザ方式で確実に子を配置したい場合は、ボタンの内側でwrapper-divを使用するのが最善です。 <table>若しくはA <fieldset>

したがって、そのバグは「解決された無効」としてマークされました。

バグ1047590display: flex;<fieldset>もあります- では動作しませんが、現在「未確認」です。


朗報:Firefox 46以降ではFlexbox forが実装されてい<fieldset>ます。バグ1230207を参照してください。


flexboxが8年間乱暴になっていることを考えると、私は「著しく」少し誇張していることがわかります。どちらかと言えば、Firefoxですぐに動作することに驚いています。多分あなたはグーグルで物事をキックアップするのを手伝いたいと思います(ええ、それを得る?)。
BoltClock

3
<button> is not implementable (by browsers) in pure CSS-それは間違っています。ブラウザは自由に実装<button>できますが、システムウィジェットライブラリなどを使用してレンダリングすることは「契約上義務付けられている」わけではなく、CSSまたは他のカスタム動作でこれらをスタイルする機能を損ないます。同じことが他の要素にも当てはまります。
午前

4
@BoltClock limboの意味がわからない。すべての主要なブラウザーは、2015年以降の構文の3番目で最後のリビジョンをサポートしています。相互運用性はかなり良いと思います。今ではグリッドの幅広いサポートも受けています!🎉
ŠimeVidas

@ŠimeVidas:なるほど、今は1年間CRだったようです。けっこうだ。私はそれを作るつもりはないと思っていました。
BoltClock

9
確かに2017年。怒りはどこに向けるのですか?フレックスボックス、無数の記事、チュート、試行錯誤を安全に実装するために何年も待っていたところ、98%がそこにあり...フィールドセットです。電気技師に家の配線を依頼するようなもので、電源ジャックが1つもアースされていないことがわかります。「大げさに言わないで」人々はそう思うが、大げさではないと思うと思う。私は文字通りこれについて明日答えなければなりません。フレックスは、私が解決する必要があったいくつかのレガシーテーブルバグの答えでした。Flexは、少数のレガシー以外のバグの原因となっています。怒りはどこに向けるのですか?
ダンジャ2017

20

私は、これはChromeとFirefoxの上のバグかもしれない見つけるlegendfieldsetされている要素を置き換えます

報告されたバグ:

バグChrome(まだオープン)
バグFirefox(v46以降で修正)

可能な回避策:

可能な回避策は<div role="group">、HTMLで使用し、div[role='group']セレクターとしてCSSに適用することです。


更新

では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">


11

バグの優先度を上げるには、Chromeバグにスターを付けてください

これはChromeのバグです。修正する優先度を上げるには、この問題にスターを追加してください:https : //bugs.chromium.org/p/chromium/issues/detail?id=375693

それまでの間、この問題を回避する方法を示すために、これら3つのコードペンの例を作成しました。これらは例としてCSSグリッドを使用して構築されていますが、同じ手法をflexboxにも使用できます。

凡例の代わりにaria-labelledbyを使用する

これは、問題に対処するためのより適切な方法です。欠点は、すべての偽の凡例要素に適用される一意の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-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>

スタイリングのために偽の複製凡例を作成する

これは、はるかにハックな方法です。引き続きアクセス可能ですが、この方法で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ラッパーを配置すると、2つの要素間の関係が壊れることです。これはフィールドセット/レジェンドのセマンティクスを壊します。

したがって、これを行うことで、最初にfieldset / legendを使用するという目的全体を打ち破っています。

また、フィールドセットに凡例を指定しない限り、フィールドセットを使用してもあまり意味がありません。


9

私の経験では、も<fieldset>、も<button><textarea>適切に使用しdisplay:flexたり、継承したりすることはできないことに気づきました。

他の人がすでに述べたように、バグが報告されています。flexboxを使用して順序を制御する場合(例:)order:2、要素をdivでラップする必要があります。flexboxで実際のレイアウトと寸法を制御したい場合は、入力コントロールではなく、divの使用を検討することをお勧めします(これは臭いです)。


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

firefox、chrome、safariには明らかにフィールドセットにバグがあるため、役割グループを使用する必要があるかもしれません。次に、CSSのセレクターは単に

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

編集:他の人々が同様に経験しているいくつかの問題があります。

問題375693

問題262679


これはまだクローム60内の問題である
evolutionxbox

まだここクローム66中
ブラッド・

Chrome 72がチェックイン
danemacmillan

Chrome 73のチェックイン
Michael Draper

Chrome 75のチェックイン
-xaddict

3

<fieldset>次の小道具で追加のdivを配置できます。

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

1
私は反対票を理解していません。これは実際に正しいです。しかし、維持するために覚えている<legend>のトップレベルに(使用する場合)の要素を<fieldset>意図したように、その使用を維持するための要素(Permitted content: An optional <legend> element, followed by flow content.-参照developer.mozilla.org/en-US/docs/Web/HTML/Element/...を
Froxx

2
それは私ではありませんでしたが、反対票が質問に答えないことと関係があると想像する必要があります。回避策を見つけることではなく、fieldsetそれ自体の動作です。
Manngo

はい、質問に直接答えることはできません(これは少し哲学的でした)が、これはこのばかげたバグを修正する可能性があります。
エリックS.ブリントン

<legend>要素のセマンティクスを壊すことを奨励するため、反対票が投じられました。これは、そもそもfieldset / legendを使用する目的に反します。ここで私の答えを参照してください:stackoverflow.com/a/59425373/1611058
Daniel Tonon

3

元の質問に答えるために:はい、それはバグですが、質問された時点では明確に定義されていませんでした。

これで、フィールドセットのレンダリングがより明確になりました:https : //html.spec.whatwg.org/multipage/rendering.html#the-fieldset-and-legend-elements

FirefoxとSafariではflexboxfieldsetこれで機能します。まだChromiumにはありません。(https://bugs.chromium.org/p/chromium/issues/detail?id=375693を参照してください

2018年に仕様で行われた改善については、https://blog.whatwg.org/the-state-of-fieldset-interoperabilityも参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.