web-dev-qa-db-ja.com

Flexboxボタンまたはフィールドセット要素で動作していません

<button>-タグの内部要素をflexboxのjustify-content: centerで中央揃えしようとしています。しかし、Safariはそれらを中央に配置しません。同じスタイルを他のタグに適用でき、意図したとおりに機能します(<p>- tagを参照)。ボタンのみが左揃えです。

FirefoxまたはChromeを試してみると、違いがわかります。

上書きする必要があるユーザーエージェントスタイルはありますか?または、この問題に対する他の解決策はありますか?

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>

そして、jsfiddle: http://jsfiddle.net/z3sfwtn2/2/

76
Ingemar

問題

問題は、一部のブラウザーが<button>要素をまだフレックス(またはグリッド)コンテナーとして設計していないことです。

より技術的には、一部のブラウザでは、<button>要素は、displayinline-blockからの切り替えを超えて、そのblock値への変更を受け入れません。これは、<button>要素を<table>にすることもできないことを意味します。

この動作は、<fieldset>および<legend>要素にも適用される場合があります。

詳細については、以下のバグレポートをご覧ください。

注:フレックスコンテナにすることはできませんが、<button>要素はフレックスアイテムにすることができます。


ソリューション

この問題に対する簡単で簡単なクロスブラウザ回避策があります。

buttonのコンテンツをspanでラップし、spanをフレックスコンテナにします。

調整されたHTML(buttonコンテンツを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>

調整済みCSS(_spanをターゲットに)

button > span, p {
    display: flex;
    flex-direction: row;
    justify-content: center;
}

改訂デモ


参考資料/バグレポート

<button>上のFlexboxはコンテンツをブロックしますが、Flexフォーマットコンテキストを確立しません

ユーザー(Oriol Brufau):flexbox仕様の指示に従って、<button>の子はブロックされます。ただし、<button>は、フレックスの代わりにコンテキストをフォーマットするブロックを確立するようです。

ユーザー(ダニエル・ホルバート):これは事実上、HTML仕様が要求するものです。いくつかのHTMLコンテナ要素は「特別」であり、GeckoのCSS display値を事実上無視します(インラインレベルかブロックレベルかは別として)。 <button>はこれらの1つです。 <fieldset><legend>も同様です。

display:flex/gridおよび<button>要素内の列セットレイアウトのサポートを追加

ユーザー(ダニエル・ホルバート):

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

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

さらに一歩下がって、これは<button>に固有のものではありません。 <fieldset><table>も考慮してください。これらも特別なレンダリング動作を持っています。

そして<button><table><fieldset>のような昔ながらのHTML要素は、応答の目的以外では、カスタムdisplay値をサポートしていません。要素の周りに他のコンテンツを流すための「この要素はブロックレベルかインラインレベルか」という非常に高レベルの質問。

以下も参照してください。

110
Michael_B

これが私の最も簡単なハックです。

button::before,
button::after {
    content: '';
    flex: 1 0 auto;
}
12
Igari Takeharu