Flexbox not working on button or fieldset elements

2018-12-31 05:08发布

I'm trying to center inner elements of a <button>-tag with flexbox's justify-content: center. But Safari does not center them. I can apply the same style to any other tags and it works as intended (see the <p>-tag). Only the button is left-aligned.

Try Firefox or Chrome and you can see the difference.

Is there any user agent style I have to overwrite? Or any other solution to this problem?

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>

And a jsfiddle: http://jsfiddle.net/z3sfwtn2/2/

2条回答
路过你的时光
2楼-- · 2018-12-31 05:36

The problem is that the <button> element is not designed to be a flex (or grid) container.

At the time of this writing, Webkit-based browsers (Chrome and Safari) adhere to this design principle. Firefox and Edge do not. I didn't test other browsers.

Therefore, you should have no problem making a <button> element a flex (or grid) container in Firefox and Edge. But don't expect it to work in Chrome or Safari.

This behavior currently applies to at least three elements:

  • <button>
  • <fieldset>
  • <legend>

I'm theorizing, but I believe that the idea is to maintain a level of common sense when styling HTML elements. For instance, the HTML gods wanted to prevent authors from turning a button into a table.

However, at least in this case, there is a simple and easy workaround:

Wrap the content of the button in a span, and make the span the flex container.

Adjusted HTML (wrapped button content in a 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>

Adjusted CSS (targeted span)

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

Revised Demo

NOTE: Although they cannot be flex containers, button elements can be flex items.

References:

查看更多
流年柔荑漫光年
3楼-- · 2018-12-31 05:36

Here is my simplest hack.

button::before,
button::after {
    content: '';
    flex: 1 0 auto;
}
查看更多
登录 后发表回答