Когда дело доходит до выставления ширины блока, большинство привычно тянется к px, % или auto. Но в CSS есть отдельная группа значений, которые рассчитывают размер не по сетке и не по контейнеру, а по самому содержимому элемента. Их так и называют — intrinsic sizing keywords или «размеры по содержимому»: min-content, max-content и fit-content.
В работе они встречаются нечасто — не потому что бесполезны, а потому что мало кто помнит, чем именно отличаются. Разберём по очереди и увидим, в каких ситуациях именно эти три значения убирают необходимость городить вычисления через calc() или JavaScript.
Значение min-content
Браузер ставит элементу такую ширину, при которой содержимое ещё помещается без переполнения, но не уже. Для текста минимальная неуменьшаемая единица — самое длинное слово в блоке: его не разорвёшь, иначе получится не слово.
.label {
width: min-content;
background: #fef3c7;
padding: 8px 12px;
}
Если внутри .label лежит фраза «Документация по API», ширина блока схлопнется до ширины слова «Документация» — самого длинного. Все остальные слова перенесутся на свои строки.
Тонкость в том, что «неразрывной единицей» для браузера может оказаться не только слово. Если внутри есть картинка фиксированной ширины, длинное URL-подобное слово или элемент с white-space: nowrap, минимальная ширина будет уже по этому объекту, и блок получится шире, чем кажется на глаз.
Значение max-content
Это полная противоположность. Элемент получает такую ширину, как если бы переноса строк не было вообще: всё содержимое выложено в одну строку, и блок ровно по нему.
.tag {
width: max-content;
background: #dbeafe;
padding: 4px 10px;
border-radius: 4px;
}
Полезно для тегов, бейджей, кнопок «по контенту» — когда нужно, чтобы элемент занимал ровно столько, сколько занимает его текст, без подсчёта в пикселях и без display: inline-block со всеми его побочными эффектами.
Главный риск: если содержимое окажется длиннее родителя, элемент выйдет за границы контейнера. max-content не оглядывается на родителя — он смотрит только на собственный контент.
Значение fit-content
Компромиссное значение: ведёт себя как max-content, пока контент помещается в родителя, и как min-content, как только перестаёт. Иначе говоря, элемент «тянется по контенту, но не больше контейнера».
.notice {
width: fit-content;
margin: 0 auto;
padding: 12px 20px;
background: #f0fdf4;
border: 1px solid #86efac;
}
Это, пожалуй, самое практичное из трёх значений: получаем плотный по содержимому блок, который при этом гарантированно не вылезет за пределы родителя. Идеально для уведомлений, всплывающих меток, центрированных карточек неизвестной длины.
Функциональная форма fit-content()
У fit-content есть менее известный двойник — функция с аргументом. Аргумент задаёт верхний предел ширины: элемент тянется по контенту, но не превышает указанное значение, даже если родитель шире.
.tooltip {
width: fit-content(300px);
padding: 8px 12px;
background: #1f2937;
color: #fff;
}
Для тултипов, информационных плашек, узких всплывашек — естественнее, чем связка max-width: 300px; width: max-content. В одну строку.
Где это реально пригождается
Большинство людей знакомятся с min-content и max-content именно через CSS Grid — потому что в треках сетки они работают особенно мощно.
В CSS Grid
Колонки и строки в Grid принимают эти ключевые слова напрямую и в составе функции minmax(). Классический рецепт «первая колонка по контенту, вторая занимает всё остальное»:
.layout {
display: grid;
grid-template-columns: max-content 1fr;
gap: 24px;
}
Ещё более практичный паттерн — колонка-резинка, которая не схлопывается уже своего содержимого:
.sidebar-layout {
display: grid;
grid-template-columns: minmax(min-content, 240px) 1fr;
}
Здесь сайдбар держится в районе 240px, но при необходимости может ужаться до ширины своего самого длинного элемента и не дальше. Без min-content в нижней границе сайдбар при узком экране начал бы рвать слова или вылезать на основной контент.
В Flexbox
В Flex эти же значения принимает flex-basis, а также width у flex-элементов:
.toolbar {
display: flex;
gap: 8px;
}
.toolbar .label {
flex-basis: max-content;
}
Удобно, когда нужно, чтобы один из flex-элементов гарантированно растянулся по своему содержимому, а остальные распределили оставшееся место.
В обычных блоках
Никакого Grid и Flex не нужно. Любой блочный элемент примет width: fit-content и будет вести себя как описано выше. Это, кстати, удобный способ центрировать блок неизвестной ширины через margin: 0 auto: fit-content уберёт лишнюю ширину, а margin центрирует то, что осталось.
На что не путать
Эти три значения часто конкурируют в голове с другими способами задать ширину. Чтобы не путаться:
- auto — для блочных элементов это «занять всю доступную ширину родителя». Это поведение по умолчанию для div, section и т. д. Никакого отношения к содержимому не имеет.
- 100% — ровно ширина родителя, без учёта box-sizing в полной мере и тоже без оглядки на контент.
- 1fr в Grid — занимает доступное пространство трека, делит его поровну с другими fr-треками. Но fr-трек не учитывает минимальный размер контента: длинное слово может вылезти из 1fr-колонки. Поэтому в реальной вёрстке часто используют minmax(0, 1fr) или minmax(min-content, 1fr).
Эти размеры читают контейнер. min-content/max-content/fit-content читают контент. Это и есть та самая категория «intrinsic sizing», ради которой группу и придумали.
Поддержка браузерами
Это не «экспериментальная фича» и не «что-то для будущего», а уже привычная часть CSS — статус Baseline с января 2020 года.
Итог
Если запомнить одно правило, оно такое: auto и 100% думают про родителя, а min-content/max-content/fit-content — про содержимое. Когда ширину диктует именно контент (тег, бейдж, плашка-уведомление, колонка с заголовком переменной длины) — эти три значения убирают необходимость в магических числах и медиа-запросах. fit-content в большинстве задач достаточно одного, остальные два пригождаются точечно — чаще всего в Grid и Flex.
Полный интерактивный пример различий.
Комментарии (0)