Подтвердить что ты не робот

Многострочный flexbox в IE11 неправильно вычисляет ширину?

Кажется, IE11 не вычисляет ширину гибких элементов должным образом, если используется flex-wrap: wrap.

См. http://jsfiddle.net/MartijnR/WRn9r/6/

Каждый из четырех ящиков имеет гибкую основу: 50%, поэтому мы должны получать по две строки по две коробки, но в IE11 каждый ящик получает одну строку. При установке границы на 0, она работает правильно.

Любая идея, если это ошибка, или если есть способ заставить IE11 вести себя (и все еще использовать границы)?

<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.S. В моем проекте, к счастью, нужно поддерживать только последнюю версию популярных браузеров, но IE11 является одним из них.

4b9b3361

Ответ 1

Похоже на ошибку, когда box-sizing не учитывается при вычислении размера с использованием свойства flex. Поскольку граница занимает 2px, она больше 50%, и, таким образом, только одна помещается на линию, поэтому все ящики растягиваются до полной ширины. Вы можете видеть то же самое, что происходит, если вы отключите границу и добавьте дополнение 2px вместо этого.

Вы можете заставить его работать правильно, сохраняя границы, добавив max-width: 50% в набор правил .box. В противном случае вы можете использовать значение flex от 33,34% до 49%. Это сделает ширину менее 50%, включая границу, и по мере того, как элементы растут, чтобы заполнить свободное пространство, они все равно будут составлять 50% контейнера flex. Вид уродливого взлома, но он будет работать, если вы не добавите комбинированную рамку и отступы более 50% за вычетом установленного значения гибкости.

Возможно, лучшим способом, чем уменьшение процентного значения, является использование calc(). Это поддерживается всеми браузерами, поддерживающими современный синтаксис Flexbox. Вам просто нужно вычесть суммарную сумму левого и правого paddings и полей из процентного значения, которое вы хотите использовать. По мере того как вы делаете это, вам действительно не нужно свойство размера окна, чтобы его можно было удалить. В IE есть другая проблема, в которой вы не можете использовать calc в сокращении flex, но можете использовать его в свойстве flex-basis, которое вам нужно.

.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);
}

См. демонстрацию: http://jsfiddle.net/dstorey/78q8m/3/

Ответ 2

Я получил обходной путь на форуме Microsoft от Роба. См. 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

Настройка min-width и изменение на flex:auto заставляет окна вести себя, сохраняя их гибкость.

См. http://jsfiddle.net/MartijnR/WRn9r/23/ и ниже для немного более продвинутого примера с обходным путем:

<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%;
}

Ответ 3

У Филиппа Уолтона есть отличное резюме этой ошибки здесь: https://github.com/philipwalton/flexbugs#7-flex-basis-doesnt-account-for-box-sizingborder-box. Он предлагает два решения, самый простой из которых - установить flex-basis: auto и вместо этого объявить width. (Не max-width или min-width.) Это решение имеет то преимущество, что вам не нужно настраивать calc() при изменении ширины прокладки или ширины границы.

Ответ 4

Это явно ошибка IE, поэтому оставьте исходный [правильный] CSS и добавьте хак, который нацелен на 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/