Адаптивна графіка

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

Фізичні пікселі (device pixel або hardware pixel) — це найменші елементи будь-якого екрана (його матриці), кожен з яких має свій колір і яскравість.



Роздільна здатність екрана — це кількість фізичних пікселів на екрані пристрою. Наприклад, роздільна здатність 1920x1080 означає, що екран 1920 фізичних пікселів по ширині і 1080 по висоті. Якщо помножити, вийде загальна кількість пікселів на такому екрані – 2073600.

Щільність пікселів (pixel density) — це кількість фізичних пікселів, яка міститься в один дюйм. Вимірюється в одиницях ppi (pixels per inch). Чим вища щільність, тим менший розмір пікселя і тим більше їх на екрані.


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




Як пов’язана властивість щільності пікселів на екрані та якості відображення зображення?
  • Чим вище щільність пікселів, тим менше пікселів на дюйм екрана, але вони більші за розміром. За рахунок пікселів більшого розміру зображення більше яскраве.
  • Чим вище щільність пікселів, тим більше пікселів на дюйм екрана. За рахунок більшої кількості пікселів зображення більш чітке.
  • Чим вище щільність пікселів, тим більше пікселів на дюйм екрана. Кількість пікселів ніяк не впливає на якість зображення.

CSS-пікселіCSS-пікселі (device-independent pixels) — це абстрактна величина не залежить від екрана пристрою. CSS-пікселі використовуються браузером для розрахунку розмірів елементів на сторінці.




На звичайних екранах один CSS-піксель відповідає одному фізичному пікселю пристрою.

При масштабуванні і на екранах високої піксельної щільності в одному CSS-пікселі може бути більше одного фізичного пікселя.

Скажімо, є блок розміром 2x2 пікселя.



Знаємо, що розміри в CSS-файлі та HTML-документі вказуються в CSS-пікселях.На звичайних екранах елемент займатиме область 2x2 фізичних пікселя.
На екранах, наприклад із щільністю 2, цей же блок отримає 4x4 фізичних пікселя. Тобто вдвічі більше по горизонталі та вертикалі.

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

Фізичні пікселі та CSS-пікселі — це одне й те саме?

  • Так! Коли ти вказуєш розміри елемента в CSS-файлі — це кількість фізичних пікселів, які буде займати цей елемент.
  • Ні! Розміри елемента вказані в редакторі коду — це CSS-пікселі. Вони можуть не збігатися з кількістю фізичних пікселів на екранах підвищеної щільності.

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

Растрові пікселі (bitmap pixels) — найменші частини, що становлять растрове зображення (png, jpg, gif і т. д.). Кожен піксель містить інформацію про свій колір і розташування в системі координат зображення.



У HTML або CSS коді розміри зображення задаються в CSS-пікселях.При відображенні на звичайному екрані один растровий піксель відповідає одному CSS-пікселю.

На екранах із щільністю 2 кожен растровий піксель множиться в 4 рази, що призводить до втрати якості зображення, не підготовленого до ретини.



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

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

Для екранів підвищеної щільності пікселів потрібні спеціально підготовлені ресурси. Текст і векторна графіка відображаються однаково добре на будь-якому екрані.

Ретинізація — це техніка підготовки растрової графіки. Для цього потрібно експортувати з макета більше зображення. Так, щоб показати зображення 200x300 CSS-пікселів на екрані з щільністю 2, необхідно підготувати його варіант у розмірі 400x600, а для екрана з щільністю 3 це зображення має бути 600x900.

У прикладі нижче використовується онлайн-сервіс зображень.

Завантажується три картинки:

  • 320x240 — для звичайних екранів (1x),
  • 640x480 — для екранів із щільністю 2 (2x)
  • 960x720 — для екранів із щільністю 3 ****(3x)
Розмір усіх елементів img однаковий — 320x240 CSS-пікселів


Якщо перейти в приклад з телефону або просто збільшити масштаб сторінки з прикладом, буде видно, що:

Перше зображення сильно розмивається.

Друге — залишається цілком якісним.

Третє — завжди чітке.

Для растрової графіки достатньо підготувати тільки 1x і 2x версії. Більшість людей з хорошим зором не помітять різницю між 2x і 3x зображенням, але вага останнього буде значно більшою, що негативно позначиться на швидкості його завантаження.

Процес ретинізації

