Работа с изображениями в HTML через CSS: размеры, пропорции, object-fit

Работа с изображениями в HTML через CSS: размеры, пропорции, object-fit Полезное

Стилизация изображений через CSS — это управление тем, как картинка из тега <img> или из фона элемента занимает место на странице: какой у нее размер, сохраняются ли пропорции, какая часть видна при обрезке и как она выглядит (скругление, фильтры). HTML отвечает за то, какая картинка загружается и что она означает, CSS — за то, как она показана.

Ниже — один рабочий пример, затем разбор: размеры и пропорции, object-fit, фоновые изображения, фильтры и типовые поломки.

Три понятия, которые путают

Прежде чем менять размеры, полезно развести три вещи:

  • Естественный размер — реальные пиксели файла (например, 1600×900).
  • Атрибуты width и height в HTML — подсказка браузеру о размере и пропорциях до загрузки файла.
  • CSS-размер — то, какой прямоугольник картинка займет в макете. Любое CSS-правило для width/height перекрывает атрибуты.

Отдельно от этого — содержимое внутри прямоугольника: как файл вписан в рамку. За это отвечают object-fit и object-position.

Минимальный рабочий пример

Сохраните код в файл index.html и откройте в браузере. Нужна любая картинка photo.jpg в той же папке.

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Картинки и CSS</title>
  <style>
    img {
      display: block;       /* убирает зазор под картинкой */
      max-width: 100%;      /* не шире контейнера */
      height: auto;         /* высота по пропорциям */
    }
    .card {
      width: 300px;
      border: 1px solid #ccc;
    }
    .card img {
      width: 100%;
      aspect-ratio: 4 / 3;  /* рамка 4:3 независимо от файла */
      object-fit: cover;    /* заполнить рамку, лишнее обрезать */
      object-position: center top;
    }
    .avatar {
      width: 96px;
      aspect-ratio: 1;
      object-fit: cover;
      border-radius: 50%;
    }
  </style>
</head>
<body>
  <img src="photo.jpg" alt="Исходное фото" width="1600" height="900">

  <div class="card">
    <img src="photo.jpg" alt="Фото в карточке" width="1600" height="900">
  </div>

  <img class="avatar" src="photo.jpg" alt="Аватар" width="1600" height="900">
</body>
</html>

Что увидите: первая картинка займет ширину окна, но не больше своих 1600 px, и сохранит пропорции 16:9. Во второй карточке шириной 300 px фото станет рамкой 4:3 — края по бокам обрежутся, верх кадра останется виден. Третья картинка — круглый аватар 96×96 без сплющивания.

Размеры и пропорции

Атрибуты width и height

В HTML атрибуты width и height у <img> задаются целым числом без единиц — это пиксели. Проценты в атрибуте по стандарту HTML не допускаются, хотя старые страницы так пишут и браузеры это терпят. Процентные и любые гибкие размеры задают в CSS.

Зачем тогда атрибуты, если размер все равно задан в CSS? Современные браузеры вычисляют по ним соотношение сторон еще до загрузки файла и резервируют место. Без них текст «прыгает», когда картинка догружается — это ухудшает метрику CLS (Cumulative Layout Shift). Поэтому практичная связка такая: реальные размеры файла в атрибутах, гибкость — в CSS.

max-width: 100% и height: auto

Правило max-width: 100%; height: auto — базовая адаптивность:

  • max-width: 100% уменьшает картинку до ширины контейнера, но не растягивает ее больше естественного размера, поэтому она не размывается;
  • height: auto пересчитывает высоту по пропорциям.

Для сравнения, width: 100% растянет файл 400 px на колонку 1200 px, и он станет мыльным.

auto — это значение CSS-свойства, а не HTML-атрибута. Запись height="auto" в теге невалидна.

Единицы в CSS

Единица Что это Когда уместна
px CSS-пиксель, 1/96 дюйма фиксированные иконки, аватары
% доля от размера контейнера ширина в колонке
vw / vh 1% ширины / высоты окна баннеры на весь экран
rem относительно размера шрифта корня размеры, согласованные с текстом
pt, in, cm 1/72 дюйма, 96 px, 96/2,54 px в основном для печати

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

Свойство aspect-ratio

aspect-ratio задает пропорции рамки: aspect-ratio: 16 / 9 или aspect-ratio: 1 для квадрата. Если указана только ширина, высота вычислится сама. Это удобно для сеток карточек с фото разного формата.

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

Когда у <img> заданы и ширина, и высота (явно или через aspect-ratio), а пропорции файла другие, браузер должен решить, что делать. По умолчанию он растягивает картинку, и она искажается.

Значение Пропорции Заполняет рамку Обрезка Когда брать
fill (по умолчанию) не сохраняет да нет почти никогда для фото
contain сохраняет нет, остаются поля нет логотипы, схемы, товар целиком
cover сохраняет да да превью, аватары, обложки
none естественный размер как получится да, если файл больше редкие случаи, кропы 1:1
scale-down сохраняет нет нет меньшее из none и contain

Правило выбора: если важно, чтобы в кадр целиком попал объект (логотип, схема), берите contain. Если важно, чтобы рамка была заполнена без полей, берите cover и настройте object-position.

