Создание адаптивной навигационной панели с Flexbox

Тренажер по CSS для пользователей с начальным уровнем подготовки.

Тренажер CSS

Эта серия упражнений поможет вам освоить использование Flexbox для создания современных и адаптивных навигационных панелей. Вы попрактикуетесь в позиционировании элементов, управлении пространством между ними и адаптации макета под разные размеры экранов. Задания построены от простого к сложному: начнем с базового применения Flexbox к списку ссылок и постепенно перейдем к созданию полностью адаптивного меню. Вам будет предоставлен готовый HTML-код и CSS-стили с пропусками, которые нужно будет заполнить, чтобы достичь желаемого результата. Теории здесь нет – только практика!

Список тем

Превращаем список в Flex-контейнер

Начнем с основ. У нас есть навигационное меню, сверстанное с помощью обычного списка `<ul>`. Ваша задача — превратить этот список в flex-контейнер, чтобы его дочерние элементы (`<li>`) стали flex-элементами и выстроились в ряд. Пока не беспокойтесь о внешнем виде, сосредоточьтесь на применении основного свойства Flexbox.

CSS
nav ul {
  /* Превратите этот список в flex-контейнер */
  input1: input2;

  /* Уберем стандартные маркеры и отступы для чистоты */
  list-style: none;
  padding: 0;
  margin: 0;
  background-color: #eee; /* Фон для наглядности */
}

nav li {
  border: 1px solid #ccc; /* Границы для наглядности */
  padding: 10px;
}

nav a {
  text-decoration: none;
  color: #333;
}
HTML
<nav class="main-nav">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Чтобы элемент стал flex-контейнером, ему необходимо задать свойство `display` со значением `flex`. Примените это свойство к селектору `nav ul`.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Выравнивание элементов по горизонтали

Теперь, когда элементы навигации расположены в ряд, давайте распределим их по всей доступной ширине панели. Используйте свойство Flexbox, отвечающее за выравнивание элементов вдоль главной оси (в данном случае, горизонтальной), чтобы создать равное пространство между ними.

CSS
nav ul {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
  background-color: #eee;

  /* Распределите элементы по горизонтали */
  input1: input2;
}

nav li {
  border: 1px solid #ccc;
  padding: 10px;
}

nav a {
  text-decoration: none;
  color: #333;
}
HTML
<nav class="main-nav">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Для управления пространством между flex-элементами вдоль главной оси используется свойство `justify-content`. Попробуйте значение `space-between` (крайние элементы прижимаются к краям контейнера) или `space-around` (равное пространство со всех сторон каждого элемента).
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Вертикальное центрирование

В нашем примере есть логотип и список ссылок. Сейчас они могут быть не выровнены по вертикали. Используйте Flexbox, чтобы выровнять и логотип, и список ссылок по центру относительно друг друга по вертикальной оси (поперечной оси для flex-контейнера `nav`).

CSS
nav.main-nav {
  display: flex;
  background-color: #f0f0f0;
  padding: 10px;

  /* Выровняйте логотип и список по центру по вертикали */
  input1: input2;

  /* Добавим немного пространства между логотипом и списком */
  justify-content: space-between;
}

.logo {
  font-weight: bold;
  font-size: 20px;
}

nav ul {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
}

nav li {
  margin-left: 15px; /* Добавим отступ между пунктами меню */
}

nav a {
  text-decoration: none;
  color: #333;
}
HTML
<nav class="main-nav">
  <div class="logo">MyApp</div>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Для выравнивания элементов по поперечной оси flex-контейнера используется свойство `align-items`. Значение `center` позволит выровнять дочерние элементы по центру.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Адаптивность: перенос строк

На узких экранах пункты меню могут не помещаться в одну строку. Чтобы они автоматически переносились на следующую строку при нехватке места, нужно разрешить перенос flex-элементов внутри контейнера `<ul>`. Добавьте соответствующее свойство.

CSS
nav.main-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #f0f0f0;
  padding: 10px;
}

.logo {
  font-weight: bold;
  font-size: 20px;
}

nav ul {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;

  /* Разрешите перенос пунктов меню */
  input1: input2;
}

nav li {
  margin-left: 10px;
  margin-bottom: 5px; /* Добавим отступ снизу при переносе */
  background-color: #ddd; /* Фон для наглядности */
  padding: 5px 8px;
}