Процес підготовки складається з:Експорту зображень у N-разів більше від розміру оригіналу
Збереження великих зображень з відповідними префіксами @2x і @3x. Для оригіналу префікс не потрібний.
Також нема потреби експортувати та завантажувати найбільше зображення.



На цьому кроці ми розглянули проблему та навчилися робити ретинізацію растрової графіки. Далі ми навчимося завантажувати різні зображення під екрани різної густини пікселів.

Гумові зображення


Уявіть зображення 1200x600 пікселів. Воно чудово виглядає на широкому екрані. А що буде, якщо ми відкриємо сторінку на телефоні чи планшеті?

Нічого доброго.

Зображення залишатиметься шириною 1200 пікселів. Отже, з'явиться горизонтальна смуга прокручування. А ще зображення виглядатиме розмито на екранах підвищеної щільності пікселів.


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

Найпростіший спосіб реалізувати респонсивність — це зробити зображення гумовим, тобто використовувати одне зображення для всіх пристроїв і глобально задати набір CSS-властивостей (див. код нижче).


img {
  display: block;
  max-width: 100%;
}


  • Зображення необхідно зробити блоковим, щоб прибрати нижній «зазор» рядкового елемента.
  • Максимальна ширина в 100% гарантує, що зображення буде зменшуватися, якщо необхідно. При цьому не розтягнеться більше ніж 100% своєї оригінальної ширини, щоб не втрачати якість.


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

Створимо контейнер для картинки div.thumb та задамо йому мінімальну та максимальну ширину. Надамо зображенню респонсивні властивості. Тепер картинка завжди гарно заповнюватиме «тумбу», змінюючи свій розмір залежно від ширини батька.

Як змінити ширину області з результатом?


Перейди за посиланням і скористайся інструментами розробника для респонсивної верстки, як було показано на прикладі сторінки goit:


відкрий інструменти розробника (Ctrl + Shift + I для Windows і Linux**, cmd + Shift + I** для macOS)
натисни на іконку 1 (див. схему вище), щоб активувати панель перемикання пристроїв (Toggle device toolbar). Для виходу з цього режиму, натисни на іконку 1 ще раз.
зміни ширину в'юпорта шляхом простого розтягування. Для цього використовується елемент управління 2. Ефект такий, ніби розтягується або стискається вікно браузера, тим самим змінюючи ширину в'юпорта.



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


Щоб браузер міг завантажити різні зображення:

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



Уявімо, що розробник вказав два доступні зображення: 300×300 і 600×600 пікселів.

Якщо браузеру достатньо картинки 300×300, це чотириразова економія ваги зображення, яке завантажується. Чим менший розмір екрану пристрою, тим швидше завантаження.


<img srcset="./img/photo.jpg 1x, ./img/photo@2x.jpg 2x" />


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


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


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


В атрибуті src обов'язково вказується версія зображення в стандартній якості. Ця версія зображення буде використана у випадку, якщо браузер старіший і не вміє працювати з атрибутом srcset.

У живому прикладі для атрибута srcset зазначені зображення стандартного та подвійного розміру, а також оригінальне зображення за замовчуванням в атрибуті src.
Щоб перевірити, яке зображення відкривається, треба відкрити інструменти розробника і перейти на вкладку Network. Там побачимо, що завантажується тільки одне зображення — версія 1x, яка відповідає щільності екрана, на якому наразі відкрита веб-сторінка. При вході з пристрою з екраном високої щільності пікселів, браузер завантажить зображення, у якого вказано дескриптор 2x.



Фонові зображення


Растрові фонові зображення також необхідно підготувати для екранів підвищеної щільності. Для ретинізації фонового зображення необхідно встановити розмір фону елемента рівним розміру самого елемента.


.box {
  width: 200px;
  height: 300px;
  background-image: url('photo.png');
  background-size: 200px 300px;
}


Якщо елемент не має фіксованої ширини і висоти, тобто залежить від ширини батька, розмір фону можна задати значенням cover. Так, фон повністю заповнить елемент.


.box {
  background-image: url('photo.png');
  background-size: cover;
}


На якість відображення фону також впливає щільність пікселів екрана.

Щоб визначити щільність пікселів екрана CSS, є медіафункції: resolution, min-resolution і max-resolution. Вони дозволяють перевірити точний збіг і мінімальне/максимальне значення щільності пікселів пристрою.


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


/* Базові стилі і 1x зображення */
.box {
  width: 200px;
  height: 300px;
  background-image: url('photo.png');
  background-size: 200px 300px;
}

