Если flex элементу прописать margin right auto что произойдет
2.23. CSS flexbox
CSS flexbox (Flexible Box Layout Module) — модуль макета гибкого контейнера — представляет собой способ компоновки элементов, в основе лежит идея оси.
Flexbox состоит из гибкого контейнера (flex container) и гибких элементов (flex items). Гибкие элементы могут выстраиваться в строку или столбик, а оставшееся свободное пространство распределяется между ними различными способами.
Модуль flexbox позволяет решать следующие задачи:
Flexbox решает специфические задачи — создание одномерных макетов, например, навигационной панели, так как flex-элементы можно размещать только по одной из осей.
Список текущих проблем модуля и кросс-браузерных решений для них вы можете прочитать в статье Philip Walton Flexbugs.
Что такое flexbox
Поддержка браузерами
1. Основные понятия
Для описания модуля Flexbox используется определенный набор терминов. Значение flex-flow и режим записи определяют соответствие этих терминов физическим направлениям: верх / право / низ / лево, осям: вертикальная / горизонтальная и размерам: ширина / высота.
Главная ось (main axis) — ось, вдоль которой выкладываются flex-элементы. Она простирается в основном измерении.
Main start и main end — линии, которые определяют начальную и конечную стороны flex-контейнера, относительно которых выкладываются flex-элементы (начиная с main start по направлению к main end).
Основной размер (main size) — ширина или высота flex-контейнера или flex-элементов, в зависимости от того, что из них находится в основном измерении, определяют основной размер flex-контейнера или flex-элемента.
Поперечная ось (cross axis) — ось, перпендикулярная главной оси. Она простирается в поперечном измерении.
Cross start и cross end — линии, которые определяют начальную и конечную стороны поперечной оси, относительно которых выкладываются flex-элементы.
Поперечный размер (cross size) — ширина или высота flex-контейнера или flex-элементов, в зависимости от того, что находится в поперечном измерении, являются их поперечным размером.
Рис. 2. Режим строки и колонки
2. Flex-контейнер
Модель flexbox-разметки связана с определенным значением CSS-свойства display родительского html-элемента, содержащего внутри себя дочерние блоки. Для управления элементами с помощью этой модели нужно установить свойство display следующим образом:
После установки данных значений свойства каждый дочерний элемент автоматически становится flex-элементом, выстраиваясь в один ряд (вдоль главной оси). При этом блочные и строчные дочерние элементы ведут себя одинаково, т.е. ширина блоков равна ширине их содержимого с учетом внутренних полей и рамок элемента.
Рис. 3. Выравнивание элементов в модели flexbox
Если родительский блок содержит текст или изображения без оберток, они становятся анонимными flex-элементами. Текст выравнивается по верхнему краю блока-контейнера, а высота изображения становится равной высоте блока, т.е. оно деформируется.
3. Flex-элементы
Flex-элементы — блоки, представляющие содержимое flex-контейнера в потоке. Flex-контейнер устанавливает новый контекст форматирования для своего содержимого, который обуславливает следующие особенности:
4. Порядок отображения flex-элементов и ориентация
Содержимое flex-контейнера можно разложить в любом направлении и в любом порядке (переупорядочение flex-элементов внутри контейнера влияет только на визуальный рендеринг).
4.1. Направление главной оси: flex-direction
Свойство относится к flex-контейнеру. Управляет направлением главной оси, вдоль которой укладываются flex-элементы, в соответствии с текущим режимом записи. Не наследуется.
flex-direction | |
---|---|
Значения: | |
row | Значение по умолчанию, слева направо (в rtl справа налево). Flex-элементы выкладываются в строку. Начало (main-start) и конец (main-end) направления главной оси соответствуют началу (inline-start) и концу (inline-end) оси строки (inline-axis). |
row-reverse | Направление справа налево (в rtl слева направо). Flex-элементы выкладываются в строку относительно правого края контейнера (в rtl — левого). |
column | Направление сверху вниз. Flex-элементы выкладываются в колонку. |
column-reverse | Колонка с элементами в обратном порядке, снизу вверх. |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
Рис. 4. Свойство flex-direction для left-to-right языков
4.2. Управление многострочностью flex-контейнера: flex-wrap
Свойство определяет, будет ли flex-контейнер однострочным или многострочным, а также задает направление поперечной оси, определяющее направление укладки новых линий flex-контейнера.
По умолчанию flex-элементы укладываются в одну строку, вдоль главной оси. При переполнении они будут выходить за пределы ограничивающей рамки flex-контейнера. Свойство не наследуется.
flex-wrap | |
---|---|
Значения: | |
nowrap | Значение по умолчанию. Flex-элементы не переносятся, а располагаются в одну линию слева направо (в rtl справа налево). |
wrap | Flex-элементы переносятся, располагаясь в несколько горизонтальных рядов (если не помещаются в один ряд) в направлении слева направо (в rtl справа налево). |
wrap-reverse | Flex-элементы переносятся на новые линии, располагаясь в обратном порядке слева-направо, при этом перенос происходит снизу вверх. |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
Рис. 5. Управление многострочностью с помощью свойства flex-wrap для LTR-языков
4.3. Краткая запись направления и многострочности: flex-flow
4.4. Порядок отображения flex-элементов: order
Свойство определяет порядок, в котором flex-элементы отображаются и располагаются внутри flex-контейнера. Применяется к flex-элементам. Свойство не наследуется.
Рис. 6. Порядок отображения flex-элементов
5. Гибкость flex-элементов
Flex-элемент будет полностью «негибок», если его значения flex-grow и flex-shrink равны нулю, и «гибкий» в противном случае.
5.1. Задание гибких размеров одним свойством: flex
W3C рекомендует использовать сокращённую запись, так как она правильно сбрасывает любые неуказанные компоненты, чтобы подстроиться под типичное использование.
5.2. Коэффициент роста: flex-grow
Свойство определяет коэффициент роста одного flex-элемента относительно других flex-элементов в flex-контейнере при распределении положительного свободного пространства. Если сумма значений flex-grow flex-элементов в строке меньше 1, они занимают менее 100% свободного пространства. Свойство не наследуется.
5.3. Коэффициент сжатия: flex-shrink
5.4. Базовый размер: flex-basis
flex-basis | |
---|---|
Значения: | |
auto | Значение по умолчанию. Элемент получает базовый размер, соответствующий размеру его содержимого (если он не задан явно). |
content | Определяет базовый размер в зависимости от содержимого flex-элемента. |
длина | Базовый размер определяется так же, как для ширины и высоты. Задается в единицах длины. |
initial | Устанавливает значение свойства в значение по умолчанию. |
inherit | Наследует значение свойства от родительского элемента. |
6. Выравнивание
6.1. Выравнивание по главной оси: justify-content
6.2. Выравнивание по поперечной оси: align-items и align-self
6.2.1. Align-items
Свойство выравнивает flex-элементы, в том числе и анонимные flex-элементы по поперечной оси. Не наследуется.
6.2.2. Align-self
6.3. Выравнивание строк flex-контейнера: align-content
11 вещей которые я узнал, читая спецификацию flexbox
Я всегда считал, что с flexbox довольно легко работать — глоток свежего воздуха после стольких лет float’ов и clearfix’ов.
Правда недавно я обнаружил что борюсь с ним; что-то растягивалось, когда я не думал, что оно должно тянуться. Я поправил здесь, другой элемент сжался. Я починил это, что-то другое ушло за экран. Какого Джорджа Буша тут происходит?
В конце концов, все заработало, но солнце село, а мой процесс был привычной игрой с CSS. Или… как называется та игра, где надо ударить крота, а затем другой крот выпрыгивает и надо ударить и его тоже?
Как бы там ни было, я решил что пора вести себя как взрослый разработчик и выучить flexbox должным образом. Но вместо того, чтобы прочитать 10 очередных блог-постов, я решил отправиться прямиком к исходнику и прочитать The CSS Flexible Box Layout Module Level 1 Spec
Вот хорошие отрывки.
1. Margin обладает особыми силами
Я думал, что если, например, ты хочешь заголовок с логотипом и названием сайта слева, а кнопкой логина справа.
… тебе следует дать названию flex: 1, чтобы прижать остальные элементы к другому концу строки.
Вот почему flexbox — Очень Хорошая Вещь. Простые вещи такие простые.
Но возможно, по какой-то причине, ты не хочешь тянуть элемент только для того чтобы прижать другой элемент вправо. Может, потому что у элемента есть подчеркивание, изображение или какая-либо третья причина, которую я не могу придумать.
Отличные новости! Вместо этого, ты можешь сказать прямо: «прижми этот элемент вправо», определив margin-left: auto на нужном элементе. Думай об этом как о float: right.
Например, если элемент слева является изображением:
Мне не нужно применять flex к изображению, мне не нужно применять space-between к flex-контейнеру, я просто установлю margin-left: auto на кнопке «Войти» («Sign in»):
Тебе может показаться это некоторым хаком, но нет, это прямо там в обзоре спецификации как способ прижать flex-элемент в конец flexbox’а. У способа даже есть своя глава: «Выравнивание с авто margin’ами».
О, мне также следует здесь упомянуть, что я предполагаю flex-direction: row везде в этом блог-посте, но все применимо также и к row-reverse или column или column-reverse.
2. min-width имеет значение
Возможно, ты думаешь, что несложно заставить все flex-элементы внутри flex-контейнера сжиматься, для того чтобы уместить контент. Наверняка, если ты укажешь flex-shrink: 1 на элементах, они так и будут себя вести, правда?
Скажем, у тебя есть часть DOM, которая отображает книгу на продажу и кнопку чтобы ее купить.
Ты разместил все с помощью flexbox и все хорошо.
(Поскольку ты хочешь кнопку «Купить» справа — даже для очень коротких названий — ты, будучи умным, указал margin-left: auto)
Название книги довольно длинное, поэтому оно использует столько пространства сколько может и затем переходит на следующую строку. Ты счастлив, жизнь прекрасна. Ты блаженно отправляешь свой код в продакшн, с уверенностью, что он выдержит все.
И потом получаешь неприятный сюрприз. Совсем не хорошего рода.
Некий дурень, много о себе возомнивший, написал книгу с длинным словом в названии.
Если красная граница обозначает ширину смартфона, и ты скрываешь переполнение (overflow: hidden), ты только что потерял свою кнопку «Купить». Твой коэффициент конверсии — как и эго бедного автора — будет страдать.
(Примечание: к счастью, там где я работаю, есть хорошая QA команда, которая наполнила нашу базу данных разнородным текстом, наподобие такого. В частности, именно эта проблема побудила меня прочитать спецификацию.)
Оказывается, такое поведение происходит из-за того, что min-width элемента описания изначально установлена в auto, что в данном случае равняется ширине слова Electroencephalographically (электроэнцефалографически). Flex-элементу буквально не разрешается быть уже чем это слово.
Решение? Переопределить эту проблемную минимальную ширину min-width: auto установив min-width: 0, указывая flexbox’у, что этот элемент может быть уже, чем содержимое внутри него.
Теперь за управление текстом внутри элемента отвечаешь ты. Я предлагаю перенести слово. Таким образом, твой CSS будет выглядеть так:
Результат будет таким:
Опять же, min-width: 0 не какой-то хак для обхода нелепости, это предлагаемое поведение прямо в спецификации.
В следующем разделе, я вернусь к тому, что кнопка «Купить» совсем не 80 пикселей по ширине, как я довольно ясно ей сказал.
3. Авторы flexbox обладают хрустальным шаром
Как вы возможно знаете, свойство flex является краткой записью flex-grow, flex-shrink и flex-basis.
Должен признать, я потратил энное количество минут, гадая-проверяя различные значения для этой тройки, когда пытался заставить элементы тянуться так, как надо мне.
Что я не знал до сей поры, это то, что, в общем случае, я хочу одну из трех комбинаций:
Надеюсь, что ты пока не на максимальном изумлении — сейчас станет еще поразительнее.
Видишь ли, Бригада Flexbox’а (мне нравится думать, что команда flexbox’а носит кожаные куртки с этой надписью сзади — доступны мужские и женские размеры). Где там было это предложение? Ах да, Бригада Flexbox’а знала, что я хочу эти три комбинации свойств в большинстве случаев. Поэтому они дали им ключевые слова специально для меня.
Первый случай — это значение initial так что ключевое слово не нужно. Для второго случая используется flex: auto, и flex: none замечательно простое решение чтобы элемент не тянулся совсем.
Кто бы мог подуть! (Who woulda thunk it — игра слов, прим. переводчика)
Это как если бы было box-shadow: garish, что по умолчанию равнялось 2px 2px 4px hotpink потому что считалось «полезным значением по умолчанию».
Вернемся к невероятно уродливому книжному примеру. Чтобы сделать ту кнопку «Купить» стабильно широкой для попадания пальцем.
… мне всего лишь надо задать на ней flex: none:
(Да, я мог бы указать flex: 0 0 80px; и сэкономить строку CSS. Но есть что-то особенное в том, как ясно flex: none демонстрирует намерение кода. Это хорошо для Будущего Дэвида который забудет как это все работает.)
4. Есть такая вещь inline-flex
По правде говоря, я узнал, что есть такая вещь как display: inline-flex несколько месяцев назад. И то, что она создаст инлайновый flex-контейнер, вместо блочного.
Но по моей оценке, 28% людей еще не знали этого, так что… теперь знайте, нижние 28%.
5. vertical-align не влияет на flex-элемент
Возможно это то, что я знал наполовину, но я уверен, что в какой-то момент, когда пытался задать правильное выравнивание, я мог испробовать vertical-align: middle и пожать плечами, когда это не сработало.
Теперь я знаю наверняка, прямо из спецификации, что «вертикальное выравнивание не влияет на flex-элемент» (так же как и float, замечу).
6. Не используй margin или padding в %
Это не просто уровня «лучшая практика», это уровня «совет-от-бабушки», так что просто делай что говорят и не задавай вопросов.
«Авторам следует полностью избегать использования процентов в padding’ах или margin’ах на flex-элементах» — с любовью, спецификация flexbox.
За этим следует моя самая любимая цитата из всех, когда-либо существовавших, спецификаций:
Заметка: это разночтение отстой, но оно в точности отражает текущее состояние мира (нет консенсуса среди реализаций, и нет консенсуса внутри CSSWG).
Осторожно! Бомбардировка честностью продолжается.
7. Margin’ы соседних элементов не схлопываются
Возможно, ты уже знаешь, что margin’ы иногда объединяются вместе. Ты также можешь знать, что margin’ы не объединяются вместе в некоторых других случаях.
И теперь мы все знаем, что margin’ы соседних flex-элементов никогда не объединяются.
8. z-index работает даже если position: static
Я не уверен, что мне есть дело до этого. Но я чувствую, что в один день, может быть, это пригодится. Это в точности та же причина, по которой я держу бутылку лимонного сока в холодильнике.
Однажды в моем доме будет другой человек, который скажет типа «эй, у тебя есть лимонный сок?», а я типа «конечно, в холодильнике», а он «спасибо, приятель. Эй, а надо ли мне указывать position если я хочу задать z-index на flex-элементе?», и тут я такой «не братан, не для flex-элементов».
9. Flex-basis тонкое и важное свойство
Когда твои требования перерастут ключевые слова initial, auto и none, все станет немного сложнее, и теперь, когда я понял flex-basis, забавно, знаешь, я не могу придумать как закончить это предложение. Оставь комментарий, если у тебя есть идеи.
Если у тебя есть три flex-элемента с flex-значениями 3, 3, 4, тогда они гарантированно займут 30%, 30% и 40% доступного пространства, независимо от их содержимого, если их flex-basis равен 0. И только если он равен нулю.
Тем не менее, если ты хочешь чтобы flex вел себя в более дружественной, предсказуемой манере, используй flex-basis: auto. В этом случае flexbox примет твои flex-значения во внимание, но также учтет и другие факторы, подумает немного, и подберет ширины, подходящие по его мнению тебе.
Взгляни на эту четкую диаграмму из спецификации:
Я уверен, что это упомянуто по меньшей мере в одном из блог-постов про flex, которые я читал, но по какой-то причине, не проникся пока не увидел эту картинку в спецификации (schmick pick in the spec)(тройная рифма если ты из Новой Зеландии).
10. align-items: baseline
Когда я хотел выравнять flex-элементы по вертикали, я всегда использовал align-items: center. Но также как с vertical-align, у тебя есть возможность установить значение в baseline, что может быть более подходящим если у твоих элементов различный размер шрифта, а ты хочешь выравнять их базу.
Возможно очевидно, align-self: baseline тоже работает.
11. Я довольно глуп
Сколько бы раз я не читал следующий параграф, я остался неспособным его понять.
Размер содержимого — это минимальный размер содержимого на основной оси, зажатый, если он имеет соотношение сторон, с помощью любых определенных минимальных и максимальных свойств кросс-размера, преобразованных через соотношение сторон, а затем дополнительно зажатых с помощью свойства максимального основного размера, если это определено.
The content size is the min-content size in the main axis, clamped, if it has an aspect ratio, by any definite min and max cross size properties converted through the aspect ratio, and then further clamped by the max main size property if that is definite.
Слова проходят через мои отверстия, преобразуются в электрические импульсы, путешествующие по моему оптическому нерву, и прибывают как раз вовремя, чтобы увидеть как мой мозг выбегает через черный ход в клубе дыма.
Как будто Минни Маус и Мэд Макс завели ребенка семь лет назад, и теперь он, будучи пьяным с мятного шнапса, оскорбляет всех в пределах слышимости словами, которые он узнал когда Мамочка и Папочка ругались.
Леди и Джентльмены, мы начали наш спуск в чепуху, что значит пришло время подвести итоги (или перестань читать, если ты здесь для изучения нового).
Самое интересное из того, что я узнал, читая спецификацию, это то, насколько неполным было мое понимание, несмотря на полдюжины блог-постов которые я прочитал, и на то, насколько относительно простым является flexbox. Оказывается, что «опыт» — это не просто занятие одним и тем же из года в год.
С удовольствием могу отметить, что время, потраченное мной на чтение, уже окупилось. Я прошелся по старому коду, выставил авто margin’ы, flex-значения в краткой записи auto или none, и задал минимальную ширину в ноль там, где это было нужно.
Я лучше отношусь к этому коду теперь, зная что я делаю это должным образом.
Еще я узнал, что несмотря на то, что спецификация — местами — перенасыщена и предназначена для вендоров как я и думал, все же содержит много дружественных слов и примеров. В ней даже выделены части которые скромные веб-разработчики могут пропустить.
Однако это спорный вопрос, потому что я рассказал тебе про все хорошие отрывки, так что тебе не нужно утруждать себя ее чтением.
Теперь, если позволите, мне надо идти и прочитать все остальные CSS спецификации.
P.S. Я крайне рекомендую прочитать следующий список всех flexbox багов по браузерам:
github.com/philipwalton/flexbugs
От переводчика: это мой первый опыт перевода зарубежных публикаций, если есть замечания/предложения/ремарки по качеству перевода или по содержимому, пишите в комментариях.
Принцип работы свойства z-index и автоматического margin в Flexbox
Дата публикации: 2016-06-28
От автора: Flexbox хорошо известен тем, что отлично решает такие задачи с макетами, как прилипающие футеры и колонки одинаковой высоты. Помимо этого, в Flexbox есть и другие полезные, но менее известные функции. Сегодня мы их и рассмотрим!
Flexbox и свойство z-index
Вы уже, наверное, знаете, что свойство z-index работает только на элементах с заданным позиционированием. По умолчанию у всех элементов задано position: static, т.е. они никак не спозиционированы. Позиционированным элемент будет считаться, если задать одно из следующих значений: relative, absolute, fixed или sticky.
«Флекс ячейки отрисовываются точно так же, как инлайновые блоки [CSS21]. Отличие только в том, что тут используется модифицированный порядок в документе, а все значения свойства z-index кроме auto создают контекст стека даже при position: static.»
Взгляните на демо ниже, чтобы понять принцип работы:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Flexbox и автоматический margin
Автоматический margin на флекс ячейках решает основные проблемы с UI. Для начала предположим, что мы хотим создать вот такой стандартный хедер:
Для этого мы будем использовать Flexbox. Никаких обтеканий, фиксированной ширины и т.д. Разметка:
В нашем примере роль флекс контейнера выполняет элемент nav, а логотип, основное меню и кнопки социальных сетей являются флекс ячейками. На картинке выше первые два элемента выравнены по левой стороне флекс контейнера вдоль главной оси. Кнопки социальных сетей же выравнены по правой стороне также вдоль основной оси.
Единственный способ выровнять элементы таким образом это использовать margin-right: auto на основном меню. Одной строкой кода мы переписываем стандартное выравнивание кнопок социальных сетей и прижимаем их к правому краю контейнера. Точно так же используем свойство align-self и переписываем стандартное выравнивание флекс ячеек вдоль оси.
Помимо автоматического внешнего отступа есть еще один метод. Первым делом необходимо удалить свойство margin-right у меню и прописать там flex-grow: 1.
Результат почти одинаковый, но есть одно существенное различие. В первом случае у меню заранее высчитанная ширина. То есть, при ширине окна в 1100 px ширина меню будет примерно такая:
Во втором методе ширина меню увеличивается, так как мы задали свойство flex-grow: 1. Ниже показана ширина меню при ширине окна в 1100 px:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Теперь представим, что мы захотели изменить макет. Вот наш новый макет:
Разметка остается без изменений. Нужно внести небольшие правки в CSS: