Usando "margin: 0 auto;" en Internet Explorer 8

81

Estoy en el proceso de hacer algunas pruebas avanzadas de IE8, y parece que la antigua técnica de uso margin: 0 auto;no funciona en todos los casos en IE8.

La siguiente pieza de HTML muestra un botón centrado en compatibilidad con FF3, Opera, Safari, Chrome, IE7 e IE8, pero NO en el estándar IE8:

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

(Como solución temporal, puedo agregar un ancho explícito al botón).

Entonces la pregunta es: ¿qué navegadores son correctos? ¿O es este uno de esos casos en los que el comportamiento no está definido?

(Mi opinión es que todos los navegadores son incorrectos, ¿no debería el botón tener un ancho del 100% si es "display: block"?)

ACTUALIZACIÓN: Estoy siendo un tonto. Dado que la entrada no es un elemento a nivel de bloque, debería haberlo contenido dentro de un div con "text-align: center". Habiendo dicho eso, por curiosidad, me gustaría saber si el botón debería o no estar centrado en el ejemplo anterior.

PARA EL BOUNTY: Sé que estoy haciendo cosas raras en el ejemplo y, como señalo en la actualización, debería haberlo alineado en el centro. Para la recompensa, me gustaría referencias a las especificaciones que responden:

  1. Si configuro "display: block", ¿debería el botón tener un ancho del 100%? ¿O es esto indefinido?

  2. Dado que la pantalla es un bloque, debería "margin: 0 auto;" centrar el botón, o no, o indefinido?

herrero
fuente
Será mejor que se apresure: IE8 RTM's hoy y estará disponible para descargar en aproximadamente 2 horas.
Joel Coehoorn
Todavía está en versión beta, por lo que la falta de compatibilidad total con IE8 es solo una de las muchas cosas que se deben solucionar antes del lanzamiento.
stusmith

Respuestas:

71

Es un error en IE8.

Comenzando con su segunda pregunta: “margin: 0 auto” centra un bloque, pero solo cuando el ancho del bloque está configurado para ser menor que el ancho del padre. Por lo general, llegan a ser iguales. Es por eso que el texto del ejemplo siguiente no está centrado.

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

Una vez que el estilo de visualización del elemento b se establece en bloque, su ancho predeterminado es el ancho principal. La especificación CSS 10.3.3 Los elementos no reemplazados a nivel de bloque en el flujo normal describen cómo: "Si 'ancho' se establece en 'auto', cualquier otro valor de 'auto' se convierte en '0' y 'ancho' se sigue de la igualdad resultante . " La igualdad mencionada allí es

'margin-left' + 'border-left-width' + 'padding-left' + 'ancho' + 'padding-right' + 'border-right-width' + 'margin-right' = ancho del bloque contenedor

Entonces, normalmente todos los autos dan como resultado un ancho de bloque igual al ancho del bloque contenedor.

Sin embargo, este cálculo no debe aplicarse a INPUT, que es un elemento reemplazado. Los elementos reemplazados están cubiertos por 10.3.4 Elementos reemplazados a nivel de bloque en flujo normal . El texto allí dice: "El valor usado de 'ancho' se determina como para los elementos reemplazados en línea". La parte relevante de 10.3.2 Elementos reemplazados en línea es: “si 'ancho' tiene un valor calculado de 'auto', y el elemento tiene un ancho intrínseco, entonces ese ancho intrínseco es el valor usado de 'ancho'”.

Supongo que el escenario que le preocupa a CSS es el elemento IMG. El logotipo de Stackoverflow en este ejemplo estará centrado en todos los navegadores.

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

El elemento INPUT debería comportarse de la misma manera.

buti-oxa
fuente
155

Agregar <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">resuelve el problema

Camarada
fuente
13
Sin el DOCTYPE, IE pasa automáticamente al modo de renderizado de Quirks. Útil :-)
Andy McCluggage
7
TAMBIÉN falla si tiene algo antes del tipo de documento (es decir, comentarios, inicio de etiqueta html, etc.)
Shanimal
También con bootstrap rompió todo
user956584
5

Sí, puede leer la especificación cientos de veces y combinar diferentes partes y piezas hasta que tenga una interpretación que se sienta correcta, pero eso es exactamente lo que hicieron los proveedores de navegadores y es por eso que estamos en la situación en la que nos encontramos hoy.

