Урок 04. Теория: шкала отступов и размеров

📁 Раздел: Базовые утилиты ⏱️ Время изучения: ~50 мин 🎯 Сложность: Начальная

⚡ Кратко

Одна переменная --spacing = 0.25rem задаёт всю шкалу: число в классе умножается на неё. Отсюда простая арифметика: p-2 = 8px, p-4 = 16px, p-6 = 24px, p-8 = 32px. Промежутки между элементами задаются gap-* у контейнера, а не отступами у детей.

Шкала: одно число — один шаг

В Tailwind нет «отступа 18px по вкусу». Есть шкала, и она линейная:

--spacing: 0.25rem;          /* базовый шаг = 4px при обычном размере шрифта */

.p-1  { padding: calc(var(--spacing) * 1); }   /*  4px */
.p-2  { padding: calc(var(--spacing) * 2); }   /*  8px */
.p-4  { padding: calc(var(--spacing) * 4); }   /* 16px */
.p-8  { padding: calc(var(--spacing) * 8); }   /* 32px */

Правило перевода в голове: число × 4 = пиксели. Обратное: пиксели ÷ 4 = число. Дробные шаги тоже есть — p-0.5 (2px), p-1.5 (6px), p-2.5 (10px).

Шкала — как размерная сетка одежды. Есть S, M, L; нет «между M и L». Ограничение выглядит неудобным ровно до момента, когда десять человек шьют один костюм: тогда общая сетка — единственный способ получить одинаковые рукава.

Сравните: одна и та же карточка с разными значениями шкалы.

p-2 — 8px
p-4 — 16px
p-8 — 32px
<div class="flex flex-wrap items-start gap-4">
  <div class="rounded-lg border border-slate-300 bg-slate-50 p-2 text-sm text-slate-700">p-2 — 8px</div>
  <div class="rounded-lg border border-slate-300 bg-slate-50 p-4 text-sm text-slate-700">p-4 — 16px</div>
  <div class="rounded-lg border border-slate-300 bg-slate-50 p-8 text-sm text-slate-700">p-8 — 32px</div>
</div>

Четыре семейства

  • p-* — внутренний отступ (padding), фон заходит под него;
  • m-* — внешний отступ (margin), фон под него не заходит;
  • gap-* — промежуток между детьми flex- или grid-контейнера;
  • space-x-*/space-y-* — промежуток между соседями через margin у всех, кроме первого.

У каждого семейства есть приставки сторон: pt/pr/pb/pl (top/right/bottom/left), px/py (по горизонтали / по вертикали) и логические ps/pe (start/end — зависят от направления письма).

💡 Когда логические: если интерфейс когда-нибудь будет на арабском или иврите, ps-4 продолжит означать «отступ со стороны начала строки», а pl-4 останется слева и сломает раскладку.

gap или space — что выбрать

Практическое правило: всегда gap, если родитель — flex или grid. space-* оставьте для случаев, когда менять родителя нельзя.

gap-3 у flex-контейнера

A
B
C

space-x-3 у обычного блока

A B C
<div class="space-y-3">
  <p class="text-xs font-medium text-slate-500">gap-3 у flex-контейнера</p>
  <div class="flex gap-3">
    <div class="rounded bg-slate-900 px-3 py-2 text-xs text-white">A</div>
    <div class="rounded bg-slate-900 px-3 py-2 text-xs text-white">B</div>
    <div class="rounded bg-slate-900 px-3 py-2 text-xs text-white">C</div>
  </div>
  <p class="text-xs font-medium text-slate-500">space-x-3 у обычного блока</p>
  <div class="space-x-3">
    <span class="inline-block rounded bg-teal-700 px-3 py-2 text-xs text-white">A</span>
    <span class="inline-block rounded bg-teal-700 px-3 py-2 text-xs text-white">B</span>
    <span class="inline-block rounded bg-teal-700 px-3 py-2 text-xs text-white">C</span>
  </div>
</div>

Разница видна на переносе строк: gap честно держит промежуток и по вертикали, а space-x добавляет левый margin — при переносе получаются неровные отступы.

Размеры: w, h и size

Ширина и высота используют ту же шкалу плюс собственные значения:

  • w-64 — 16rem, число из шкалы;
  • w-full — 100%, w-1/2 — 50%, w-1/3 — 33.333%;
  • w-screen — 100vw, min-h-svh — «маленькая» высота вьюпорта, устойчивая к панели браузера на мобильных;
  • size-10 — ширина и высота одним классом (иконки, аватары);
  • min-w-*, max-w-*, min-h-*, max-h-* — ограничения.
size-8 · size-12 · size-16
<div class="flex items-center gap-4">
  <div class="size-8 rounded-full bg-indigo-600"></div>
  <div class="size-12 rounded-full bg-indigo-600"></div>
  <div class="size-16 rounded-full bg-indigo-600"></div>
  <span class="text-sm text-slate-600">size-8 · size-12 · size-16</span>
</div>

Ограничение ширины текста

Длинную строку тяжело читать: глаз теряет начало следующей. Поэтому текст ограничивают не по width, а по max-w-* — блок остаётся адаптивным, но не растягивается.

max-w-prose ограничивает строку комфортной длиной чтения. Блок по-прежнему сжимается на узком экране, но на широком не превращается в бесконечную строку, по которой невозможно вести взгляд.

<p class="max-w-prose text-sm text-slate-700">
  max-w-prose ограничивает строку комфортной длиной чтения. Блок по-прежнему
  сжимается на узком экране, но на широком не превращается в бесконечную строку,
  по которой невозможно вести взгляд.
</p>

Произвольные значения и отрицательные отступы

<div class="w-[37px] p-[3px] mt-[calc(100%-2rem)]">…</div>
<div class="-mt-4">поднять блок на 16px вверх</div>

Квадратные скобки — «аварийный выход» из шкалы: точный размер логотипа, значение из макета, вычисление через calc(). Отрицательные отступы (минус перед классом) применяются для «наезжающих» элементов — аватара поверх обложки, кнопки, выходящей за край карточки.

Если произвольных значений в файле стало больше, чем значений из шкалы, — это сигнал, что дизайн-макет не согласован со шкалой. Лучше договориться о шкале, чем расставлять скобки.