Размеры элементов и блочная модель
Настроим блочную модель карточки и сделаем размеры изображений зависимыми от доступной ширины.
К этому шагу у карточек появился фон и рамка, но текст расположен слишком близко к краю, а широкая обложка может растянуть страницу. Добавим внутренние поля и единый способ расчёта размеров. Задача урока — понимать, какую часть коробки описывает размер, а не подобрать случайную ширину, при которой текущие шесть названий выглядят аккуратно.
В CSS элемент имеет содержимое, внутренние поля, рамку и внешние отступы. Эти области выполняют разные функции. Внутреннее поле отделяет текст от рамки карточки, внешнее — карточку от соседней коробки. Пока список остаётся вертикальным, но те же расчёты позднее будут использоваться внутри Grid. Поэтому правила размера стоит подготовить до перехода к колонкам.
Что входит в заданную ширину
Представим отдельную коробку с шириной триста пикселей, полями по двадцать и рамками по одному. При обычном content-box заданная ширина относится к содержимому. Полный размер по горизонтали станет триста сорок два пикселя без внешних отступов. Если контейнер рассчитан на триста, коробка выйдет за его границы. Это результат арифметики выбранной модели, а не ошибка значения padding.
При border-box заданный размер включает поля и рамку. В том же примере наружная ширина будет триста, а доступная ширина содержимого уменьшится до двухсот пятидесяти восьми. Внешний отступ по-прежнему не входит в этот размер. Слои коробки описаны в MDN. Такой расчёт помогает предсказывать результат до подбора нескольких взаимоисключающих правил.
В наш файл добавьте следующие объявления. Они продолжают предыдущие стили, а не заменяют HTML:
.layout-lab,
.layout-lab *,
.layout-lab *::before,
.layout-lab *::after {
box-sizing: border-box;
}
.layout-lab {
margin: 0;
}
.layout-lab .course-card {
padding: 1.25rem;
border: 1px solid #3b3c4c;
border-radius: .5rem;
}
.layout-lab .course-card--featured {
border-color: #6c43af;
}
.layout-lab .course-cover {
display: block;
max-inline-size: 100%;
block-size: auto;
}
Ожидается, что содержимое отступит от границ карточки, а картинка перестанет превышать доступную ширину. Радиус закругляет рамку, но не меняет расчёт места для текста. У страницы убран внешний отступ браузера. Это не означает, что текст навсегда должен касаться окна: собственную оболочку и поля страницы введём в следующем уроке.
Поля и единицы размера
1.25rem зависит от размера шрифта корневого элемента. Если он равен шестнадцати пикселям, поле составит двадцать; при другом исходном размере значение изменится. Мы не фиксируем размер корня ради получения привычной цифры. Такая единица позволяет расстояниям следовать за настройкой текста. Рамка в один пиксель остаётся отдельным визуальным решением, а не универсальным масштабом для всего интерфейса.
На этом шаге не задаём карточке жёсткую высоту. Названия и описания могут занимать разное число строк. При изменении ширины или размера шрифта содержимое должно увеличивать коробку по высоте. Если установить произвольные двести пикселей, можно скрыть проблему на одном тексте и получить переполнение на другом. Размер лучше вводить по задаче, а не по фотографии текущей страницы.
padding расположен внутри фона и рамки. Поэтому цвет карточки продолжается на его площадь. margin, напротив, отделяет коробки снаружи и не окрашивается фоном самого элемента. Для наглядного опыта временно добавьте внешнее поле карточке и сравните область вокруг рамки. Верните его после наблюдения: интервалы между элементами списка в следующем уроке будут заданы системно.
Изображение и доступное место
max-inline-size: 100% ограничивает картинку шириной содержащего её блока. Логическое направление inline в нашем русскоязычном горизонтальном документе соответствует горизонтали. Свойство не заставляет маленький ресурс всегда растягиваться до полной ширины. Оно говорит, что превышать доступное место нельзя. Собственная ширина нашего SVG велика, поэтому в узкой карточке он ожидаемо уменьшится.
block-size: auto сохраняет естественное отношение сторон при ограничении ширины. Атрибуты HTML с шестьюстами сорока и тремястами шестьюдесятью остаются полезными сведениями. Не удаляйте их только потому, что CSS задаёт другое отображение. У карточки есть внутренняя площадь после вычитания полей и рамки, и именно в ней располагается обложка.
display: block убирает поведение изображения как части обычной строки. Это помогает избежать небольшого пространства, связанного с выравниванием по текстовой линии. Мы не используем отрицательное поле для скрытия этого промежутка: сначала выбираем нужный тип отображения. У других inline-элементов такое изменение не следует применять автоматически, поскольку оно влияет на поток текста.
Диагностика переполнения
Если горизонтальная прокрутка остаётся, проверьте не только картинку. Длинная последовательность без пробелов или ширина другой коробки тоже могут расширить страницу. Уберите временно обложку: исчезновение проблемы укажет на область поиска, но ещё не докажет конкретное свойство. Затем посмотрите вычисленный размер и ограничения изображения в инструментах разработчика.
Для простого опыта задайте карточке inline-size: 20rem и большое внутреннее поле. Сравните content-box и border-box, переключая только одно значение. Ожидаемая разница касается наружной ширины и доступного места внутри. Не меняйте сразу поле, рамку и размер: иначе результат трудно связать с моделью. После опыта удалите заданную ширину, чтобы основной каталог снова занимал естественное доступное место.
Внешние отступы имеют дополнительные правила взаимодействия, включая схлопывание в некоторых условиях обычного потока. border-box не отключает этот механизм. Он меняет расчёт размеров, а не любые расстояния между элементами. В следующем уроке отделим интервалы внутри карточек от промежутков списка и зададим оболочку страницы без абсолютного позиционирования.
Закругление рамки само по себе не означает, что любой дочерний элемент будет обрезан по её форме. Если изображение прилегает к краю без поля, оно может потребовать собственного радиуса или осознанного ограничения переполнения. У нас обложка отделена внутренним полем, поэтому такой задачи пока нет. Не добавляйте overflow: hidden ко всем карточкам автоматически: оно способно скрыть не только край картинки, но и нежелательное переполнение текста, которое лучше исправить по причине.
Свойство переполнения и блочная модель связаны, но не взаимозаменяемы. Обрезанная часть всё ещё может существовать в документе. Аккуратный край не доказывает, что содержание разместилось правильно.
Максимальный размер отличается от обязательного размера. Если вместо max-inline-size задать inline-size: 100%, обложка будет стремиться занять всю ширину даже там, где её собственный размер меньше. У нашего крупного SVG оба варианта часто выглядят одинаково, но это не делает свойства взаимозаменяемыми. Для другого ресурса различие станет заметным. Прежде чем копировать правило в новый компонент, нужно понять, ограничивает оно коробку или принудительно задаёт ей выбранный размер.
Теперь коробки имеют предсказуемые поля и рамки, а обложки следуют за шириной. Этот результат пригодится и в одной колонке, и в будущей сетке. Основной принцип остаётся тем же: сначала определить, какое пространство доступно содержимому, затем выбирать способ размещения нескольких элементов в нём.