Резиновая верстка - как управлять блоками в header
Ребят, привет! Помогите, пожалуйста, с резиновой версткой:
Начинаю с мобильной версии (нужно сделать именно резиновую верстку для мобильного устройства, планшета и десктоп версию) - делаю верстку для телефона, но проблема возникает в том, что под телефон блоки располагаются в макете друг под другом, как на фото-схеме, а в планшете и десктопе - в ряд - тоже нарисовала, input на них становится между логотипом и кнопкой профиля. Не понимаю, как это реализовать - или что почитать? Спасибо! 
<div class="header">
<div class="header__section">
<div class="header__item header__logo">
<img src="img/logo.svg" alt="">
</div>
<div class="header__search">
<input type="text" placeholder="Найти...">
</div>
<div class="header__item header__button-icon">
<a href="#"><img src="img/profile-icon.svg" alt="profile-icon"></a>
</div>
</div>
</div>
Ответы (4 шт):
Пример
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
.header__section {
display: flex;
align-items: center;
justify-content: space-between;
padding: .5rem 1rem;
background-color: #f7f7f7;
}
.header__logo {
background-color: #000;
width: 4rem;
height: 2rem;
}
@media (max-width: 576px) {
.header__section {
flex-wrap: wrap;
}
.header__search {
order: 1;
width: 100%;
margin-top: .5rem;
}
.header__search input {
width: 100%;
}
}
<div class="header">
<div class="header__section">
<div class="header__item header__logo">
<img src="img/logo.svg" alt="">
</div>
<div class="header__search">
<input type="text" placeholder="Найти...">
</div>
<div class="header__item header__button-icon">
<a href="#"><img src="img/profile-icon.svg" alt="profile-icon"></a>
</div>
</div>
</div>
Ох, самое дурацкое, когда дизайнер меняет поток элементов.
Вот у вас поток следующий.
Десктоп и планшет:
<блок>
<лого>
<инпут>
<что-то ещё>
</блок>
А потом в мобилке бац и:
<блок>
<лого>
<что-то ещё>
</блок>
<инпут>
Вот и как жить?
Есть несколько вариантов:
Вариант 1:
Используем два "инпута" в разных местах, один показываем в одном месте на десктопе и планшете, другой в другом на мобилке.
.header {
display: block;
width: 100%;
color: #12153a;
}
.header__block {
display: flex;
justify-content: space-between;
align-items: center;
border: 2px solid #12153a;
width: 100%;
padding: 1em 2em;
box-sizing: border-box;
}
.header__input {
display: block;
width: 100%;
background-color: #e3b6ea;
border: 2px solid #12153a;
padding: 1em 2em;
box-sizing: border-box;
text-align: center;
}
.header-input--desktop {
margin: 0 2em;
}
.header-input--mobile {
display: none;
border-top: none;
}
@media (max-width: 768px) {
.header-input--desktop {
display: none;
}
.header-input--mobile {
display: block;
}
}
<header class="header">
<div class="header__block">
<div class="header__logo">logo</div>
<div class="header__input header-input--desktop">input</div>
<div class="header__other">
<p>
</div>
</div>
<div class="header__input header-input--mobile">input</div>
</header>
Основной минус - два элемента, по сути одинаковых, если требуется вешать слушатель, придётся вешать на оба два..
Вариант 2:
JSом перемешаем элемент в другое место.
const header__block = document.querySelector('.header__block'),
header__input = document.querySelector('.header__input'),
header__logo = document.querySelector('.header__logo'),
mediaPhone = window.matchMedia('(max-width: 768px)');
ChangeHeaderInput(mediaPhone.matches);
mediaPhone.addListener(function(e) {ChangeHeaderInput(e.matches)});
function ChangeHeaderInput(isPhone) {
MoveElement(header__input, isPhone ? header__block : header__logo);
}
function MoveElement(el, to) {
to.after(el);
}
.header {
display: block;
width: 100%;
color: #12153a;
}
.header__block {
display: flex;
justify-content: space-between;
align-items: center;
border: 2px solid #12153a;
width: 100%;
padding: 1em 2em;
box-sizing: border-box;
}
.header__input {
display: block;
width: 100%;
background-color: #e3b6ea;
border: 2px solid #12153a;
padding: 1em 2em;
margin: 0 2em;
box-sizing: border-box;
text-align: center;
}
@media (max-width: 768px) {
.header__input {
border-top: none;
margin: 0;
}
}
<header class="header">
<div class="header__block">
<div class="header__logo">logo</div>
<div class="header__input">input</div>
<div class="header__other">
<p>
</div>
</div>
</header>
Плюсы: Переносится даже эвенты и всякие плюшки переносимого элемента.
Минусы: Если много чего нужно переносить и при разных медиа, придётся написать большой JS.
Вариант 3:
Flexbox, всякие там order и прочие извращения, чтобы переместить элемент, как-то его отделить и прочее.
Я б написал пример, но чёт уже устал, если интересно, могу оформить, но позже :)
Самый простой и современный вариант - использовать grid:
main {
display: grid;
gap: .5em 1em;
grid-template: "logo input icon" / auto 1fr auto;
}
div {
padding: .25em .5em;
background: silver;
}
@media (max-width: 600px) {
main {
grid-template: "logo . icon" "input input input" / auto 1fr auto;
}
}
<main>
<div style="grid-area: logo">logo</div>
<div style="grid-area: input">input</div>
<div style="grid-area: icon">icon</div>
</main>
Старый универсальный вариант на float'ах:
main {
overflow: hidden;
}
div {
padding: .25em .5em;
background: silver;
}
.logo {
float: left;
margin-right: 1em;
}
.icon {
float: right;
margin-left: 1em;
}
.input {
overflow: hidden;
}
@media (max-width: 600px) {
.logo, .icon {
margin-bottom: .5em;
}
.input {
clear: both;
}
}
<main>
<div class="logo">logo</div>
<div class="icon">icon</div>
<div class="input">input</div>
</main>