Если вы занимаетесь веб-разработкой, то высока вероятность того, что вам знакомы два чудовища, о которых пойдёт речь в статье, перевод которой мы сегодня публикуем. Речь идёт об изображениях и о дедлайнах. Иногда, по каким-то причинам, картинки никак не хотят помещаться в те места макетов страниц, которые для них предназначены, а вы не можете потратить несколько часов на то, чтобы с этим разобраться.



Автор этого материала говорит, что он часто сталкивался с подобной проблемой, и эти столкновения кое-чему его научили. Здесь он хочет рассказать о пяти подходах к управлению размерами изображений, которые нравятся ему больше всего.

Подход №1: background-image


Пятница. Пять часов вечера. Вам надо срочно доделать некую страницу. Всё готово, проблема лишь в картинках, которые никак не помещаются туда, где им положено быть. Если это случилось с вами — вот одно волшебное средство, которое вас выручит:

.myImg {
  background-image: url("my-image.png");
  background-size: cover;
}

Выглядит знакомо? Мы все это делали когда-то. Не наводил ли вас это на мысли о мошенничестве?

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

Подход №2: object-fit


Что если я скажу, что свойство object-fit применимо к элементам <img>? Оно, кстати, работает и с видео.

.myImg {
  object-fit: cover;
  width: 320px;
  height: 180px;
}

Вот и всё. Обратите внимание на то, что свойству object-fit можно назначить значение contain.

?О поддержке object-fit


К несчастью, object-fit не будет работать в IE и в старых версиях Safari, однако, для таких случаев имеется полифилл.

Вот сведения о поддержке этой возможности, взятые отсюда.


Поддержка object-fit настольными браузерами

> Вот пример использования object-fit

Подход №3: способ, которым пользуется Netflix


То, о чём мы только что говорили, может показаться интересным, но в устаревших браузерах, без полифиллов, работать это не будет. Если вам нужно что-то универсальное, возможно, то, о чём мы будем говорить сейчас, вам подойдёт. Этот метод, один из моих любимых, работает везде.

Заключается он в том, что изображение нужно поместить в родительский элемент, свойство position которого установлено в значение relative, а свойство padding задано в процентном выражении. В результате изображение займёт всю свободную область родительского элемента. Выглядит это так:

.wrapper {
  position: relative;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}
img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: auto;
}

Тут вы можете подумать о том, что это слишком сложно. Однако, после того как вы поймёте смысл этого приёма, вы осознаете, что он очень прост и удобен. К тому же, этот приём широко используется, например, в Netflix.


Взгляните на имена классов

> Вот пример реализации этого приёма

Подход №4: height


Тут для управления размерами изображения используется свойство height: auto, и, кроме того, свойство max-width. Вполне возможно, что вам этот приём уже знаком:

img {
  height: auto;
  width: 100%;
/* свойство max-width, позволит лучше контролировать изображение */
  max-width: 720px;
}

Такой подход применим в большинстве случаев, тогда, когда ваш макет не слишком сложен.

> Вот пример

Подход №5: управление изображениями и производительность


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

Знаете ли вы о том, что в современных браузерах можно менять источник изображения в зависимости от ширины страницы? Именно для этого существует атрибут srcset.

Подобные атрибуты можно использовать в теге HTML 5 . В том случае, если браузер эту технологию не поддерживает, здесь предусмотрен запасной вариант с использованием тега <img>:

<picture>
  <source media="(max-width: 799px)" srcset="elva-480w.jpg">
  <source media="(min-width: 800px)" srcset="elva-800w.jpg">
  <img align="center" src="elva-800w.jpg">
</picture>

>
Вот пример

Итоги


Подведём итоги:

  • Если ваше изображение не является частью содержимого страницы — используйте background-image.
  • Если поддержка IE вас не интересует — воспользуйтесь object-fit.
  • Техника с применением контейнера со специально настроенным свойством padding, используемая Netflix, работает везде.
  • В большинстве случаев для решения проблемы с картинками достаточно использовать в CSS свойство height: auto;
  • Если вы стремитесь сократить время загрузки страниц, используйте атрибут srcset для загрузки изображений меньших размеров на мобильных устройствах.

Надеемся, рассмотренные здесь подходы к работе с изображениями вам пригодятся.

Комментарии (5)


  1. vin2809
    24.08.2018 15:06

    Мне кажется, что images and deadlines
    стоит переводить как изображения и сроки, а не дедлайны…


  1. savostin
    24.08.2018 15:11

    Такой подход применим в большинстве случаев, тогда, когда ваш макет не слишком сложен.

    Насколько должен быть сложным макет, чтобы этот (как по мне самый простой вариант) не подошел?


    1. wheercool
      26.08.2018 01:25

      №4 вариант не позволяет задать жесткий размер картинки, например в карточках товара.


  1. PaulZi
    24.08.2018 18:46
    +1

    Третий и четвёртый способ не равен `background-size: cover`, при длинной картинке они покажут поля:
    codepen.io/anon/pen/JaYgKg
    codepen.io/anon/pen/qMOeqW


    1. iZamza
      26.08.2018 07:20

      3-й способ очень полезен для, например, добавления видео из youtube… Т.е. вещей в которых соотношение сторон не меняется, и не хочется что бы вылазили полоски. Высчитывается делением высоты на ширину х 100%. Т.е. 9:16х100 = 56,25% и т.д.
      Встречал раньше немного другую интерпретацию данного приема.
      Там использовались 3 дива( родитель, див с паддингом и 0 высотой, и непосредственно контент в абсолюте)

      .parent{
      position:relative;
      .ratio{padding-top: 56,6%; 
      height: 0px;}
      .content{
      position: absolute;
      top:0;
      left:0;
      width: 100%;
      height: 100%;
      }
      }