multiline-flexbox en IE11 calculando anchos incorrectamente?


Parece que IE11 no calcula correctamente los anchos de elementos flexibles si se utiliza flex-wrap: wrap.

Véase http://jsfiddle.net/MartijnR/WRn9r/6 /

Las 4 cajas cada una tienen una base flexible: 50%, por lo que debemos obtener dos líneas de dos cajas cada una, pero en IE11 cada caja obtiene una línea. Al establecer el borde a 0, funciona correctamente.

¿Alguna idea si esto es un error, o si hay una manera de hacer que IE11 se comporte (y todavía use bordes)?

<section>
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
</section>
section {
    display: -moz-flex;
    display: -webkit-flex;
    display: flex;
    -moz-flex-direction: row;
    -webkit-flex-direction: row;
    flex-direction: row;
    -moz-flex-wrap: wrap;
    -webkit-flex-wrap: wrap;
    flex-wrap: wrap;
    width: 100%;
    box-sizing:border-box;
    margin:0;
}
.box {
    border: 1px solid black;
    background: #ccc;
    display: block;
    -ms-flex: 50%;
    -moz-flex: 50%;
    -webkit-flex: 50%;
    flex: 50%;
    box-sizing: border-box;
    margin:0;
}

P.d. En mi proyecto solo la última versión de los navegadores populares necesita ser compatible, afortunadamente, pero IE11 es uno de ellos.

Author: Martijn van de Rijdt, 2014-02-21

4 answers

Parece un error donde box-sizing no se está teniendo en cuenta al calcular el tamaño usando la propiedad flex. Como el borde ocupa 2px, es más grande que el 50% y por lo tanto solo uno cabe en una línea, por lo que todas las cajas se estiran a todo el ancho. Puede ver lo mismo sucediendo si deshabilita el borde y agrega relleno 2px en su lugar.

Puede hacer que funcione correctamente mientras mantiene los bordes agregando max-width: 50% al conjunto de reglas .box. De lo contrario, puede utilizar un valor flex entre 33.34% y 49%. Esto hará que el ancho sea inferior al 50%, incluido el borde, y a medida que los elementos crezcan para llenar el espacio disponible, seguirán siendo el 50% del contenedor flexible. Una especie de truco feo, pero funcionará a menos que agregue un borde combinado y un relleno mayor del 50% menos el valor de flexión que estableció.

Quizás una mejor manera de disminuir el valor porcentual directamente es usar calc(). Esto es soportado por todos los navegadores que soportan la sintaxis moderna de Flexbox. Solo tienes que restar el total combinado de los rellenos izquierdo y derecho y los márgenes del valor porcentual que desea usar. Al hacer esto, realmente no necesita la propiedad de tamaño de la caja para que pueda eliminarse. Parece haber otro problema en IE donde no se puede usar calc en la abreviatura flex, pero se puede usar en la propiedad flex-basis, que es la que desea.

.box {
    border: 1px solid black;
    /* additional styles removed for clarity */

    /* 
    50% - (border-left-width + border-right-width +
           padding-left + padding-right)
    */
    -webkit-flex-basis: calc(50% - 2px);
    flex-basis: calc(50% - 2px);
}

Ver la demo: http://jsfiddle.net/dstorey/78q8m/3/

 34
Author: David Storey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-22 20:45:57

He recibido una solución en el foro de Microsoft de Rob. Véase http://social.msdn.microsoft.com/Forums/ie/en-US/8145c1e8-6e51-4213-ace2-2cfa43b1c018/ie-11-flexbox-with-flexwrap-wrap-doesnt-seem-to-calculate-widths-correctly-boxsizing-ignored?forum=iewebdevelopment

Establecer un min-width y cambiar a flex:autohace que las cajas se comporten, manteniendo su flexibilidad.

Véase http://jsfiddle.net/MartijnR/WRn9r/23 / y por debajo de un poco más avanzado ejemplo con la solución:

<section>
    <div class="box fifty">1</div>
    <div class="box twentyfive">2</div>
    <div class="box twentyfive">3</div>
    <div class="box fifty">4</div>
    <div class="box fifty">5</div>
</section>


section {
    display: -moz-webkit-flex;
    display: -webkit-flex;
    display: flex;
    -ms-flex-direction: row;
    -moz-flex-direction: row;
    -webkit-flex-direction: row;
    flex-direction: row;
    -ms-flex-wrap: wrap;
    -moz-flex-wrap: wrap;
    -webkit-flex-wrap: wrap;
    flex-wrap: wrap;
    width: 100%;
    box-sizing:border-box;
    margin:0;
}
.box {
    border: 1px solid black;
    background: #ccc;
    display: block;
    box-sizing: border-box;
    margin:0;
    -ms-flex: auto;
    -moz-flex: auto;
    -webkit-flex: auto;
    flex: auto;
}
.fifty {
    min-width: 50%;
}
.twentyfive {
    min-width: 25%;
}
 10
Author: Martijn van de Rijdt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-22 16:56:25

Philip Walton tiene un excelente resumen de este error aquí: https://github.com/philipwalton/flexbugs#7-flex-basis-doesnt-account-for-box-sizingborder-box. Propone dos soluciones, la más fácil de las cuales es establecer flex-basis: auto y declarar un width en su lugar. (No max-width o min-width.) Esta solución tiene la ventaja de no tener que ajustar su calc() cuando cambia el relleno o los anchos de borde.

 7
Author: nabrown78,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-06 13:52:40

Esto es claramente un error de IE así que deje el CSS original [correcto] y agregue un hack que se dirija a IE10+:

/* IE10+ flex fix: */
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
    .box {
        flex: 0;
        min-width: 50%;
    }
}

Http://jsfiddle.net/stedman/t1y8xp2p /

 6
Author: stedman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:47