Практика Flexbox

Готовые паттерны раскладок на Flexbox: навигация, карточки, Holy Grail, центрирование, media object, sticky footer. Каждый паттерн — рабочий CSS-код для реальных задач.

Зачем нужно

Теория Flexbox без практики быстро забывается. Эти паттерны покрывают 90% задач верстки компонентов и могут быть адаптированы под любой проект.

Где используется

  • Все типичные компоненты UI
  • Landing-страницы
  • Приложения и дашборды
  • Формы и карточки

Предпосылки


1. Навигационная панель

.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  height: 60px;
  background: #1a1a2e;
  color: white;
}

.navbar__logo {
  flex: 0 0 auto;
  font-size: 1.25rem;
  font-weight: 700;
}

.navbar__links {
  display: flex;
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.navbar__actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

/* Мобильная: колонка */
@media (max-width: 768px) {
  .navbar {
    flex-direction: column;
    height: auto;
    padding: 16px;
    gap: 12px;
  }
}

2. Карточная раскладка

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.card {
  flex: 1 1 300px; /* Минимум 300px, растёт */
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.card__image {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.card__body {
  flex: 1; /* Растянуть — кнопка будет внизу */
  padding: 20px;
}

.card__footer {
  padding: 16px 20px;
  border-top: 1px solid #eee;
}

3. Holy Grail Layout

.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.page__header {
  flex: 0 0 auto;
  padding: 16px 24px;
  background: #1a1a2e;
  color: white;
}

.page__body {
  flex: 1;
  display: flex;
}

.page__sidebar-left {
  flex: 0 0 220px;
  padding: 20px;
  background: #f8f9fa;
}

.page__main {
  flex: 1;
  padding: 20px;
}

.page__sidebar-right {
  flex: 0 0 280px;
  padding: 20px;
  background: #f8f9fa;
}

.page__footer {
  flex: 0 0 auto;
  padding: 16px 24px;
  background: #2c3e50;
  color: white;
}

/* Мобильная: всё в колонку */
@media (max-width: 768px) {
  .page__body {
    flex-direction: column;
  }
  .page__sidebar-left,
  .page__sidebar-right {
    flex-basis: auto;
  }
}

4. Центрирование

/* Абсолютное центрирование */
.center-absolute {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* Центрирование с margin: auto */
.center-margin {
  display: flex;
  min-height: 100vh;
}
.center-margin > .content {
  margin: auto; /* Центр по обеим осям */
}

5. Media Object

.media {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.media__image {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
}

.media__body {
  flex: 1;
  min-width: 0; /* Для корректного truncate */
}

.media__title {
  font-weight: 600;
  margin-bottom: 4px;
}

.media__text {
  color: #666;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Футер всегда внизу страницы */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
}

main {
  flex: 1; /* Растягивает main, прижимая footer вниз */
}

footer {
  flex-shrink: 0;
  padding: 24px;
  background: #2c3e50;
  color: white;
}

7. Форма с инлайн-полями

.search-form {
  display: flex;
  gap: 8px;
}

.search-form__input {
  flex: 1;
  padding: 10px 16px;
  border: 2px solid #ddd;
  border-radius: 8px;
  font-size: 1rem;
}

.search-form__button {
  flex: 0 0 auto;
  padding: 10px 24px;
  background: #3498db;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

8. Тэги / Chips

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 12px;
  background: #e8f4fd;
  color: #2980b9;
  border-radius: 16px;
  font-size: 0.875rem;
}

.tag__close {
  display: inline-flex;
  cursor: pointer;
  font-size: 0.75rem;
}

Частые ошибки

  1. Карточки разной высоты — забыт flex: 1 на .card__body:

    /* Кнопки прыгают на разной высоте */
    .card { display: flex; flex-direction: column; }
    .card__body { flex: 1; } /* Это выравнивает футеры */
    
  2. Текст не обрезается в flex-элементе — нужен min-width: 0:

    .flex-child {
      min-width: 0; /* Позволяет text-overflow работать */
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    
  3. Мобильная версия без flex-direction: column — контент слишком узкий

Практика

  • Создать навбар с лого, ссылками и кнопками
  • Сверстать карточную раскладку с flex-wrap
  • Реализовать Holy Grail Layout с мобильной версией
  • Создать sticky footer
  • Сверстать media object (аватар + текст)

Связанные темы

Ресурсы