$ sudo teach IT

Картинки — частый источник проблем в адаптиве: то растягиваются и искажаются, то вылезают за контейнер, то оставляют «прыгающий» макет, пока грузятся. А ещё хочется, чтобы сетка карточек сама подбирала число колонок под ширину — без ручных медиазапросов на каждый порог. Всё это решают несколько современных инструментов: object-fit вписывает картинку без искажений, aspect-ratio держит пропорции, а auto-fit/auto-fill вместе с minmax() создают сетку, которая сама меняет количество колонок. Это красивый финал курса — самая «магическая» часть адаптива.

После этого урока вы сможете аккуратно вписывать изображения любой формы и строить сетки, которые адаптируются полностью сами, без единого breakpoint.

Что уже умеем / что добавим

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

Что вы узнаете в рамках статьи

  • Как вписывать изображение в блок через object-fit.
  • Как задавать и удерживать пропорции через aspect-ratio.
  • Как строить авто-сетку с auto-fit/auto-fill и minmax().
  • Чем отличаются auto-fit и auto-fill.

Ключевые термины

  • object-fit — как изображение вписывается в свой блок (cover, contain).
  • aspect-ratio — заданное соотношение сторон элемента.
  • auto-fit — авто-число колонок, растягивающее их под ширину.
  • auto-fill — авто-число колонок с сохранением пустых мест.
  • minmax() — диапазон ширины колонки (из раздела о Grid).

Вписываем картинку: object-fit

Проблема обычной картинки: если задать ей ширину и высоту, не совпадающие с её пропорциями, она исказится — лица «расплющатся», круги станут овалами. Свойство object-fit решает это, управляя тем, как изображение заполняет отведённый блок:

.card__img {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

Значение cover масштабирует картинку так, чтобы она полностью закрыла блок, сохранив пропорции, — лишнее аккуратно обрежется по краям. Изображение больше не искажается: оно заполняет область 100%×200px как фон, но остаётся тегом img. Альтернатива — contain: картинка целиком помещается внутрь блока, сохраняя пропорции, но могут остаться пустые поля. Для карточек и обложек обычно нужен cover, для логотипов и иконок — contain.

Держим пропорции: aspect-ratio

Часто нужно, чтобы блок сохранял заданное соотношение сторон при любой ширине — например, все превью были 16:9. Раньше для этого шли на хитрости, а теперь есть прямое свойство aspect-ratio:

.card__img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

Мы задали только ширину (100%), а высота вычислится сама из соотношения 16 / 9. При любой ширине карточки картинка сохранит пропорцию 16:9, а object-fit: cover впишет содержимое без искажений. Большой бонус: браузер заранее знает высоту блока и резервирует место, поэтому макет не «прыгает» при загрузке картинки. aspect-ratio работает не только с картинками — им удобно задавать пропорции любым блокам, например квадратным плиткам (aspect-ratio: 1).

Авто-сетка: auto-fit и minmax()

Теперь — обещанная «магия». Помните repeat() и minmax() из раздела о Grid? Если вместо числа повторов в repeat() поставить ключевое слово auto-fit, сетка сама подберёт количество колонок под доступную ширину:

.services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}

Читается так: «делай столько колонок шириной от 220px до 1fr, сколько влезет». На широком экране поместится, скажем, четыре колонки, на планшете — две, на телефоне — одна. И всё это без единого медиазапроса: сетка пересчитывает число колонок сама, непрерывно. Колонки при этом растягиваются на всю ширину благодаря 1fr. Это самый компактный способ сделать адаптивную галерею — одна строка вместо нескольких контрольных точек.

auto-fit против auto-fill

У auto-fit есть близнец — auto-fill, и разница между ними тонкая, но важная. Оба создают столько колонок, сколько влезает. Отличие в том, как они ведут себя, когда элементов меньше, чем помещается колонок.

auto-fit «схлопывает» лишние пустые колонки, и существующие элементы растягиваются, заполняя всю ширину. auto-fill сохраняет пустые колонки как невидимые места — элементы не растягиваются сверх своей minmax, а справа остаётся свободное пространство под будущие элементы.

/* Элементы растянутся на всю ширину */
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));

/* Останутся пустые «слоты» справа */
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));

На практике auto-fit выбирают, когда хотят, чтобы имеющиеся карточки заняли всю ширину (это чаще всего), а auto-fill — когда важно сохранить сетку «как есть», с местами под добавление. Для большинства галерей подходит auto-fit.

Применяем в проекте

Финальный штрих: приведём в порядок картинки в карточках услуг и сделаем их сетку полностью самонастраивающейся. Картинки получат единые пропорции и object-fit, а сетка — auto-fit, чтобы сама подбирать число колонок.

.services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}

.card__img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
}

Медленно меняйте ширину окна: карточки услуг сами перестраиваются — от одной колонки на телефоне до нескольких на десктопе, плавно и без ступеней, а картинки в них аккуратно вписаны, держат пропорцию 16:9 и не искажаются. Мы добились полной адаптивности галереи одной строкой сетки и парой свойств для изображений — без единого медиазапроса. Проект получил профессиональный, отзывчивый вид.

Частые ошибки

  • Картинка без object-fit.
    Заданные ширина и высота без object-fit искажают изображение; добавьте cover или contain.
  • auto-fit без minmax().
    repeat(auto-fit, 1fr) не сработает как надо; авто-число колонок требует диапазона minmax().
  • Путаница auto-fit и auto-fill.
    auto-fit растягивает элементы на всю ширину, auto-fill оставляет пустые слоты; выбирайте по нужному поведению.
  • Забыть про пропорции.
    Без aspect-ratio или высоты блок картинки может «прыгать» при загрузке; фиксируйте размеры заранее.

Итоги

Поздравляем — вы завершили третий курс и освоили адаптивную вёрстку целиком! Вы научились вписывать изображения через object-fit, удерживать пропорции с aspect-ratio и строить авто-сетки на auto-fit/auto-fill с minmax(), которые сами подбирают число колонок. За этот курс вы прошли огромный путь: двумерные макеты на CSS Grid, позиционирование и слои, а теперь — полноценная адаптивность от мета-тега viewport до текучих размеров и самонастраивающихся сеток. Ваш сайт компании безупречно выглядит и на телефоне, и на десктопе.

Вы выросли из верстальщика статичных страниц в мастера отзывчивых, современных макетов — по-настоящему гордитесь этим! Впереди четвёртый курс, где вас ждёт самое зрелищное: современные возможности CSS, переходы, трансформации и анимации, которые оживят ваши интерфейсы. Но это следующая ступень — а сегодня отметьте своё достижение. Вы его заслужили!

На следующий урок