web-dev-qa-db-fra.com

Flexbox ne fonctionne pas sur les éléments button et fieldset

J'essaie de centrer les éléments internes d'un tag <button> Avec le justify-content: center De flexbox. Mais Safari ne les centre pas. Je peux appliquer le même style à toutes les autres balises et cela fonctionne comme prévu (voir la balise <p>). Seul le bouton est aligné à gauche.

Essayez Firefox ou Chrome et vous pourrez voir la différence.

Y a-t-il un style d'agent utilisateur que je dois écraser? Ou toute autre solution à ce problème?

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>

Et un jsfiddle: http://jsfiddle.net/z3sfwtn2/2/

76
Ingemar

Le problème

Le problème est que certains navigateurs n’ont pas encore conçu l’élément <button> Pour qu’il soit un conteneur flex (ou grid).

Plus techniquement, dans certains navigateurs, l'élément <button> N'accepte pas les modifications apportées à sa valeur display, au-delà du passage de block à inline-block. Cela signifie qu'un élément <button> Ne peut pas non plus être un <table>.

Vous pouvez trouver que ce comportement s'applique également aux éléments <fieldset> Et <legend>.

Voir les rapports de bogues ci-dessous pour plus de détails.

Remarque: bien qu'ils ne puissent pas être des conteneurs flex, les éléments <button> Peuvent être des éléments flex.


La solution

Il existe une solution simple et facile entre navigateurs pour résoudre ce problème:

Enveloppez le contenu du button dans un span et créez le span comme conteneur flex.

HTML ajusté (contenu button encapsulé dans un 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 ajusté (ciblé span)

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

démo révisée


Références/Rapports de bogues

La Flexbox sur un <button> Bloque le contenu mais n'établit pas de contexte de formatage flexible

Utilisateur (Oriol Brufau): Les enfants du <button> Sont bloqués, comme l'indique le flexbox spec. Cependant, le <button> Semble établir un contexte de formatage de bloc au lieu d'un contexte flex.

Utilisateur (Daniel Holbert): C’est ce qui est requis par la spécification HTML. Plusieurs éléments de conteneur HTML sont "spéciaux" et ignorent effectivement leur valeur CSS display dans Gecko [indépendamment du fait que ce soit en ligne ou au niveau du bloc]. <button> En fait partie. <fieldset> & <legend> Le sont aussi.

Ajout du support pour display: layout flex/grid et columnset dans les éléments <button>

Utilisateur (Daniel Holbert):

<button> N'est pas implémentable (par les navigateurs) en CSS pur; ils sont donc un peu comme une boîte noire, du point de vue de CSS. Cela signifie qu'ils ne réagissent pas nécessairement de la même manière que, par exemple. un <div> serait.

Ceci n'est pas spécifique à flexbox - par exemple, nous ne rendons pas les barres de défilement si vous mettez overflow:scroll Sur un bouton et nous ne le rendons pas comme une table si vous mettez display:table dessus.

Reculant encore plus loin, ce n'est pas spécifique à <button>. Considérons <fieldset> Et <table> Qui ont également un comportement de rendu spécial.

Et les anciens éléments HTML tels que <button> Et <table> Et <fieldset> Ne prennent tout simplement pas en charge les valeurs personnalisées display, à des fins autres que répondant à la question de très haut niveau de "est cet élément au niveau du bloc ou au niveau de la ligne", pour faire circuler un autre contenu autour de l'élément.

Regarde aussi:

110
Michael_B

Voici mon hack le plus simple.

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