Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flex / Grid layouts not working on button or fieldset elements

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/

like image 863
Ingemar Avatar asked Feb 17 '16 17:02

Ingemar


People also ask

Does Fieldset support flexbox?

1 Does not support flexbox and grid layouts within this element.

Can buttons be flex items?

In addition to <button> elements, you may find this constraint applying to <fieldset> and <legend> elements, as well. See the bug reports below for more details. Note: Although they cannot be flex containers, <button> elements can be flex items.

How do I make my flex grid responsive?

Creating the responsive gridUsing display: flex , our grid-row stretches to the full size of the container. We use flex-flow: wrap to designate that child divs (our columns/grid-items) should wrap if they exceed the width of the row. Then, flex-flow: row means our grid-items will flex from left to right.


Video Answer


2 Answers

The Problem

In some browsers the <button> element doesn't accept changes to its display value, beyond switching between block and inline-block. This means that a <button> element cannot be a flex or grid container, or a <table>, either.

In addition to <button> elements, you may find this constraint applying to <fieldset> and <legend> elements, as well.

See the bug reports below for more details.

Note: Although they cannot be flex containers, <button> elements can be flex items.


The Solution

There is a simple and easy cross-browser workaround to this problem:

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


References / Bug Reports

Flexbox on a <button> blockifies the contents but doesn't establish a flex formatting context

User (Oriol Brufau): The children of the <button> are blockified, as dictates the flexbox spec. However, the <button> seems to establish a block formatting context instead of a flex one.

User (Daniel Holbert): That is effectively what the HTML spec requires. Several HTML container-elements are "special" and effectively ignore their CSS display value in Gecko [aside from whether it's inline-level vs. block-level]. <button> is one of these. <fieldset> & <legend> are as well.

Add support for display:flex/grid and columnset layout inside <button> elements

User (Daniel Holbert):

<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.

And old-timey HTML elements like <button> and <table> and <fieldset> simply do not support custom display values, other than for the purposes of answering the very high-level question of "is this element block-level or inline-level", for flowing other content around the element.

Also see:

  • Flexbug #9: Some HTML elements can't be flex containers
  • 10. Some HTML elements can't be grid containers
like image 187
Michael Benjamin Avatar answered Oct 12 '22 13:10

Michael Benjamin


Here is my simplest hack.

button::before, button::after {     content: '';     flex: 1 0 auto; } 
like image 38
Igari Takeharu Avatar answered Oct 12 '22 12:10

Igari Takeharu