Резиновая верстка - как управлять блоками в 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 шт):

Автор решения: soledar10

Пример

*{
  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>

→ Ссылка
Автор решения: De.Minov

Ох, самое дурацкое, когда дизайнер меняет поток элементов.

Вот у вас поток следующий.

Десктоп и планшет:

<блок>
  <лого>
  <инпут>
  <что-то ещё>
</блок>

А потом в мобилке бац и:

<блок>
  <лого>
  <что-то ещё>
</блок>
<инпут>

Вот и как жить?


Есть несколько вариантов:

Вариант 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">
      &lt;p&gt;
    </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">
      &lt;p&gt;
    </div>
  </div>
</header>

Плюсы: Переносится даже эвенты и всякие плюшки переносимого элемента.
Минусы: Если много чего нужно переносить и при разных медиа, придётся написать большой JS.


Вариант 3:

Flexbox, всякие там order и прочие извращения, чтобы переместить элемент, как-то его отделить и прочее.

Я б написал пример, но чёт уже устал, если интересно, могу оформить, но позже :)

→ Ссылка
Автор решения: Qwertiy

Самый простой и современный вариант - использовать 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>

→ Ссылка
Автор решения: Qwertiy

Старый универсальный вариант на 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>

→ Ссылка