Home

Адаптивна верстка empty

Зміст

  1. Медіа-запити
  2. Логічні оператори
  3. Метатег viewport
  4. Типи верстки
  5. Щільність пікселів
  6. Респонсивні зображення
  7. Респонсивні фонові зображення
  8. Респонсивний елемент img
  9. Атрибут srcset
  10. Дескриптор x
  11. Дескриптор w
  12. Атрибут sizes
  13. Як браузер вибирає
  14. Елемент picture
  15. Підтримка сучасних форматів
  16. Кадрування (art direction)

Медіа-запити

Медіа-запити - це те, що робить можливим створення сучасних адаптивних веб-сторінок, які однаково добре виглядають на будь-якому екрані, чи то десктоп, чи то смартфон. Все зводиться до застосування того або іншого CSS-правила, залежно від розміру вікна браузера (області перегляду, в'юпорту), налаштувань браузера або можливостей пристрою

  • Алгоритм застосування стилів наступний:
  • Розробник описує набір медіа-запитів і CSS-правил всередині них.
  • Браузер відстежує зміну розміру в'юпорту.
  • Браузер застосовує CSS-правила з медіа-запитів, що відповідають поточному розміру в'юпорту.
        @media screen and (min-width: 900px) {
            body {
              background-color: orange;
            }
          }
                
        під час друку документа.
        @media print 

        при ширині в'юпорту більше 400px.
        @media screen and (min-width: 400px) 

        Тип screen можна не вказувати, 
        якщо стилі пишуться тільки для екранів.
        @media (min-width: 400px)
                

Медіа-типи

  • all - якщо не вказати тип носія, за замовчуванням буде використано це значення, яке означає будь-який пристрій.
  • print - відповідає принтерам і пристроям, призначених для відтворення друкованого варіанту, наприклад веб-браузера, що відображає документ у режимі «Попередній перегляд».
  • screen - описує пристрої з фізичним екраном: смартфони, планшети, монітори, телевізори тощо. Тобто все, що не охоплює тип print.

Логічні оператори

Медіа-тип і медіа-функції можуть бути розділені необов'язковими логічними операторами not, and і only - значення за замовчуванням.

        @media only|not media-type only|and|
            not (media-feature)
                

Оператор and

Оператор and (буквально «І») використовується не тільки між типом носія і медіа-умовою, але і для зв'язування декількох медіа-функцій з перевірками значень.

        @media screen and (min-width: 400px) 
            and (max-width: 800px) {}
                

Оператор , or

Оператор , or (буквально «АБО») дозволяє вказати набір виразів, при виконанні хочаб одного з них, виконається медіа-запит

    @media (max-width: 600px), (min-width: 900px)
    @media (max-width: 600px) or (min-width: 900px)
                

Оператор not

    @media not print {} // скрізь, крім друку
    /* Ніколи не виконається */
    @media not (max-width: 500px)
    Виконається, якщо ширина буде більша за 500px.
    @media not screen and (max-width: 500px) 
                

Метатег viewport

Сторінки, адаптовані для перегляду на різних пристроях, повинні містити в розділі head мета-тег viewport. Він повідомляє браузеру, яким чином потрібно контролювати розміри і масштаб в'юпорту.

    head
    !-- Інші мета-теги --
    meta name="viewport" content="width=device-width, 
        initial-scale=1.0" /
    title Мета-тег viewport 
        важливий для адаптивних сторінок /title
    /head
                
vievport
  1. 3 - вибір пристрою з точними розмірами, наприклад iPhone, iPad, Pixel тощо, або значення за замовчуванням - Reponsive, респонсивний режим з довільною шириною в'юпорту.
  2. 4 - поточні розміри ширини і висоти в'юпорту. Також можна ввести значення вручну.
  3. 5 - зміна масштабу, на випадок, коли робота ведеться з великими величинами і потрібно подивитися повністю всю верстку.
  4. 6 - можливість імітувати поворот пристрою у портретний або ландшафтний режим.

Типи верстки adaptive responsive

Респонсивна (responsive) веб-сторінка - має кілька варіантів відображення, переходи між ними плавні, елементи і контейнер тягнуться як гумові. При зміні розміру в'юпорту блоки плавно стискаються або розтягуються, а коли настає точка перелому (breakpoint) - змінюють своє розташування таким чином, щоб оптимально зайняти увесь вільний простір за горизонталлю.

Адаптивна (adaptive) веб-сторінка - має кілька варіантів відображення, і, на відміну від респонсивної сторінки - буквально. Дизайн змінюється ривками у жорстко заданих точках перелому, і не тягнеться між ними.

Example

Щільність пікселів

Ретинізація графіки

    img src="icon.png" width="200" height="300"
    img src="icon@2x.png" width="200" height="300"
    img src="icon@3x.png" width="200" height="300"
                

Далі ми навчимося завантажувати різні зображення під кожну ширину або щільність екрану.

Респонсивні зображення

Респонсивні зображення - це термін для опису набору прийомів, що використовуються в HTML і CSS, за допомогою яких контентні та фонові зображення виглядають однаково добре на пристроях з різними розмірами і щільністю екрану.

    /* Властивості потрібно застосувати до всіх зображень,
    тому використовується селектор тегу. */
    img {
        display: block;
        max-width: 100%;
        height: auto;
    }
                

Респонсивні фонові зображення

    .box {
        width: 480px;
        height: 320px;
        background-image: url('photo.png');
        background-size: 480px 320px;
      }
      
      @media (min-device-pixel-ratio: 2),
        (-webkit-min-device-pixel-ratio: 2),
        (min-resolution: 192dpi),
        (min-resolution: 2dppx) {
        .box {
          background-image: url('photo@2x.png');
        }
      }
                

У медіа-функції min-device-pixel-ratio вказується числове значення піксельної щільності екрану - коефіцієнт між фізичними і CSS-пікселями. Також необхідно вказати функцію min-resolution з двома різними значеннями.

  • dpi (dots per inch) - кількість фізичних пікселів на дюйм екрана. На екранах стандартної щільності пікселів в одному дюймі 96 точок.
  • dppx (dots per pixel) - кількість фізичних пікселів в одному CSS-пікселі, іншими словами - це щільність пікселів. 1dppx = 96dpi.
  • Медіа-функція min-device-pixel-ratio підтримується деякими браузерами тільки з вендорним префіксом, тому, якщо обробити цей код автопрефіксером, отримаємо фінальний варіант.

Якщо відкрити інструменти розробника і перейти на вкладку Network, то буде видно, що завантажується тільки одне зображення

network

Респонсивний елемент img

Респонсивний елемент використовується браузером для завантаження тільки того зображення, яке підходить для цього пристрою із запропонованих розробником. Розробник вказує список доступних для завантаження зображень, а браузер, виходячи з розміру екрану пристрою і його піксельної щільності, вибирає найбільш вдалий.

Атрибут srcset

Визначає список версій однакового зображення різних розмірів. Не варто намагатися завантажити різні зображення (за контентом або форматом) за допомогою цієї техніки, браузер звертає увагу тільки на розмір і вважає, що все, що передають в srcset - це версії одного й того самого зображення.

                    img srcset="" src="" alt="" /
                

Дескриптор x

Найпростіший спосіб використання респонсивного елемента img - це застосування дескриптора x, який буквально вказує браузеру, для якої щільності екрану підходить ця версія зображення.

    img
      srcset="photo.jpg 1x, photo@2x.jpg 2x"
      src="photo.jpg"
      alt="Опис зображення для усіх версій"
    /
                

В атрибуті src вказується версія зображення стандартної якості, яка буде використана у разі, якщо браузер старий і не знає про srcset. В атрибуті srcset вказуємо 1x і 2x версії зображення, розділяючи оголошення комою. Якщо сторінка буде відкрита на пристрої з щільністю пікселів 2 або вище, замість стандартного, буде використане зображення photo@2x.jpg.

У прикладі для атрибута srcset вказані зображення стандартної і подвійної щільності, а також оригінальне зображення за замовчуванням в атрибуті src.

Cute puppy

Єдиний недолік такого підходу полягає в обмеженості критеріїв, за якими браузер вибирає зображення - тільки щільність пікселів екрану. Респонсивні зображення використовуються у респонсивній верстці, розміри блоків в якій змінюються, залежно від розміру в'юпорту.

Не завжди можливо задати точні розміри зображення на екрані, тому що під час збільшення в'юпорту необхідно буде показувати зображення 300x200 у блоці розмірами 600x400 пікселів або більше.

Ідеально, якби браузер вибирав зображення не тільки за щільністю пікселів, але ще враховував поточний розмір в'юпорту і розмір самого зображення на екрані. Для цього йому необхідно знати розмір оригінального зображення із запропонованого списку. Якраз це завдання і вирішує дескриптор w та атрибут sizes.

Дескриптор w

Ми, як і раніше, надаємо одне і те саме зображення у різних розмірах, але водночас даємо браузеру більше інформації, щоб він міг сам вибрати необхідне зображення, виходячи зі щільності пікселів, розміру в'юпорту та оригінального розміру зображення.

    img
srcset="photo-300.jpg 300w, photo-600.jpg 600w, photo-1200.jpg 1200w"
    src="photo-300.jpg"
    alt="Опис зображення для всіх версій"/
                

Позначаючи кожне зображення дескриптором w, в якому вказана ширина цього зображення в пікселях, ми перекладаємо всі обчислення і вибір зображення на браузер.

Атрибут sizes

У разі використання дескриптора w, тобто прив'язки до фізичних розмірів зображення, необхідно використовувати атрибут sizes, щоб підказати браузеру приблизний розмір полотна, на якому в браузері буде малюватися зображення. Розміри можна вказувати як у пікселях, так і у відносних одиницях.

Наприклад, якщо зображення на екрані завжди буде 300px, достатньо вказати одне значення.

img
  srcset="photo-300.jpg 300w, photo-600.jpg 600w, photo-1200.jpg 1200w"
  sizes="300px"
  src="photo-300.jpg"
  alt="Опис зображення для всіх версій"
/
                

У разі, коли зображення повинно бути на 100% ширини в'юпорту на мобільних пристроях до 600px, 300px на екранах 601-900px і 600px на екранах ширше, значення sizes буде містити медіа-запити.

img
  srcset="photo-300.jpg 300w, photo-600.jpg 600w, photo-1200.jpg 1200w"
  sizes="(min-width: 900px) 600px, (min-width: 600px) 300px, 100vw"
  src="photo-300.jpg"
  alt="Опис зображення для всіх версій"
/
                
  • (min-width: 900px) 600px - при ширині в'юпорту від 900px, розмір зображення 600px.
  • (min-width: 600px) 300px - при ширині в'юпорту від 600px, розмір зображення 300px
  • 100vw - повна ширина в'юпорту. Значення за замовчуванням, яке вказується останнім.

Як браузер вибирає

Браузер вибирає зображення за дуже простим алгоритмом - множить розмір полотна (значення sizes) на щільність пікселів і вибирає найближче, підходяще за розміром зображення.

adaptiv-viev-width

На ілюстрації показаний десктоп і смартфон з шириною зображення 100% ширини в'юпорту. Напишемо розмітку респонсивного елемента img для цього випадку.

img
  srcset="img-1200x714.png 1200w, img-3000x1768.png 3000w"
  sizes="100vw"
  src="img.png"
  alt="Опис зображення для всіх версій"
/
                

Браузер множить ширину в'юпорту на щільність пікселів.

  • 1680 * 2 = 3360 - на ілюстрації це img-3000x1768.png для десктопа.
  • 375 * 3 = 1125 - на ілюстрації це img-1200x714.png для смартфона.

У разі, коли в sizes задане фіксоване значення ширини зображення, браузер помножить його на щільність пікселів. Наприклад, sizes задане значення 400px.

img
  srcset="
    photo-300.jpg   300w,
    photo-600.jpg   600w,
    photo-900.jpg   900w,
    photo-1200.jpg 1200w
  "
  sizes="400px"
  src="photo-300.jpg"
  alt="Опис зображення для всіх версій"
/
                
  • 400 * 2 = 800 - для десктопа буде взято зображення максимально близьке до 800px, а саме photo-900.jpg.
  • 400 * 3 = 1200 - для смартфона буде взято зображення максимально близьке до 1200px, а саме photo-1200.jpg.

Тобто для мобільного пристрою буде взято більше зображення? Не завжди, браузер вибирає те зображення, яке найкраще підходить в цій ситуації.

Елемент picture

Як ми вже розібралися, респонсивний елемент img дозволяє завантажувати різні версії (розміри) однакового зображення. Елемент picture використовується у разі, коли необхідно завантажити зображення різного формату (розширення), зображення різної геометрії (кадрування) або зображення для підтримки режиму темної теми.

Елемент picture - це контейнер для одного або більше елементів source, в яких перераховуються можливі варіанти, та одного обов'язкового елемента img

        picture
            source srcset="" media="" sizes="" type="" /
            source srcset="" media="" sizes="" type="" /
            img src="" alt="" /
        /picture
                
  • Браузер перевірить кожен з елементів source і вибере найбільш придатний. Щоб вибрати оптимальне зображення, браузер аналізує атрибути srcset, media, sizes і type.
  • Якщо жоден з варіантів не підійде, буде вибране зображення, вказане в атрибуті src елемента img
  • Вибране зображення малюється на полотні, яке займає елемент img.

Підтримка сучасних форматів

Елемент picture застосовується для завантаження зображень в сучасних форматах (наприклад webp). Для браузерів, які не підтримують такі формати, вказується дефолтне зображення в альтернативному форматі (наприклад jpg або png). Атрибут type вказує MIME-тип зображення. Якщо браузер не підтримує його, то цей елемент source пропускається.

Наступний приклад визначає елемент picture, який дозволить браузерам завантажити photo.webp, водночас надається альтернатива photo.jpg для браузерів, які ще не підтримують webp.

<picture>
    <source srcset="photo.webp 1x, photo@2x.webp 2x" 
        type="image/webp" />
    <source srcset="photo.jpg 1x, photo@2x.jpg 2x" 
        type="image/jpeg" />
    <img src="photo.jpg" alt="Кіт" />
</picture>
                

Всі варіанти доступних зображень перелічуються в тегах source, які будуть послідовно оброблятися браузером.

Для того щоб швидко і зручно конвертувати зображення у формат webp, можна використовувати онлайн-інструменти, наприклад squoosh.app.

Кадрування (art direction)

Атрибут media дозволяє визначити медіа-запит, який браузер буде аналізувати для вибору елемента source. Якщо медіа-запит визначається як помилковий (не підходить), то цей елемент source пропускається.

Перейдіть у приклад і змінюйте ширину області перегляду.

Cute puppy

Для підтримки екранів з високою щільністю пікселів, кожному елементу source необхідно додати набір зображень з дескрипторами в атрибут srcset, і не забути задати атрибут sizes.

Додамо в код попереднього прикладу підтримку ретіни зі щільністю 2x, використовуючи дескриптор w. Обмежимо ландшафтну версію зображення максимальною шириною 800px, якщо в'юпорт ширший за 800 пікселів. В іншому випадку зображення тягнеться на 100% в'юпорту.

Cute puppy