web-dev-qa-db-fra.com

Utilisation de "margin: 0 auto;" dans Internet Explorer 8

Je suis en train de faire des tests IE8 avancés, et il semble que l'ancienne technique consistant à utiliser margin: 0 auto; ne fonctionne pas dans tous les cas dans IE8.

Le code HTML suivant donne un bouton centré dans FF3, Opera, Safari, Chrome, IE7 et IE8 compat, mais PAS dans la norme IE8:

<div style="height: 500px; width: 500px; background-color: Yellow;">
    <input type="submit" style="display: block; margin: 0 auto;" />
</div>

(En tant que solution de contournement, je peux ajouter une largeur explicite au bouton).

La question est donc: quels navigateurs sont corrects? Ou est-ce l'un de ces cas où le comportement n'est pas défini?

(Je pense que tous les navigateurs sont incorrects - le bouton ne devrait-il pas être 100% largeur s'il est "display: block"?)

UPDATE: Je suis un cancre. Puisque l’entrée n’est pas un élément de niveau bloc, j’aurais simplement dû la contenir dans un div avec "text-align: center". Cela dit, par curiosité, j'aimerais quand même savoir si le bouton doit être centré ou non dans l'exemple ci-dessus.

FOR THE BOUNTY: Je sais que je fais des choses étranges dans l'exemple, et comme je le souligne dans la mise à jour, j'aurais dû simplement aligner son centre. Pour la prime, j'aimerais des références aux spécifications qui réponse:

  1. Si je règle "display: block", le bouton doit-il avoir une largeur de 100%? Ou est-ce indéfini?

  2. Puisque l'affichage est bloqué, "margin: 0 auto;" doit-il centrer le bouton ou non, ou non défini?

80
stusmith

C'est un bug dans IE8.

Commençant par votre deuxième question: "margin: 0 auto" centre un bloc, mais uniquement lorsque la largeur du bloc est définie sur une largeur inférieure à celle du parent. D'habitude, ils deviennent les mêmes. C'est pourquoi le texte de l'exemple ci-dessous n'est pas centré.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
    <b style="display: block; margin: 0 auto; ">text</b>
</div>

Une fois que le style d'affichage de l'élément b est défini sur block, sa largeur correspond par défaut à la largeur des parents. Spéc. CSS 10.3.3 Eléments de niveau bloc non remplacés dans un flux normal explique comment: "Si 'largeur' est réglé sur 'auto', toutes les autres valeurs 'auto' deviennent '0' et 'largeur' découle de l'égalité résultante. ”L'égalité mentionnée il y a

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = largeur du bloc conteneur

Ainsi, normalement, toutes les autos donnent une largeur de bloc égale à la largeur du bloc conteneur.

Toutefois, ce calcul ne doit pas être appliqué à INPUT, qui est un élément remplacé. Les éléments remplacés sont couverts par 10.3.4 Les éléments remplacés au niveau du bloc dans un flux normal . Le texte indique: "La valeur utilisée de" width "est déterminée comme pour les éléments remplacés en ligne." La partie pertinente de 10.3.2 Éléments en ligne remplacés is: “si 'width' a une valeur calculée de 'auto' et que l'élément a une largeur intrinsèque, alors cette largeur intrinsèque est la valeur utilisée de 'width' '.

Je suppose que le scénario dont CSS se soucie est l’élément IMG. Le logo Stackoverflow dans cet exemple sera centré par tous les navigateurs.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
    <img style="display: block; margin: 0 auto; " border="0" src="http://stackoverflow.com/content/img/so/logo.png" alt="">
</div>

L'élément INPUT doit se comporter de la même manière.

71
buti-oxa

Ajouter <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> résout le problème

155
Pal

Oui, vous pouvez lire les spécifications cent fois et combiner différents éléments jusqu'à obtenir une interprétation correcte - mais c'est exactement ce que les éditeurs de navigateurs ont fait et c'est pourquoi nous sommes dans la situation où nous sommes aujourd'hui.

En substance, lorsque vous appliquez une largeur de 100% à un élément, il doit s’étendre à 100% de la largeur de son parent, si ce parent est un élément de bloc. Vous ne pouvez plus le centrer avec margin: 0 auto; _ puisqu’il occupe déjà 100% de la largeur disponible.

Pour centrer n'importe quoi avec margin: 0 auto; vous devez définir une largeur explicite. Pour centrer un élément en ligne, vous pouvez utiliser text-align: center; sur l'élément parent, bien que cela puisse avoir des effets secondaires indésirables si le parent a d'autres enfants.

5
Wolfr

Les contrôles de formulaire sont éléments remplacés en CSS.

10.3.4 Niveau bloc, éléments remplacés en flux normal

La valeur utilisée de 'width' est déterminée comme pour les éléments remplacés en ligne . Ensuite, les règles pour les éléments de niveau bloc non remplacés sont appliquées pour déterminer les marges.

Donc, le contrôle de formulaire ne devrait pas être étendu à 100% de la largeur.

Cependant, il devrait être centré. Cela ressemble à un bug ordinaire dans IE8. Il centre l'élément si vous définissez une largeur spécifique:

<input type="submit" style="display: block; width:100px; margin: 0 auto;" />
5
Kornel

Comme expliqué par buti-oxa, il s'agit d'un problème lié à la manière dont IE8 gère les éléments remplacés. Si vous ne souhaitez pas ajouter de largeur explicite à votre bouton, vous pouvez le remplacer par un bloc en ligne et aligner le contenu au centre:

<div style="height: 500px; width: 500px; background-color: Yellow; text-align: center;">
  <input type="submit" style="display: inline-block;" />
</div>

Si vous voulez que cela fonctionne dans les anciennes versions de Mozilla (y compris FF2) qui ne supporte pas inline-block, vous pouvez ajouter display: -moz-inline-stack; au bouton.

3
Simon Dyson

Une fois de plus: nous détestons tous IE!

<div style="width:100%;background-color:blue;">
    <div style="margin:0 auto;width:300px;background-color:red;">
        Not Working
    </div>
</div>

<div style="width:100%;background-color:green;text-align:center;">
    <div style="margin:0 auto;width:300px;background-color:orange;text-align:left;">
        Working, but dumb that you have to use text-align
    </div>
</div>
2
zeroasterisk

Ajouter <!doctype html> en haut de votre sortie HTML.

2
Mohammad Naji

essayé tout ce qui précède, finissez par le faire

<div style="width:100%; background-color:red; text-align:center;">
        <div style="width:900px; margin:0 auto; background-color:blue;">
            hello
        </div>
    </div>
2
Rouslan Karimov

Pour autant qu'il s'agisse d'un "bug" par rapport à la spécification; ce n'est pas. En tant qu'auteur des questions de l'article, le comportement de ce comportement serait "non défini", car ce comportement dans IE ne se produit que sur les contrôles de formulaire, conformément aux spécifications:

CSS 2.1 ne définit pas les propriétés qui s'appliquent aux contrôles de formulaire et aux cadres, ni comment CSS peut être utilisé pour les styler. Les agents utilisateurs peuvent appliquer des propriétés CSS à ces éléments. Il est recommandé aux auteurs de traiter ce type de support comme étant expérimental.

( http://www.w3.org/TR/CSS21/conform.html#conformance )

À votre santé!

2
Zoffix Znet

le bouton ne devrait pas être 100% largeur si c'est "display: block"

Non, cela signifie simplement que c'est la seule chose dans l'espace verticalement (en supposant que vous n'utilisez pas un autre truc pour forcer autre chose là aussi). Cela ne signifie pas qu'il doit remplir toute la largeur de cet espace.

Je pense que votre problème dans cet exemple est que le input n'est pas nativement un élément de bloc. Essayez de l’emboîter dans une autre div et de définir la marge. Mais je n'ai pas de navigateur IE8 pour tester cela pour le moment, donc c'est juste une supposition.

1
Joel Coehoorn

"margin: 0 auto" centre uniquement un élément dans IE si l'élément parent a un "text-align: center".

1
Chris
  1. En supposant margin: 0 auto alors l'élément doit être centré, mais la largeur est laissée telle quelle - quel que soit son calcul, sans tenir compte des paramètres de marge.
  2. Si vous définissez le <INPUT> tag à display:block, alors il devrait être centré avec margin: 0 auto.

Voir Détails du modèle de formatage visuel - Calcul des largeurs et des marges à partir des spécifications CSS 2.1 pour plus de détails. Les bits pertinents comprennent:

Dans un contexte de formatage de bloc, chaque bord extérieur gauche de la boîte touche le bord gauche du bloc conteneur.

et

Lorsque la largeur totale des zones en ligne sur une ligne est inférieure à la largeur de la zone de ligne les contenant, leur distribution horizontale dans la zone de ligne est déterminée par la propriété 'text-align'.

enfin

Si "width" est réglé sur "auto", toutes les autres valeurs "auto" deviennent "0" et "width" découle de l'égalité résultante.

Si "marge gauche" et "marge droite" sont tous deux "auto", leurs valeurs utilisées sont égales. Cela centre l'élément horizontalement par rapport aux bords du bloc conteneur.

0
Jon Adams