Гибкий макет - это вёрстка, где ширина блоков задана не в жёстких пикселях, а в процентах от родителя, поэтому вся структура сама растягивается или сжимается под любой экран. Перевести фиксированный макет в проценты помогает простая формула: target ÷ context = result.
В этом уроке
Попробуй прямо сейчас: числа на картинке - настоящие, их вычисляет сам браузер. Поменяй у .inner значение width на 80% и посмотри, как изменится итоговое число в пикселях у самого вложенного блока - оно посчитано от ширины СРЕДНЕГО блока, а не от внешнего.
От px к процентам: формула target ÷ context
Если есть готовый макет с фиксированными размерами - например, сайдбар шириной 350px внутри контейнера 1000px - его легко перевести в проценты по формуле Итана Маркотта: target ÷ context = result, то есть "нужный размер" делим на "размер контейнера, в котором он находится". 350 ÷ 1000 = 0.35, то есть 35%. Так же переводятся отступы и любые другие горизонтальные размеры. Это дополняет уже знакомые относительные единицы для текста - px, em и rem из отдельного урока - только здесь речь о ширине самих блоков макета, а не о размере шрифта.
.sidebar { width: 35%; } - тот же сайдбар, посчитанный по формуле, теперь тянется вместе с контейнером.
.sidebar { width: 350px; } - при уменьшении контейнера меньше 350px сайдбар либо вылезет за края, либо столкнётся с соседними блоками.
От чего отсчитывается процент
Здесь легко ошибиться: ширина в процентах отсчитывается не от экрана целиком, а от ширины БЛИЖАЙШЕГО родительского элемента - точно так же, как уже говорилось в уроке про padding про процентные вертикальные отступы. Из этого следует важный практический момент: вложенные друг в друга проценты ПЕРЕМНОЖАЮТСЯ, а не складываются. Если внешний блок - 400px, блок внутри него с width: 50% получит примерно 200px, а ещё один блок с width: 50% внутри ТОГО получит уже примерно 100px - то есть 25% от самого внешнего блока, а не 50%.
проверять цепочку родителей - прежде чем задавать %, полезно посчитать, от какого именно размера он в итоге отсчитается.
ожидание, что 50% внутри 50% всё ещё даст половину от самого внешнего блока - на деле получится только четверть.
Гибкость с разумным пределом: max-width
Чистые проценты без ограничений создают свою проблему: на очень широком мониторе блок шириной 100% растянется на весь экран, и строка текста станет неудобно длинной для чтения. Решение простое - сочетать width: 100% с max-width, задающим разумный потолок. Тогда блок остаётся гибким на маленьких и средних экранах, но на больших просто перестаёт расти дальше заданного предела.
.container { width: 100%; max-width: 1200px; margin: 0 auto; } - гибкий на маленьких экранах, ограниченный на больших, да ещё и центрируется по горизонтали.
.container { width: 100%; } без max-width - на мониторе 2560px и шире контент растягивается на весь экран, читать неудобно.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Считают, что % всегда отсчитывается от экрана целиком | Реальный расчёт идёт от ширины БЛИЖАЙШЕГО родителя, а не от viewport | Проверять размер родительского элемента, прежде чем задавать % |
| Забывают, что вложенные проценты перемножаются | Итоговая ширина оказывается заметно меньше ожидаемой | Считать итоговый процент от самого верхнего контейнера, а не только от прямого родителя |
| Задают width: 100% без max-width | На больших мониторах контент растягивается на весь экран, читать неудобно | Комбинировать width: 100% с разумным max-width |
| Переводят px в % "на глаз", без формулы | Пропорции макета получаются неточными | Использовать формулу target ÷ context = result |
Шпаргалка
| Что нужно | Как сделать |
|---|---|
| Формула перевода px в % | target ÷ context = result (например, 350 ÷ 1000 = 35%) |
| От чего отсчитывается width в % | от ширины БЛИЖАЙШЕГО родителя, не всей страницы |
| Вложенные проценты | перемножаются (50% внутри 50% = 25% от внешнего блока) |
| Гибкость с пределом | width: 100%; max-width: конкретное значение; |
| Классическое русское название техники | "резиновая вёрстка" |
Коротко: отвечаем на вопросы
От чего отсчитывается ширина в процентах?
От ширины ближайшего родительского элемента, а не от экрана целиком. Если родитель сам задан в процентах, проценты внутри него перемножаются, а не складываются.
Как перевести пиксели в проценты?
По формуле target ÷ context = result: нужный размер делим на размер контейнера, в котором он находится. Например, сайдбар 350px внутри контейнера 1000px даёт 350 ÷ 1000 = 35%.
Что делать, если проценты дают слишком широкий блок на большом экране?
Сочетать width: 100% с max-width, задающим разумный потолок ширины. Блок остаётся гибким на маленьких и средних экранах, но перестаёт растягиваться дальше заданного предела на очень больших мониторах.