Делайте из слона муху

Вадим Макеев, HTML Academy

Делайте
из слона
муху

Слон с крыльями
Логотип HTML Academy
Веб-стандарты Лёша, Оля и Вадим записывают подкаст

youtube.com/pepelsbey

Вадим в видеоблоге

Ситуация

DUMP

На главной

Как так вышло, DUMP?

Графика

Фрай

Форматы

SVG vs PNG

Векторные

Цвета Прозрачность Анимация
SVG Много Да Да



SVG — это программируемая графика, как Canvas.

Растровые

Цвета Прозрачность Анимация
GIF 256 Да Да
PNG 256 и больше Да, альфа Да *
JPEG Много Нет Нет
WebP 256 и больше Да, альфа Да
HEIC Много Да, альфа Да

Анимация

Гифка — это жанр,
а не формат графики.

Видео

            <video autoplay loop muted>
                <source type="video/webm" src="bolt.webm">
                <source type="video/mp4" src="bolt.mp4">
            </video>
        
            $ ffmpeg -i bolt.gif -movflags faststart -pix_fmt yuv420p -crf 0 bolt.mp4
        

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

            <picture>
                <source type="image/webp" srcset="bolt.webp">
                <img src="bolt.gif" alt="Болт кривляется">
            </picture>
        
            $ gif2webp bolt.gif -o bolt.webp
        
AV1

Новый кодек AV1, Андрей Ситник

GIF

Анимированные песочные часы Кадры анимации песочных часов

Создание

Редакторы

Photoshop Illustrator Affinity Sketch Figma CSS
Дедпул в образе Боба Росса

CSS-графика

            <div class="burger">
                <div class="burger__line burger__line--1"></div>
                <div class="burger__line burger__line--2"></div>
                <div class="burger__line burger__line--3"></div>
            </div>
        

CSS-графика

                .burger {
                    position: relative;
                    width: 12px;
                    height: 10px;
                }
            
                .burger__line {
                    position: absolute;
                    left: 0;
                    width: 12px;
                    height: 2px;
                    background-color: #4b86c2;
                }
            

CSS-графика

                .burger__line--1 {
                    top: 0;
                }
                .burger__line--2 {
                    top: 4px;
                }
            
                .burger__line--1 {
                    top: 8px;
                }
            

CSS-графика получше

                .burger {
                    width: 12px; height: 10px;
                    background-image: repeating-linear-gradient(
                        #4b86c2, #4b86c2 2px,
                        #fff 2px, #fff 4px
                    );
                }
            

Ручной SVG

            <svg width="120" viewBox="0 0 12 10" fill="#4b86c2">
                <rect width="12" height="2" x="0" y="0"/>
                <rect width="12" height="2" x="0" y="4"/>
                <rect width="12" height="2" x="0" y="8"/>
            </svg>
        

Canvas

Canvas

Скучающий Фрай

CSS Paint API

            div {
                --burger-color: #4b86c2;
                background-image: url('burger.png');
                background-image: paint(burger);
            }
        
            CSS.paintWorklet.addModule('burger.js');
        

CSS Paint API

            class Shape {
                static get inputProperties() {
                    return ['--burger-color'];
                }
                paint(context, geometry, properties) {  }
            }
            registerPaint('burger', Shape);
        

CSS Paint API

            const color = properties.get(
                '--burger-color'
            );
            context.fillStyle = color;
            context.fillRect(0, 0, 120, 20);
            context.fillRect(0, 40, 120, 20);
            context.fillRect(0, 80, 120, 20);
        

CSS Paint API

            div:hover {
                --burger-color: #32b332;
            }
        

CSS Paint API

Фрай размахивает пачкой денег

Экспорт

Иконка Photoshop
Photoshop: Save for web
Photoshop: Экспорт документа
Photoshop: Выбор слоя
Photoshop: Экспорт слоя
Photoshop: Экспорт группы
Иконка Illustrator
Illustrator: Сбор ассетов
Illustrator: Экспорт ассетов
Illustrator: Копирование кода
Avocode Zeplin
Sketch Figma
Sketch: Экспорт и настройки
Sketch: Плагин SVGO в настройках

Заглядывайте в SVG

<desc>Created using Figma</desc>
<path d="m269.246984 855.728762 78.364445-47.425016
    c15.118222 26.804825 28.871111 49.483175 61.858539
    49.483175 31.620064 0 51.555556-12.368864 51.5555
    56-60.481016v-327.192381h96.229587v328.553651c0
    99.669333-58.422857 145.03619-143.660698…"/>

Заглядывайте в SVG

<svg><image xlink:href="data:image/png;base64,iVBORw0KGgo
AAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAA7EAAAOxAGV
Kw4bAAAIXUlEQVR4nO3WMQEAIAzAsIF/z+ACjiYKenbNzBkAIGX/DgAA3
jMAABBkAAAgyAAAQJABAIAgAwAAQQYAAIIMAAAEGQAACDIAABBkAAAgyA
AAQJABAIAgAwAAQQYAAIIMAAAEGQAACDIAABBkAAAgyAAAQJABAIAgAwA
AQQYAAIIMAAAEGQAACDIAABBkAAAgyAAAQJABAIAgAwAAQQYAAIIMAAAE
GQAACDIAABBkAAAgyAAAQJABAIAgAwAAQQYAAIIMAAAEGQA…"/></svg>