/* Перевизначаємо шлях до зображення
   якщо щільність екрана як мінімум 2x */
@media (min-resolution: 192dpi) {
  .box {
    background-image: url('photo@2x.png');
  }
}


Значення медіафункцій перевірки щільності пікселів — це одиниця dpi (dots per inch), тобто кількість фізичних пікселів на дюйм екрана.


На екранах стандартної щільності пікселів в одному дюймі 96 точок. Тому для перевірки екранів із щільністю 2 і більше вказуємо значення 192dpi (96x2).


У прикладі встановлено однакове фонове зображення в різних розмірах для екранів зі стандартною (1x) та подвоєною (2x) щільністю пікселів.



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




Практичне завдання


Завдання 1


Доповни код у CSS-редакторі, додавши правило із селектором усіх зображень документа. Запиши у правилі властивості, щоб зробити зображення гумовими.

Критерії виконання завдання

  • У коді є правило із селектором img
  • У правилі із селектором img є властивість display зі значенням block
  • У правилі із селектором img є властивість max-width зі значенням 100%

<section class="infocard"> <img src="https://picsum.photos/id/85/600/400" alt="Infocard image" /> <div class="content"> <h2 class="title">Bravery</h2> <p class="descr"> The quality or state of having or showing mental or moral strength to face danger, fear, or difficulty </p> </div> </section>


* {

  box-sizing: border-box;

}


body {

  font-family: sans-serif;

  color: #212121;

  line-height: 1.5;

}


.infocard {

  max-width: 300px;

  border: 1px solid #212121;

}


.content {

  padding: 8px;

}


.title,

.descr {

  margin: 0;

}



Завдання 2


Доповни код у HTML-редакторі так, щоб зображення всередині елемента з класом infocard було респонсивним.

  • Для екранів стандартної щільності пікселів має завантажуватись зображення https://picsum.photos/id/85/300/200
  • Для екранів щільності пікселів 2 і більше має завантажуватися зображення https://picsum.photos/id/85/600/400

Критерії виконання завдання

  • У коді є тег img
  • У тега img є атрибут alt зі значенням Infocard image
  • У тега img є атрибут src зі значенням https://picsum.photos/id/85/300/200
  • У тега img є атрибут srcset зі значенням https://picsum.photos/id/85/300/200 1x, https://picsum.photos/id/85/600/400 2x

<section class="infocard">
  <img alt="Infocard image" />
  <div class="content">
    <h2 class="title">Bravery</h2>
    <p class="descr">
      The quality or state of having or showing mental or moral strength to face
      danger, fear, or difficulty
    </p>
  </div>
</section>

* {
  box-sizing: border-box;
}

body {
  font-family: sans-serif;
  color: #212121;
  line-height: 1.5;
}

img {
  display: block;
  max-width: 100%;
}

.infocard {
  max-width: 300px;
  border: 1px solid #212121;
}

.content {
  padding: 8px;
}

.title,
.descr {
  margin: 0;
}

Завдання 3


Доповни код у CSS-редакторі так, щоб фонове зображення елемента з класом banner було респонсивним.

  • Фон не повинен повторюватися
  • Фон має бути центрованим
  • Фон повинен повністю заповнювати елемент
  • Для екранів стандартної щільності пікселів має завантажуватись зображення https://picsum.photos/id/11/960/300
  • Для екранів щільності пікселів 2 і більше має завантажуватися зображення https://picsum.photos/id/11/1920/600

Критерії виконання завдання

  • У коді є правило із селектором .banner
  • У правилі із селектором .banner є властивість height зі значенням 300px
  • У правилі із селектором .banner є властивість max-width зі значенням 960px
  • У правилі із селектором .banner є властивість background-color зі значенням darkolivegreen
  • У правилі із селектором .banner є властивість background-repeat зі значенням no-repeat
  • У правилі із селектором .banner є властивість background-position зі значенням center
  • У правилі із селектором .banner є властивість background-size зі значенням cover
  • У коді є медіа-запит із медіа-функцією min-resolution
  • Для екранів стандартної щільності пікселів завантажується фонове зображення https://picsum.photos/id/11/960/300
  • Для екранів щільності пікселів 2 та більше завантажується фонове зображення https://picsum.photos/id/11/1920/600
<div class="banner"></div>

.banner {
  height: 300px;
  max-width: 960px;
  background-color: darkolivegreen;
}

Нові Старіші