Перейти к содержанию

Внутренние размеры элементов

До сих пор мы чаще задавали размер числом или долей доступного пространства. Но у содержимого есть собственные требования к размеру: строка может быть показана целиком или перенесена по допустимым границам. Внутренние размеры позволяют учитывать эти требования явно. Они объясняют и компактную подпись, и случай, когда длинное слово мешает сжать столбец.

Продолжим каталог с согласованными рядами. Данные шести курсов не меняются. Результат урока — небольшая подпись количества, занимающая место по содержимому, и поля формы с понятными ограничениями ширины. Заодно разберём разницу между min-content, max-content и fit-content, не превращая все элементы страницы в коробки одинакового размера.

Размер из содержимого

max-content описывает размер, при котором содержимое не требует мягких переносов. Для короткого количества уроков он невелик, а для длинного предложения может оказаться шире окна. min-content учитывает возможные переносы и стремится к минимальному внутреннему размеру без такого переполнения, которое нельзя устранить разрешённым переносом. Для текста на результат влияют пробелы, правила разрыва и отдельные длинные слова.

Это не две постоянные величины, записанные в HTML. После изменения текста или шрифта внутренний размер меняется. Поэтому подпись «12 уроков» и длинная аннотация одного курса имеют разные требования, даже если находятся в одинаковой карточке. Сначала выбираем роль элемента, затем выбираем способ определения его коробки.

Добавьте в конец styles.css следующий блок. Список и подрешётки предыдущего урока сохраняются. Здесь вводятся новые ограничения конкретных элементов, поэтому менять всю схему Grid не нужно.

@layer components {
.layout-lab .course-count { inline-size: fit-content; max-inline-size: 100%; padding-inline: .5rem; background: #30323f; border-radius: .25rem; }
.layout-lab .course-title { min-inline-size: 0; overflow-wrap: anywhere; }
.layout-lab .lab-request form { max-inline-size: 34rem; }
.layout-lab .lab-request input { inline-size: min(100%, 28rem); }
}

Подпись количества ожидается на небольшом отличающемся фоне. Она не должна автоматически растягиваться на всю ширину метаданных: inline-size: fit-content выбирает размер, зависящий от содержимого и доступного пространства. Внутренний горизонтальный отступ отделяет число от края фона. Максимальное ограничение не позволяет коробке сознательно получить больше ширины своего контейнера.

fit-content является ключевым словом для размера коробки. Его смысл ограничен внутренними минимумом и максимумом, поэтому оно не обещает сжать неразрывное содержание до произвольного числа. Для длинного слова может понадобиться отдельное правило переноса. Именно поэтому оно не заменяет все остальные меры против переполнения.

Ключевое слово и функция сетки

В Grid встречается похожая запись fit-content(20rem), которой можно ограничить дорожку. Это функция с заданным пределом, а не то же самое объявление, что inline-size: fit-content. Удобно сначала назвать объект настройки: дорожка родительской сетки или коробка ребёнка. Одинаковая часть имени ещё не делает два места использования взаимозаменяемыми.

Для самостоятельного опыта временно задайте одной обычной текстовой коробке inline-size: max-content, а затем min-content. Используйте фразу с несколькими словами, а не неразрывную строку. Ожидается длинная строка в первом случае и более узкая, часто многострочная коробка во втором. После наблюдения удалите опыт: настоящие карточки по-прежнему получают ширину от сетки.

Правила ключевого слова и его связь с внутренними границами приведены в MDN о fit-content. В нашем приложении важен конкретный выбор компактной подписи; он не требует вручную вычислять длину каждой русской строки. Браузер учитывает текущий шрифт и допустимые разрывы в момент компоновки.

Минимум элемента и минимум дорожки

Значение 1fr делит доступное пространство между дорожками, но оно не означает безусловный запрет переполнения любым содержимым. Автоматический минимальный размер Grid- или Flex-элемента может удерживать его шире ожидаемой доли. Поэтому ранее у слота было min-inline-size: 0, а теперь мы явно разрешили сжатие коробки названия.

Нулевая нижняя граница не обрезает текст и не создаёт разрешённых переносов сама по себе. Она снимает одно ограничение коробки. overflow-wrap: anywhere отдельно даёт возможность разорвать длинную строку, когда иначе она выходит за доступное место. В обычных названиях переносы по пробелам остаются естественным первым вариантом; дополнительное правило помогает необычно длинному фрагменту.

Не подменяйте эту задачу overflow: hidden на всей карточке. Тогда источник большой ширины может остаться непонятным, а часть названия просто исчезнет из видимой области. Если продукт действительно требует сокращённую подпись, нужно объяснить этот выбор и сохранить доступ к полному тексту. Наш учебный каталог показывает полные названия, поэтому сначала решает размер и перенос, а не маскирует результат.

У дорожки и у элемента разные минимумы. Например, minmax(0, 1fr) задаёт нижнюю границу дорожки, а min-inline-size: 0 относится к выбранной коробке. В некоторых схемах нужны оба решения, в других достаточно одного. Не добавляйте их механически в каждый селектор: найдите, какой уровень удерживает лишнюю ширину, и уточните обязанность именно там.

Ограничение поля без фиксированного окна

Форма теперь получает максимум 34rem, а текстовое поле — ширину min(100%, 28rem). На просторной странице поле не разрастается до всей ширины общего shell. На узкой странице процентная часть ограничивает его доступным местом. Это пример сочетания содержимого и контейнера: человеку нужна разумная длина поля, но окно не обязано соответствовать заранее выбранному числу пикселей.

Здесь значение поля не определяет его ширину автоматически. input имеет собственную модель отображения и начальные размеры; мы задаём геометрию интерфейса явным CSS. Если пользователь введёт длинное вымышленное имя, браузер может прокручивать текст внутри поля, а сама страница не должна из-за него расширяться. Атрибут maxlength ограничивает ввод символов по учебному контракту и не является средством подбора ширины.

Кнопка остаётся содержимым формы с обычным размером по надписи и отступам. Делать её равной ширине поля сейчас не требуется. Если такая задача появится, она будет отдельным решением макета формы, а не следствием темы внутренних размеров. Мы не меняем отправку GET на соседнюю страницу и не начинаем хранить введённые данные.

Вариант с длинным названием

Для диагностического опыта временно добавьте в название первого курса длинную строку без пробелов. Предскажите сначала поведение без overflow-wrap, затем с текущим правилом. Ожидается возможность переноса длинного фрагмента, а не появление горизонтального окна для всей страницы. После опыта верните исходный текст. Число карточек и адрес первого оглавления должны остаться прежними в обоих состояниях.

Сравнивайте видимую ширину с computed-значениями конкретного элемента. Сам факт, что фон выглядит компактным, не доказывает правильно выбранную минимальную границу родителя. Полезно рассматривать подпись количества, заголовок и слот раздельно: они подчиняются разным правилам и решают разные задачи. Учебный пример намеренно небольшой, чтобы это различие не скрывалось среди десятков обёрток.

Внутренний размер также зависит от масштаба и доступного шрифта. Не записывайте ожидаемую ширину русской подписи как полученный замер, если страницу не открывали в конкретном окружении. Мы задаём проверяемое поведение относительно текста и контейнера. Следующий урок добавит числовые нижнюю и верхнюю границы для величин, которые должны плавно расти между ними.

Полное состояние этого шага находится в layout-lab/lesson-20 внутри исходников продолжения. Каждый снимок открывается отдельно; подключать CSS разных уроков одновременно не нужно.

Оглавление курса.