Экспорт

PNG PNG 8 JPG SVG
Photoshop 852 155 3596 130
Affinity 1555 856 10793 602
Sketch 5639 3836 525
Figma 2179 7797 153
Руки 111 111 1144 98

Оптимизация

ImageOptim
TinyPNG
SVGOMG
Squoosh

Вставка

Хороший интерфейс
как прогресс-бар.

Тегом

            <img src="cat.jpg" alt="Рыжий кот">
        
            <figure>
                <img src="cat.jpg" alt="Рыжий кот">
                <figcaption>Мой кот самый лучший</figcaption>
            </figure>
        

Идеально для контентных картинок.

Тегом: плюшки

            <picture>
                <source type="image/webp"
                     srcset="cat@2x.webp 2x
                             cat.webp 1x">
                <img srcset="cat@2x.jpg 2x"
                        src="cat.jpg" alt="Рыжий кот">
            </picture>
        

Тегом: плюшки

            <img srcset="cat@3x.jpg 3x"
                 srcset="cat@2x.jpg 2x"
                    src="cat.jpg"
                 alt="Рыжий кот">
        

Для ретины достаточно атрибута srcset.

Фоном

            button {
                background-image: url(icon.png);
            }
        

Фоном: плюшки

            @media (min-resolution: 2dppx) {
                button {
                    background-image: url(icon@2x.png);
                }
            }
        

Не забудьте про Autoprefixer -webkit-min-device-pixel-ratio.

Фоном: облом

            @supports (background-image: url(icon.webp)) {
                button {
                    background-image: url(icon.webp);
                }
            }
        

Другой формат в стилях просто не подсунуть, см. Modernizr.

Всегда фоном!

            div.picture {
                background-image: url(picture.png);
                background-size: cover;
            }
        

Лучше тегом

            img, video {
                object-fit: cover;
                object-position: 25% 0;
            }
        

Стилями

            a::before {
                content: url(icon.png);
            }
        

Вставляет оформление в контент стилями.

Инлайном

            <svg class="burger" viewBox="0 0 12 10" aria-label="Меню">
                <rect class="burger__line" x="0" y="0"/>
                <rect class="burger__line" x="0" y="4"/>
                <rect class="burger__line" x="0" y="8"/>
            </svg>
        

Видно из стилей, удобно менять цвета.

Инлайном

            .burger {
                fill: #4b86c2;
            }
             
            .burger:hover {
                fill: #32b332;
            }
        

Спрайтом

            <svg width="120" height="100"
                viewBox="0 0 12 10" aria-label="Меню">
                <use xlink:href="#burger"></use>
            </svg>
        

Видно из стилей, удобно менять цвета.

Внешним спрайтом

            <svg width="120" height="100"
                 aria-label="Меню">
                <use xlink:href="sprite.svg#burger"></use>
            </svg>
        

К сожалению, стили уже не пробьются внутрь. Но оно вам точно нужно?

Внешним спрайтом

            <svg xmlns="http://www.w3.org/2000/svg">
                <symbol id="burger" viewBox="0 0 12 10">
                    <rect width="12" height="2" x="0" y="0"/>
                    <rect width="12" height="2" x="0" y="4"/>
                    <rect width="12" height="2" x="0" y="8"/>
                </symbol>
            </svg>
        

Base64

            button {
                background-image: url('data:image/png;base64,iVBORw0K
        EUgAAAgAAAAIACAYAAAD0eNT6AAAACXBIWXMAAA7EAAAOxAGV
        AAgyAAAQJABAIAgAwAAQQYAAIIMAAAEGQAACDIAABBkAAAgyA
        MAAAEGQAACDIAABBkAAAgyAAAQJABAIAgAwAAQQYAAIIMAAAE
        ABBkAAAgyAAAQJABLJBGFFAIAgAwAAQQYAAIIMAAAEGQA…');
            }
        

URL-кодирование

            button {
                background-image: url('data:image/svg+xml,%3Csvg xmlns
        ='http://www.w3.org/2000/svg' viewBox='0 0 12 10'
        fill='%234b86c2'%3E%3Crect width='12' height='2'
        x='0' y='0'/%3E%3Crect width='12' height='2' x='0'
        y='4'/%3E%3Crect width='12' height='2' x='0' y…');
            }
        

DVD+RW

DVD-диск

Загрузка

Ленивая загрузка

            <img src="picture.jpg" loading="lazy">
        

Приоритет загрузки

            <img src="picture.jpg" importance="low">
        

Если очень-очень нужно, то осторожно можно:

            <link rel="preload" href="picture.jpg" as="image">
        

Неблокирующий рендеринг

            <img src="picture.jpg" async="on">
        

Загрузка скриптом

            const img = new Image();
            img.src = 'picture.png';
        
                img.onload = () => {
                    // Вставка img
                };        
            
                img.decode().then(() => { 
                    // Вставка img
                });
            

Пока только в Chrome, см. MDN и ждите счастья.

Проверка поддержки

            const img = new Image();
            img.src = 'picture.webp';
            img.decode().then(() => {
                console.info('WebP');
            }).catch(() => {
                console.warn('Извини');
            });
        
Милдред звонит по телефону

Спасибо!

Ссылки

@pepelsbey

sokr.me/eif