En esencia, cuando aplica un ancho del 100% a un elemento, debe extenderse al 100% del ancho de su padre, si ese padre es un elemento de bloque. No puede centrarlo más con margin: 0 auto;entonces, ya que ocupa el 100% del ancho disponible.

Para centrar cualquier cosa con margin: 0 auto;necesita definir un ancho explícito. Para centrar un elemento en línea, puede usarlo text-align: center;en el elemento principal, aunque esto podría tener efectos secundarios no deseados si el padre tiene otros elementos secundarios.

Wolfr
fuente
5

Los controles de formulario son elementos reemplazados en CSS.

10.3.4 Elementos reemplazados a nivel de bloque en flujo normal

El valor usado de 'ancho' se determina como para los elementos reemplazados en línea . Luego, se aplican las reglas para los elementos a nivel de bloque no reemplazados para determinar los márgenes.

Por lo tanto, el control de formulario no debe extenderse al 100% de ancho.

Sin embargo, debería estar centrado. Parece un error normal en IE8. Centra el elemento si establece un ancho específico:

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

Como lo explica buti-oxa, este es un error con la forma en que IE8 maneja los elementos reemplazados. Si no desea agregar un ancho explícito a su botón, puede cambiarlo a un bloque en línea y alinear el contenido en el centro:

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

Si desea que esto funcione en versiones anteriores de Mozilla (incluido FF2) que no admiten el bloqueo en línea, puede agregarlo display: -moz-inline-stack;al botón.

Simon Dyson
fuente
2

En cuanto a que esto es un "error" en relación con la especificación; no lo es. Como autor de las preguntas de la publicación, el comportamiento para esto sería "indefinido" ya que este comportamiento en IE solo ocurre en los controles de formulario, según las especificaciones:

CSS 2.1 no define qué propiedades se aplican a los controles y marcos de formulario, ni cómo se puede usar CSS para diseñarlos. Los agentes de usuario pueden aplicar propiedades CSS a estos elementos. Se recomienda a los autores que traten dicho apoyo como experimental.

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

¡Salud!


fuente
2

Una vez más: ¡todos odiamos 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>
zeroasterisk
fuente
2

intente todo lo anterior, termine haciendo esto

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

Agregue <!doctype html>en la parte superior de su salida HTML.

Mohammad Naji
fuente
1

¿No debería el botón tener un ancho del 100% si es "display: block"?

No. Eso solo significa que es la única cosa en el espacio verticalmente (asumiendo que no estás usando otro truco para forzar algo más allí también). No significa que tenga que llenar el ancho de ese espacio.

Creo que su problema en este caso es que inputno es un elemento de bloque de forma nativa. Intente anidarlo dentro de otro div y establezca el margen en eso. Pero no tengo un navegador IE8 para probar esto en este momento, así que es solo una suposición.

Joel Coehoorn
fuente
1

"margin: 0 auto" solo centra un elemento en IE si el elemento padre tiene un "text-align: center".

Chris
fuente
0
  1. Suponiendo que margin: 0 autoel elemento debe estar centrado, pero el ancho se deja como está, sea lo que sea que se calcule, sin tener en cuenta la configuración de los márgenes.
  2. Si establece la <INPUT>etiqueta en display:block, debe centrarse con margin: 0 auto.

Consulte Detalles del modelo de formato visual: cálculo de anchos y márgenes a partir de las especificaciones de CSS 2.1 para obtener más detalles. Los bits relacionados incluyen:

En un contexto de formato de bloque, el borde exterior izquierdo de cada cuadro toca el borde izquierdo del bloque contenedor.

y

Cuando el ancho total de los cuadros en línea en una línea es menor que el ancho del cuadro de línea que los contiene, su distribución horizontal dentro del cuadro de línea está determinada por la propiedad 'text-align'.

finalmente

Si 'ancho' se establece en 'auto', cualquier otro valor de 'auto' se convierte en '0' y 'ancho' se sigue de la igualdad resultante.

Si tanto 'margin-left' como 'margin-right' son 'auto', sus valores usados ​​son iguales. Esto centra horizontalmente el elemento con respecto a los bordes del bloque contenedor.

Jon Adams
fuente