Тег <picture> в сочетании с <source>

Тег <picture> в сочетании с <source> — это мощный инструмент для адаптивной загрузки изображений

Редактировать...

Отличный выбор! Тег `<picture>` в сочетании с `<source>` — это мощный инструмент для адаптивной загрузки изображений. Давайте разберем его подробно.


### Основная идея

Тег `<picture>` сам по себе не отображает изображение. Он служит **контейнером** для одного или нескольких элементов `<source>` и одного обязательного `<img>`. Браузер выбирает первый подходящий `<source>`, а если ни один не подошел — загружает изображение из `<img>` (это fallback).

### Синтаксис и структура


```html

<picture>

<!-- Источники проверяются сверху вниз. Первый подходящий — будет использован -->

<source

media="(min-width: 1200px)"

srcset="large.jpg"

type="image/jpeg"

>

<source

media="(min-width: 768px)"

srcset="medium.jpg"

type="image/jpeg"

>

<!-- Элемент <img> — ОБЯЗАТЕЛЕН. Он работает как fallback и задает размеры -->

<img

src="small.jpg"

alt="Описание изображения"

width="800"

height="600"

>

</picture>

```


### Ключевые атрибуты для `<source>`


1. **`srcset`** (обязательный для `<source>`):

* Указывает путь к файлу изображения.

* Может содержать несколько файлов с дескрипторами плотности пикселей (`1x`, `2x`) или ширины (`w`).

* **Пример с плотностью:** `srcset="image-1x.jpg 1x, image-2x.jpg 2x"` (браузер выберет подходящий для экрана).

* **Пример с шириной:** `srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"`. Часто используется с атрибутом `sizes`.


2. **`media`** (опционально):

* Принимает медиа-выражение (как в CSS).

* Браузер использует этот `<source>`, только если условие `media` истинно.

* **Пример:** `media="(min-width: 768px) and (orientation: landscape)"`


3. **`type`** (опционально):

* Указывает MIME-тип изображения (например, `image/webp`, `image/avif`).

* Браузер использует этот источник, **только если он поддерживает данный формат**. Идеально для современных форматов.

* **Пример:** `type="image/avif"`


4. **`sizes`** (опционально, работает в паре с `srcset`, использующим дескриптор `w`):

* Описывает, какую ширину изображения (в визуальных пикселях) нужно на разных макетах.

* **Пример:** `sizes="(max-width: 600px) 100vw, 50vw"` — на экранах до 600px изображение занимает 100% ширины окна, на больших — 50%.


### Основные сценарии использования


#### 1. Адаптивность под разные размеры экрана (Art Direction)

Меняем не только размер, но и композицию кадра для разных устройств.


```html

<picture>

<source media="(min-width: 992px)" srcset="desktop-wide-crop.jpg">

<source media="(min-width: 576px)" srcset="tablet-square-crop.jpg">

<!-- Fallback для мобильных и старых браузеров -->

<img src="mobile-vertical-crop.jpg" alt="Пример арт-дирекшна">

</picture>

```


#### 2. Поддержка современных форматов изображений

Загрузка более эффективных форматов (AVIF, WebP) с fallback на JPEG/PNG.


```html

<picture>

<!-- Самый современный формат — проверяется первым -->

<source srcset="image.avif" type="image/avif">

<source srcset="image.webp" type="image/webp">

<!-- Формат для всех остальных браузеров -->

<img src="image.jpg" alt="Современный формат с фолбэком">

</picture>

```


#### 3. Адаптивность под плотность пикселей (Retina-экраны)

```html

<picture>

<!-- Для широких экранов — большие изображения даже для ретины -->

<source

media="(min-width: 1200px)"

srcset="hero-large.jpg 1x, hero-large@2x.jpg 2x"

>

<!-- Для мобильных — меньше -->

<img

src="hero-small.jpg"

srcset="hero-small@2x.jpg 2x"

alt="Пример для ретины"

>

</picture>

```


#### 4. Комбинированный пример (Формат + Размеры)

```html

<picture>

<!-- Большой экран, формат AVIF -->

<source

media="(min-width: 1200px)"

srcset="large.avif 1200w, large@2x.avif 2400w"

sizes="80vw"

type="image/avif"

>

<!-- Мобильный, формат WebP -->

<source

srcset="small.webp 400w, medium.webp 800w"

sizes="100vw"

type="image/webp"

>

<!-- Универсальный fallback -->

<img

src="small.jpg"

srcset="small.jpg 400w, medium.jpg 800w"

sizes="100vw"

alt="Комплексный пример"

loading="lazy"

>

</picture>

```


### Важные моменты и лучшие практики


1. **Порядок имеет значение:** Браузер проверяет `<source>` сверху вниз и использует первый подходящий. Ставьте более специфичные условия выше.

2. **Обязательный `<img>`:** Всегда включайте тег `<img>` последним внутри `<picture>`. Он:

* обеспечивает совместимость со старыми браузероми,

* задает фактические размеры изображения,

* содержит обязательный атрибут `alt`.

3. **Атрибуты `width` и `height`:** Всегда указывайте их для `<img>` внутри `<picture>`, чтобы предотвратить смещение макета (Cumulative Layout Shift - CLS). Можно использовать `style="aspect-ratio: 16 / 9"` как альтернативу.

4. **Ленивая загрузка:** Добавляйте `loading="lazy"` к тегу `<img>` для повышения производительности.

5. **Не злоупотребляйте:** Используйте `<picture>` для важных, адаптивных изображений (герои, баннеры, товары). Для декоративных иконок или фонов достаточно `background-image` в CSS или простого `<img>`.


### Преимущества перед `<img>` с `srcset`/`sizes`

* **Контроль формата:** Главное преимущество — возможность использовать `type` для загрузки современных форматов.

* **Art Direction:** Полный контроль над кадрированием для разных размеров экрана.

* **Более четкая логика:** Условия (`media`) проверяются строго по порядку, что иногда понятнее, чем сложные `sizes`.


**Итог:** `<picture>` — это ваш лучший инструмент для **качественной**, **адаптивной** и **производительной** загрузки изображений в современной веб-разработке.