object-position работает как background-position: по умолчанию 50% 50%, то есть кадр центрируется. Значение center top сохраняет верх снимка — полезно для портретов, где иначе может обрезаться голова.

Ошибка: картинку сплющило

Неверно — заданы оба размера, пропорции файла 16:9:

.thumb {
  width: 300px;
  height: 300px;
}

Результат: фото 16:9 растянуто в квадрат, лица вытянуты по вертикали. Работает значение по умолчанию object-fit: fill.

Исправление:

.thumb {
  width: 300px;
  height: 300px;
  object-fit: cover;
}

Теперь квадрат заполнен без искажения, левый и правый края кадра обрезаны.

Фоновое изображение

Картинку можно показать через background-image на любом элементе. Это уместно для декора: фон секции, текстура, баннер с текстом поверх.

.hero {
  min-height: 60vh;
  background-image: url("hero.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

Результат: блок высотой 60% окна полностью закрыт фото, края обрезаются по размеру блока.

background-size принимает auto (естественный размер), длины, проценты (от области фона самого элемента, а не от картинки), а также contain и cover — смысл у них тот же, что у object-fit. По умолчанию фон повторяется плиткой, поэтому no-repeat почти всегда нужен.

Граница применимости: у фона нет атрибута alt, скринридеры его не озвучивают, поисковики обычно не считают его содержимым страницы. Если картинка несет смысл (фото товара, схема, фото автора), нужен <img> с осмысленным alt, а для декоративного <img> — пустой alt="".

Скругления, тени и фильтры

Оформление картинки тоже задается CSS, файл менять не нужно:

.photo {
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  filter: grayscale(100%);
  transition: filter 0.3s;
}
.photo:hover {
  filter: grayscale(0%);
}

Результат: фото со скругленными углами и тенью показано черно-белым, при наведении плавно становится цветным. Другие функции filter: blur(4px), brightness(0.8), contrast(1.2), sepia(60%); их можно перечислять через пробел.

Фильтр пересчитывается браузером при отрисовке, поэтому на больших изображениях и в анимациях blur() может заметно нагружать слабые устройства. Для постоянного эффекта надежнее обработать сам файл.

Адаптивность: что делает CSS, а что HTML

CSS меняет размер показа, но не выбирает файл. Телефону с экраном 390 px CSS покажет уменьшенную копию, но скачает все тот же файл на 1600 px. Выбор файла под экран — задача HTML:

  • атрибуты srcset и sizes у <img> — браузер берет подходящий по ширине файл;
  • элемент <picture> с <source> — другой кадр или формат (AVIF, WebP) под условия;
  • атрибут loading="lazy" — отложенная загрузка картинок ниже первого экрана.

Для фоновых картинок аналог srcset в CSS — функция image-set(), а под разные экраны можно менять background-image в медиазапросах.

Если не получилось

Симптом Причина Что делать
Под картинкой узкая полоса <img> строчный элемент и стоит на базовой линии текста display: block или vertical-align: middle
Картинка вылезает за колонку не задано ограничение ширины max-width: 100%; height: auto
Фото растянуто или сплющено заданы оба размера, object-fit: fill object-fit: cover или contain
object-fit ничего не меняет у картинки не ограничена высота или ширина рамки задайте оба размера или aspect-ratio
Фон не виден у блока нулевая высота, фон содержимым не считается задайте min-height или aspect-ratio блоку
Картинка мыльная CSS-размер больше естественного max-width вместо width, крупнее файл через srcset
Правило из CSS не применяется более специфичный селектор или инлайн-стиль посмотрите вычисленные стили в DevTools

Выводы

  • Размер файла, атрибуты width/height и CSS-размер — разные вещи: атрибуты резервируют место, CSS задает итоговый размер.
  • Базовая адаптивность картинки — max-width: 100%; height: auto; width: 100% растягивает мелкие файлы.
  • Чтобы вписать фото в рамку другой формы без искажений, нужен object-fit: cover заполняет с обрезкой, contain показывает целиком.
  • Фоновое изображение подходит для декора; смысловая картинка — только <img> с alt.
  • CSS управляет показом, выбор файла под экран делают srcset, sizes и <picture> в HTML.

Где применяется / связь с практикой

Эти приемы нужны в карточках товаров и статей, галереях, аватарах и баннерах, а на практике стыкуются с Flexbox, Grid и медиазапросами.

Освойте тему на практике

Если хотите системно освоить верстку от разметки до адаптивных макетов, посмотрите курс HTML/CSS. Попробовать формат и разобрать отдельные темы можно на открытых уроках Otus.

FAQ

Можно ли задать размер картинки только в HTML, без CSS?
Да, атрибутами width и height в пикселях, но такой размер не адаптивен. Для гибкой верстки размеры задают в CSS, а атрибуты оставляют для резервирования места.

Чем object-fit отличается от background-size?
Значения у них похожи, но object-fit работает с содержимым <img> и <video>, а background-size — с фоном любого элемента.

Как сделать картинку черно-белой без редактора?
Свойством filter: grayscale(100%). Файл не меняется, эффект применяется только при отрисовке в браузере.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)