Ошибки, которые могут возникать при использовании flexbox, и их решение
Flexbox стремительно набирает популярность благодаря своей гибкости и адаптивности. Использование этого элемента позволяет легко верстать макеты, которые раньше заставляли попотеть. Основная проблема flexbox в том, что этот довольно новый элемент не гарантирует вам стабильную работу во всех используемых браузерах. Довольно часто встречаются случаи, когда стандартные решения не приносят ожидаемого результата. В этой статье мы рассмотрим некоторые ошибки и пути их решения.
1.Искажение вложенных объектов, размер которых больше размера ячейки
Эта ошибка встречается в Chrome, Opera и Safari. Когда элементы имеют слишком большие размеры, чтобы поместиться внутри контейнера, они должны быть трансформированы, чтобы уменьшить их так, как это определяет свойство flex-shrink. При этом объекты уменьшаются не бесконечно, они не могут получить размеры меньшие, чем их минимальная высота и минимальная ширина.
В соответствии с текущей спецификацией flexbox:
По умолчанию, элементы не будут сжиматься меньше их минимального размера (длина самого длинного слова или фиксированного размера элемента). Чтобы изменить это, установите свойства min-width или min-heigh.
Решение
Спецификация Flexbox говорит нам, что свойство flex-shrink имеет значение по умолчанию равное 1, но также указывает, что детали не должны сжиматься меньше их минимального размера по умолчанию. Вы можете использовать значение 0 для flex-shrink, что позволит вам избежать этой ошибки. Если ваши элементы рассчитывают свои размеры, исходя из размеров родителей, и не имеют заданных свойств width, height или flex-basis, в остальном они будут вести себя также.
2. Содержимое flex-элемента, для которого установлено align-items:center, выходит за рамки элемента
Ошибка встречается в Internet Explorer 10-11. При использовании align-items:center для контейнера, его содержимое, если оно имеет достаточно большой размер, будет выходить за рамки объекта.
Решение
В большинстве случаев это может быть исправлено установкой максимальной ширины 100% для контейнера. Если flex-элемент имеет box-sizing:border-box, вы должны убедиться, что указанные размеры учитывают эти свойства. Если вы используете box-sizing, это решение не будет работать, в таком случае вам придется использовать дополнительный контейнер внутри основного.
3. Ошибка с обработкой min-height, указанного для колонок
Для того чтобы элементы могли определять свои размеры и позиционирование, они должны знать о размерах контейнера, в который они помещены. Например, чтобы центрировать объект по вертикали, необходимо знать высоту его родителя. В IE 10-11 объекты ведут себя так, как будто не догадываются о свойствах своих родителей.
Решение
Самым распространенным решением является установка height: 100vh (или 100%). В таком случае, если в контейнер будет помещено слишком много содержимого, появится полоса вертикальной прокрутки. Бывают случаи, когда такое решение не будет работать, тогда используйте определение браузера.
4. Ошибка обработки короткой записи значений свойства flex
Раньше спецификация flexbox требовала использовать полную запись:
Если preferred-size равен 0, это должно быть указано, например, \»0px\», чтобы избежать двусмысленности, в другом случае возникнет синтаксическая ошибка.
Это требование уже неактуально, но IE 10-11 все еще воспринимает его всерьез.
Решение
Всегда явно указывайте preferred-size.
Важно: используя значения вроде 1 0 0px, вы все еще можете столкнуться с проблемой, потому что многие минимизаторы CSS будут конвертировать 0px в 0. Чтобы избежать этого, убедитесь, что используете 0% вместо 0px, так как большинство минимизаторов не убирают процентные значения.
5. Нарушение пропорций некоторых элементов
Спецификация 2014 года описывает определение размера flex-элемента следующим образом:
Размер элемента, переполнения которого не видно, приравнивается к меньшему из значений: а) min-content; б) width/height, если они указаны.
В случае если вы пытаетесь вписать изображение размерами 200×500 пикселей, а ширина контейнера составляет всего 300 пикселей, изображение будет масштабировано для того, чтобы вписаться в контейнер. В итоге высота изображения получит значение 120 пикселей. Из приведенной выше спецификации неясно, какое значение высоты изображения будет использовано для расчета высоты контейнера: 200 или 120.
Последняя спецификация решила эту проблему в пользу размеров, которые не нарушают пропорций вложенного объекта, но IE 10-11 все еще работает по старой спецификации.
Решение
Вы можете избежать этой проблемы путем добавления еще одного элемента контейнера с теми же пропорциями. Тогда внутренний элемент перестанет быть гибким и будет масштабироваться, как обычный.
6. Изменилось значение Flex по умолчанию
Когда IE 10 только разрабатывался, значение flex по умолчанию устанавливалось none, что аналогично (0 0 auto). Недавняя спецификация определила стартовым значением (0 1 auto). Это значит, что IE 10 использует схему масштабирования, отличную от других браузеров.
Решение
Если у вас есть необходимость поддерживать IE 10, лучшим решением будет всегда явно задавать flex-shrink или flex для всех ваших гибких элементов.
7. Flex-basis не учитывает box-sizing:border-box
Ошибка, которая встречается в Internet Explorer 10-11.
Явное указание flex-basis должно действовать так же, как и width или height. Оно определяет размер элемента и все примененные к нему свойства, чтобы увеличить или уменьшить свои размеры соответственно. Но Internet Explorer 10-11 всегда использует box model гибкого элемента, даже если для него установлены box-sizing:border-box.
Решение
Есть два способа обойти эту ошибку. Первый не требует дополнительной разметки, но второй более гибкий:
- Вместо того чтобы установить точное значение flex-basis, используйте auto, а затем явно задайте ширину или высоту.
- Применяйте элемент-оболочку, который не использует границы или отступы.
8. Отсутствие поддержки Calc () при сокращенной записи
Internet Explorer 10-11 игнорирует сокращенную запись значений flex, которая использует calc() при описании flex-basis.
Решение
Эта ошибка проявляется только при короткой записи, так что если вам необходимо использовать Calc (), указывайте каждое свойство индивидуально.
9. Button не становится flex-контейнером
В отличие от input, элементы типа \»button\» или \»submit\» могут содержать дочерние элементы. Это позволяет вставлять что-то кроме текста, не нарушая семантику. Однако Firefox не позволяет использовать этот прием.
Решение
Простое решение этой проблемы заключается в использовании оболочки для Button со свойством display:flex.
Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице
Задавались когда-нибудь вопросом, как работает CSS Flexbox? Наглядно объясняем возможности технологии с использованием анимации.
CSS Flexbox — это технология для создания сложных гибких макетов за счёт правильного размещения элементов на странице. О самой технологии пишут здесь. Мы же решили объяснить возможности CSS Flexbox с использованием гифок — настоящая flex шпаргалка.
Разберёмся, как работает display flex CSS. Есть страница:На ней размещено 4 div разных размеров, которые находятся внутри серого div . У каждого div есть свойство display: block . Поэтому каждый блок занимает всю ширину строки. И вот как реализовать CSS display flex. Чтобы начать работать с CSS Flexbox, нужно сделать контейнер flex контейнером. Делается это так:
#container
Так у блоков появилось свойство flex-контекст, которое в дальнейшем позволит ими управлять гораздо проще, чем с использованием стандартного CSS.
flex-direction
У flex-контейнера есть две оси: главная и перпендикулярная ей.По умолчанию все предметы располагаются вдоль главной оси — слева направо. Именно поэтому блоки в предыдущем примере выстроились в линию, когда мы применили display: flex . А вот flex-direction позволяет вращать главную ось.
#container
Обратите внимание, что flex-direction: column не выравнивает блоки по оси, перпендикулярной главной. Главная ось сама меняет своё расположение, и теперь направлена сверху вниз.Есть ещё парочка свойств для flex-direction : row-reverse и column-reverse .
justify-content
Отвечает за выравнивание элементов по главной оси:
#container
Justify-content может принимать 5 значений:
Space-between задаёт одинаковое расстояние между блоками, но не между контейнером и блоками. Space-around также задаёт одинаковое расстояние между блоками, но теперь расстояние между контейнером и блоками равно половине расстояния между блоками.
align-items
Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси. Вернёмся к flex-direction: row и пройдёмся по командам align-items :
Стоит заметить, что для align-items: stretch высота блоков должна быть равна auto . Для align-items: baseline теги параграфа убирать не нужно, иначе получится так:
Чтобы получше разобраться в том, как работают оси, объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction :
align-self
Позволяет выравнивать элементы по отдельности:
#container < align-items: flex-start;>.square#one < align-self: center;>// Only this square will be centered.Для двух блоков применим align-self , а для остальных — align-items: center и flex-direction: row .
flex-basis
Отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами CSS Flexbox. flex-basis влияет на размер элементов вдоль главной оси. Давайте посмотрим, что случится, если мы изменим направление главной оси:
Заметьте, что нам пришлось изменить и высоту элементов: flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.
flex-grow
Это свойство немного сложнее. Для начала зададим блокам одинаковую ширину в 120px:По умолчанию значение flex-grow равно 0. Это значит, что блокам запрещено увеличиваться в размерах. Зададим flex-grow равным 1 для каждого блока:
Теперь блоки заняли оставшееся место в контейнере. Но что значит flex-grow: 1 ? Попробуем сделать flex-grow равным 999:
И… ничего не произошло. Так получилось из-за того, что flex-grow принимает не абсолютные значения, а относительные. Это значит, что не важно, какое значение у flex-grow , важно, какое оно по отношению к другим блокам:
Вначале flex-grow каждого блока равен 1, в сумме получится 6. Значит, наш контейнер разделён на 6 частей. Каждый блок будет занимать 1/6 часть доступного пространства в контейнере. Когда flex-grow третьего блока становится равным 2, контейнер делится на 7 частей: 1 + 1 + 2 + 1 + 1 + 1. Теперь третий блок занимает 2/7 пространства, остальные — по 1/7. И так далее.
flex-grow работает только для главной оси, пока мы не изменим её направление.
flex-shrink
Прямая противоположность flex-grow . Определяет, насколько блоку можно уменьшиться в размере. flex-shrink используется, когда элементы не вмещаются в контейнер. Вы определяете, какие элементы должны уменьшиться в размерах, а какие — нет. По умолчанию значение flex-shrink для каждого блока равно 1. Это значит, что блоки будут сжиматься, когда контейнер будет уменьшаться.Зададим flex-grow и flex-shrink равными 1:
Теперь поменяем значение flex-shrink для третьего блока на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:
flex-shrink основывается на пропорциях. То есть, если у первого блока flex-shrink равен 6, а у остальных он равен 2, то, это значит, что первый блок будет сжиматься в три раза быстрее, чем остальные.
flex
Заменяет flex-grow , flex-shrink и flex-basis . Значения по умолчанию: 0 (grow) 1 (shrink) auto (basis) .Создадим два блока:
.square#one < flex: 2 1 300px;>.square#two
У обоих одинаковый flex-basis . Это значит, что оба будут шириной в 300px (ширина контейнера: 600px плюс margin и padding ). Но когда контейнер начнет увеличиваться в размерах, первый блок (с большим flex-grow ) будет увеличиваться в два раза быстрее, а второй блок (с наибольшим flex-shrink ) будет сжиматься в два раза быстрее:Ещё больше возможностей свойства вы можете найти в анимированном руководстве по CSS flex.
Дополнительно
Как с CSS Flexbox меняется размер?
Когда увеличивается первый блок, он не становится в два раза больше второго, и когда уменьшается второй, он также не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.
Немного математики
И последний пример по flex box CSS. Начальный размер контейнера: 640px. Вычтем по 20px с каждой стороны для padding , и у нас останется 600px для двух блоков. Когда ширина контейнера становится равной 430px (потеря в 210px), первый блок ( flex-shrink: 1 ) теряет 70px. Второй блок ( flex-shrink: 2 ) теряет 140px. Когда контейнер сжимается до 340px, мы теряем 300px. Первый блок теряет 100px, второй — 200px. То же самое происходит и с flex-grow .
Если помимо flex CSS вы также интересуетесь CSS Grid, можете ознакомиться с нашей статьёй, где мы рассматриваем Flexbox и Grid.
Надеемся, вам была полезна наша анимированная Flexbox шпаргалка. Подписывайтесь на тег CSS, чтобы узнать больше о возможностях Флексбокс и не только.
Как реально работают flex — shrink и flex — grow
Механизм расчёта свободного места во флекс-контейнере при помощи свойств flex — grow и flex — shrink .
Время чтения: 9 мин
Открыть/закрыть навигацию по статье
- flex-grow
- Что ещё здесь важно помнить?
Обновлено 2 октября 2023
flex — grow и flex — shrink — это CSS-свойства, определяющие, какое количество свободного пространства флекс-контейнера может занимать текущий элемент.
Рассмотрим каждое свойство в отдельности.
flex — grow
Скопировать ссылку «flex-grow» Скопировано
Создадим флекс-контейнер с двумя вложенными элемента с разными значениями flex — grow .
flex-grow: 2;flex-grow: 1;div class="container"> code class="container-item-grown">flex-grow: 2;code> code class="container-item-common">flex-grow: 1;code> div>.container display: flex; width: 1200px; height: 100px;> .container-item-grown background-color: #2E9AFF; flex-grow: 2;> .container-item-common background-color: #F498AD; flex-grow: 1;>.container display: flex; width: 1200px; height: 100px; > .container-item-grown background-color: #2E9AFF; flex-grow: 2; > .container-item-common background-color: #F498AD; flex-grow: 1; >У нас есть контейнер шириной 1200 px, для первого элемента указан flex — grow : 2 , а для второго — flex — grow : 1 . Первый элемент занимает 800 px, а второй 400 px.
Хочется думать, что здесь всё просто и работает по правилам математики:
- сложить значения свойства для каждого контейнера и получить 3 (2 + 1);
- поделить ширину контейнера на общее количество «частей» и получить 400 px (1200 px / 3);
- для каждого блока использовать значение flex — grow как вес и умножить на ширину одной части;
- для первого блока 400 px * 2 = 800 px;
- для второго блока 400 px * 1 = 400 px.
Пока всё верно. Однако, часто на практике мы ожидаем, что сейчас мы укажем flex — grow и это нас спасёт и… не работает.
Вот пример, такого «не работает».
Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия.div class="container"> div class="container-item-grown"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div class="container-item-common"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div>.container display: flex; width: 1200px;> .container-item-grown background-color: #2E9AFF; flex-grow: 2;> .container-item-common background-color: #F498AD; flex-grow: 1;>.container display: flex; width: 1200px; > .container-item-grown background-color: #2E9AFF; flex-grow: 2; > .container-item-common background-color: #F498AD; flex-grow: 1; >Пример отличается от предыдущего тем, что в блоках появился текст, обёрнутый в параграф. И результат таков, что блоки стали одинаковыми по ширине.
Получается, что логика рассуждений, приведённая выше, не работает?
Не совсем так, давайте разбираться.Деталь кроется в том, что flex — grow определяет, какое количество свободного места занимает элемент. И если внимательно посмотреть, то каждый блок текста занял по 600 px ширины, а свободного пространства не осталось. Поэтому и распределять нечего.
Почему же в первом примере всё работает ожидаемо? Там логика сработала, потому что для блоков не указана ширина и в них нет вложенных элементов, а значит ширина обоих 0 px, и свободное место — это и есть ширина контейнера, то есть 1200 px.
И что, если свободного места нет, то использовать flex — grow не получится? Не совсем, нужно просто добавить свойство flex — basis . Если использовать эти свойства в комплекте, то алгоритм расчёта ширины изменится.
flex — basis — это свойство, которое устанавливает начальный основной размер флекс-элемента. Его можно задать в любых единицах, в которых можно задать ширину элемента.
В результате мы получим то, чего хотим.
Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия.div class="container"> div class="container-item-grown"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div class="container-item-common"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div>.container display: flex; width: 1200px;> .container-item-grown background-color: #2E9AFF; flex-grow: 2; flex-basis: 800px;> .container-item-common background-color: #F498AD; flex-grow: 1; flex-basis: 400px;>.container display: flex; width: 1200px; > .container-item-grown background-color: #2E9AFF; flex-grow: 2; flex-basis: 800px; > .container-item-common background-color: #F498AD; flex-grow: 1; flex-basis: 400px; >Ещё один пример без flex — basis для закрепления. Попробуем задать ширину параграфов: для первого параграфа зададим 300 px, а для второго 600 px.
Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия.div class="container"> div class="container-item-grown"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div class="container-item-common"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div>.container display: flex; width: 1200px;> .container-item-grown background-color: #2E9AFF; flex-grow: 2;> .container-item-common background-color: #F498AD; flex-grow: 1;> .container-item-grown p width: 300px;> .container-item-common p width: 600px;>.container display: flex; width: 1200px; > .container-item-grown background-color: #2E9AFF; flex-grow: 2; > .container-item-common background-color: #F498AD; flex-grow: 1; > .container-item-grown p width: 300px; > .container-item-common p width: 600px; >Здесь получается не совсем ожидаемый от flex — grow результат, если не знать как работает свойство на самом деле. Но мы-то уже знаем, давайте посчитаем:
- Первый блок занимает 300 px. Это свойство задано для селектора p .
- Второй блок занимает 600 px. Причина всё та же — так задано в дочернем элементе.
- Итого, для распределения свойством flex — grow остаётся 300 px. Далее применим логику, которая была описана чуть выше, и…
- На первый элемент придётся 200 px, а на второй — всего 100 px.
- В итоге первый элемент займёт 500 px (300 px + 200 px), а второй — 700 px (600 px + 100 px).
Что ещё здесь важно помнить?
Скопировать ссылку «Что ещё здесь важно помнить?» Скопировано
Как работает свойство box-sizing. Вычисление свойства flex — basis также, как и свойства width зависит от box — sizing , и результат, в зависимости от указанного значения, будет разным.
flex — shrink
Скопировать ссылку «flex-shrink» Скопировано
Теперь посмотрим на свойство flex-shrink. Его мы используем в тех случаях, когда места не хватает и размеры элементов флекс-контейнера нужно уменьшить. Здесь математика чуть сложнее, вот пример:
Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия.div class="container"> div class="container-item-shrikned"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div class="container-item-common"> p> Равным образом сложившаяся структура организации требуют определения и уточнения модели развития. Повседневная практика показывает, что дальнейшее развитие различных форм деятельности обеспечивает широкому кругу (специалистов) участие в формировании систем массового участия. p> div> div>.container display: flex; width: 800px;> .container-item-shrinked background-color: #2E9AFF; flex-shrink: 2; flex-basis: 400px;> .container-item-common background-color: #F498AD; flex-shrink: 1; flex-basis: 800px;>.container display: flex; width: 800px; > .container-item-shrinked background-color: #2E9AFF; flex-shrink: 2; flex-basis: 400px; > .container-item-common background-color: #F498AD; flex-shrink: 1; flex-basis: 800px; >У нас в примере два элемента, у каждого есть изначальная ширина ( flex — basis равен 400 px и 800 px соответственно). Итого 1200 px. Однако ширина флекс-контейнера всего 800 px.
Сначала посчитаем общий вес при том, что для первого элемента значение flex — shrink составляет 2, а для второго — 1: 2 * 400 px + 1 * 800 px = 1600 px.
Для полноценного размещения нам не хватает 1200 px — 800 px = 400 px.Подсчёт сокращения будет выглядеть следующим образом:
- Пространство, которого не хватает, умножим на значение flex — shrink .
- Затем результат умножим на значение flex — basis .
- Результат предыдущего действия разделим на общий вес.
- 400 px * 2 * 400 px / 1600 px = 200 px
- 400 px * 1 * 800 px / 1600 px = 200 px
А в результате ширина блоков будет следующая:
- 400 px — 200 px = 200 px
- 800 px — 200 px = 600 px
Вывод: с помощью свойств flex — basis , flex — grow , flex — shrink можно предусмотреть как ситуации, когда контейнер окажется больше, чем элементы, в нём размещённые, так и наоборот — когда контейнер мал для элементов. А если знать как рассчитываются итоговые размеры, то можно избежать различных неожиданностей.
Почему не работает display: flex; flex-direction: row;?
Работает. По умолчанию justify-content равен flex-start, вот элемент hi__body и находится с левого края. Для того чтобы действие «flex-direction: row» было заметней, нужно задать другое значение для justify-content (center например) или добавить еще один элемент (или несколько) по соседству с hi__body. Прошу прощения если неправильно понял проблему.
Ответ написан более года назад
Комментировать
Нравится Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- HTML
- +1 ещё
Какие могут быть подводные камни при верстке в REM c шрифтом HTML в VW?
- 1 подписчик
- 5 часов назад
- 38 просмотров