nav a {
  text-decoration: none;
  color: #333;
}
HTML
<nav class="main-nav">
  <div class="logo">MyApp</div>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Portfolio</a></li>
    <li><a href="#">Blog</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Используйте свойство `flex-wrap` со значением `wrap` для контейнера `nav ul`, чтобы разрешить перенос его дочерних элементов (`<li>`) на новую строку.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Адаптивность: меняем направление в Media Query

Давайте сделаем навигацию полностью вертикальной на маленьких экранах (например, меньше 400px). Используйте медиа-запрос (`@media`) и измените направление главной оси для flex-контейнера `nav ul` с горизонтального на вертикальное.

CSS
nav.main-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #f0f0f0;
  padding: 10px;
}

.logo {
  font-weight: bold;
  font-size: 20px;
}

nav ul {
  display: flex;
  flex-wrap: wrap; /* Оставим перенос для средних размеров */
  list-style: none;
  padding: 0;
  margin: 0;
}

nav li {
  margin-left: 10px;
  margin-bottom: 5px;
  background-color: #ddd;
  padding: 5px 8px;
}

nav a {
  text-decoration: none;
  color: #333;
}

/* Стили для маленьких экранов */
@media (max-width: 400px) {
  nav.main-nav {
    /* На маленьком экране логотип и меню друг под другом */
    flex-direction: column;
    align-items: flex-start; /* Выравниваем все по левому краю */
  }

  nav ul {
    /* Измените направление flex-элементов на вертикальное */
    input1: input2;
    width: 100%; /* Растянем список на всю ширину */
    margin-top: 10px; /* Добавим отступ сверху */
  }

  nav li {
    margin-left: 0; /* Убираем отступ слева */
    width: 100%; /* Растянем пункты на всю ширину */
    text-align: center; /* Центрируем текст */
  }
}
HTML
<nav class="main-nav">
  <div class="logo">MyApp</div>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Внутри блока `@media (max-width: 400px)` для селектора `nav ul` измените свойство `flex-direction` на `column`. Это заставит flex-элементы (`<li>`) располагаться друг под другом.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Растягивание элемента на всю доступную ширину

Представим, что мы хотим, чтобы первый пункт меню (`Home`) занимал все доступное пространство слева, отодвигая остальные пункты вправо. Используйте свойство Flexbox, которое позволяет элементу 'расти' и занимать свободное место.

CSS
nav ul {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
  background-color: #eee;
  align-items: center; /* Выровняем по вертикали для наглядности */
  height: 50px;
}

nav li {
  border: 1px solid #ccc;
  padding: 10px;
}

nav li:first-child {
  /* Заставьте этот элемент занять все свободное место */
  input1: input2;
  background-color: #ccf; /* Выделим цветом */
}

nav a {
  text-decoration: none;
  color: #333;
}
HTML
<nav class="main-nav">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Примените свойство `flex-grow` со значением `1` к первому элементу списка (`nav li:first-child`). Это заставит его занять все доступное пространство по главной оси.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку

Прижимаем последний элемент вправо

Часто в навигации требуется разместить основной блок ссылок слева, а один или два элемента (например, 'Login' или 'Settings') — справа. Используйте автоматические отступы во Flexbox, чтобы 'отодвинуть' последний элемент списка вправо.

CSS
nav ul {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
  background-color: #eee;
  align-items: center;
  height: 50px;
}

nav li {
  border: 1px solid #ccc;
  padding: 10px;
  margin-right: 10px; /* Небольшой отступ между элементами */
}

nav li:last-child {
  /* Отодвиньте этот элемент вправо */
  input1: input2;
  margin-right: 0; /* Уберем правый отступ у последнего элемента */
  background-color: #fcc; /* Выделим цветом */
}

nav a {
  text-decoration: none;
  color: #333;
}
HTML
<nav class="main-nav">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Features</a></li>
    <li><a href="#">Pricing</a></li>
    <li><a href="#">Login</a></li>
  </ul>
</nav>
Примените свойство `margin-left` со значением `auto` к последнему элементу списка (`nav li:last-child`). Во flex-контейнере `margin: auto` по направлению главной оси забирает все доступное пространство, отодвигая элемент.
Заполнить ответами все поля
Результат
Сообщения
Выполнить
Отметить решенным
Показать подсказку
НайтиКурс.Ру