Fluid layout: использование относительных единиц и calc()

Почему гибкий макет — это сила 💪

Фиксированные пиксели (px) — это прошлый век. В мире, где устройства бывают от 320px до 8K, только относительные единицы и calc() помогут создать по-настоящему адаптивный дизайн без костылей.

Гибкий макет (fluid layout) — это когда элементы плавно меняют размеры в зависимости от доступного пространства. Никаких резких скачков на брейкпоинтах!


Единицы измерения: %, vw, vh, rem, em

Проценты (%)

Работают относительно родителя. Если родитель — body с width: 1000px, то width: 50% у ребёнка = 500px.

.parent {
  width: 80%; /* 80% от ширины его родителя */
}

.child {
  width: 50%; /* 50% от ширины .parent */
}

🔥 Совет: % для height работает, только если у родителя явно задана высота.

Viewport-единицы (vw, vh, vmin, vmax)

  • 1vw = 1% ширины окна
  • 1vh = 1% высоты окна
  • vmin — минимум из vw и vh
  • vmax — максимум из vw и vh
.fullscreen-block {
  width: 100vw;  /* займёт всю ширину экрана */
  height: 50vh;  /* половина высоты окна */
}

rem и em

  • rem — зависит от размера шрифта <html> (по умолчанию 16px).
  • em — зависит от размера шрифта родителя.
html {
  font-size: 16px; /* 1rem = 16px */
}

.parent {
  font-size: 20px; /* 1em = 20px внутри .parent */
}

.child {
  font-size: 1.5em; /* 30px */
  padding: 1rem;    /* 16px (от html) */
}

⚠️ Ловушка em: вложенные элементы с em умножают размеры рекурсивно.


Магия calc(): математика в CSS 🧮

calc() позволяет комбинировать разные единицы в одном выражении:

.block {
  width: calc(100% - 40px); /* ширина родителя минус 40px */
  height: calc(100vh - 80px);
  margin: calc(2rem + 5vw); /* адаптивный отступ */
}

Пример: резиновый контейнер с отступами

Хотим, чтобы блок занимал всю ширину, но не прилипал к краям на маленьких экранах?

.container {
  width: calc(100% - 2rem); /* 100% минус отступы по 1rem слева и справа */
  max-width: 1200px;        /* но не шире 1200px */
  margin: 0 auto;           /* центрирование */
}

Комбинируем vw и rem для типографики

Делаем шрифт адаптивным, но с минимальным и максимальным размером:

html {
  font-size: calc(16px + 0.5vw); /* растёт с шириной экрана */
}

@media (min-width: 1600px) {
  html {
    font-size: 24px; /* ограничиваем рост */
  }
}

Практика: создаём гибкую карточку

CSS

.card {
  display: flex;
  flex-direction: column;
  width: calc(100% - 2rem); /* адаптивная ширина */
  max-width: 400px;         /* не больше 400px */
  margin: 2rem auto;
  border: 1px solid #ddd;
  border-radius: 0.5rem;
  overflow: hidden;
  background-color: #fff;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
}

.card img {
  width: 100%; /* изображение растягивается по ширине */
  height: auto;
}

.card-content {
  padding: 1rem;
  font-size: calc(1rem + 0.2vw); /* адаптивный текст */
}

.card-content h2 {
  margin: 0 0 0.5em;
  font-size: 1.5em;
}

.card-content p {
  line-height: 1.6;
  margin-bottom: 1rem;
}

button {
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  background-color: #3498db;
  color: white;
  border: none;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

button:hover {
  background-color: #2980b9;
}

HTML

<div class="card">
  <img src="https://placekitten.com/400/250" alt="Product image">
  <div class="card-content">
    <h2>Кототерапия</h2>
    <p>Лучшее средство от стресса — пушистый кот. Гибкий дизайн и мягкие лапки.</p>
    <button>Купить</button>
  </div>
</div>
Скрыть рекламу навсегда

🧠 Учёба без воды и зубрёжки

Закрытый Boosty с наработками опытного преподавателя.

Объясняю сложное так, чтобы щелкнуло.

🚀 Забрать доступ к Boosty