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

Вадим Макеев, 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