Особливості верстки для мобільних пристроїв
Конспект лекції: Retina-дисплеї, Device Pixel Ratio, viewport мета-тег, мобільні браузери
1. Проблема декоративної графіки на Retina-дисплеях
Декоративні зображення (іконки, фони) вставляються через CSS за допомогою background-image. На
екранах з підвищеною щільністю пікселів (Retina) растрова графіка може виглядати розмито.
Фізичні vs CSS-пікселі
CSS-піксель — це віртуальна одиниця. Один CSS-піксель може відповідати 2, 3 або більше фізичним пікселям екрана. Коефіцієнт DPR (Device Pixel Ratio) визначає це співвідношення.
| Ситуація | Результат |
|---|---|
Розмір файлу = background-size |
Якість ідеальна |
Файл більший за background-size |
Браузер зменшує — якість зберігається |
Файл менший за background-size |
Браузер розтягує — якість втрачається (розмиття) |
2. Рішення «в лоб» — збільшене зображення
Найпростіший підхід — підготувати зображення в 2× (або 3×) більшому розмірі, а в CSS вказати потрібний background-size:
.icon {
background-image: url("icon@2x.png"); /* 32×32 px файл */
background-size: 16px 16px; /* відображаємо як 16×16 */
background-repeat: no-repeat;
}
3. Іконковий шрифт (Icon Font)
Іконковий шрифт — це шрифт, де замість літер — іконки. Оскільки шрифт — векторний, іконки масштабуються без втрати якості.
Підключення
@font-face {
font-family: "MyIcons";
src: url("fonts/icons.woff2") format("woff2");
font-weight: normal;
font-style: normal;
}
Використання через псевдоелемент
.link::before {
content: "\e901"; /* Unicode-код іконки */
font-family: "MyIcons";
font-size: 16px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
Переваги
- Розмір змінюється через
font-size— без втрати якості - Колір змінюється через
color(як звичайний текст) - Готові набори іконок (Font Awesome, Material Icons тощо)
Недоліки
- Іконка — це символ (текст), а не графіка — семантично неправильно
- Не можна розфарбувати окремі частини іконки різними кольорами
- Застарілий підхід — SVG має всі переваги без недоліків
4. SVG — сучасне рішення
SVG (Scalable Vector Graphics) — формат векторної графіки. Масштабується без втрати якості, бо описує фігури формулами, а не пікселями.
Два способи використання
| Спосіб | Як | Зміна кольору | Доступ з JS |
|---|---|---|---|
| Зовнішній файл | background-image: url("icon.svg") |
Ні | Ні |
| Вбудований (inline) | Тег <svg> прямо в HTML |
Так (через fill) |
Так |
Структура SVG
<svg class="icon" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s..."/>
</svg>
<svg>— контейнер;viewBoxзадає систему координат<path>— контур фігури; атрибутdописує кривніfill— колір заливки (атрибут або CSS-властивість)
Керування кольором inline SVG
/* Видаліть атрибут fill з <path> в розмітці! */
.icon path {
fill: #333;
}
.link:hover .icon path {
fill: #0066cc;
}
fill заданий атрибутом у тезі <path fill="...">,
CSS-властивість fill його не перевизначить (як inline-стилі). Видаліть атрибут, щоб керувати
кольором з CSS.
Розмір inline SVG
.icon {
width: 24px;
height: 24px;
}
5. Порівняння підходів до декоративної графіки
| Критерій | PNG @2x | Іконковий шрифт | SVG |
|---|---|---|---|
| Якість при масштабуванні | Обмежена розміром файлу | Без втрат | Без втрат |
| Зміна кольору в CSS | Ні | Так (color) |
Так (fill, тільки inline) |
| Багатоколірність | Так | Ні | Так (окремі <path>) |
| Семантичність | Графіка | Текст (семантично неправильно) | Графіка |
| Підтримка браузерами | Усі | Усі | Усі сучасні |
6. Стилізація форм на мобільних пристроях
Мобільні браузери мають власні дефолтні стилі для елементів форм — скруглені кути у <input>,
нестандартний вигляд <select>.
Скидання системного вигляду
input, select, textarea, button {
-webkit-appearance: none;
-moz-appearance: none;
border-radius: 0;
}
appearance без префікса не підтримується всіма браузерами. Завжди
використовуйте обидва префікси: -webkit-appearance та
-moz-appearance.
Повернення стрілки для select
Після скидання appearance у <select> зникне стрілка. Додайте її через
SVG-фон:
select {
background-image: url("arrow-down.svg");
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 12px;
padding-right: 30px;
}
border,
border-radius, background, color, font-size. Не
покладайтесь на дефолтні стилі — вони різні на різних платформах.
7. Автовизначення телефонних номерів на iOS
iOS Safari автоматично розпізнає числа, схожі на телефонні номери, і перетворює їх на сині підкреслені
посилання з протоколом tel:.
Чому просте скидання стилів не працює
Браузер не змінює ваш тег — він обгортає текст у <a href="tel:...">
всередині вашого елемента. Тому стилі для батьківського елемента не допоможуть.
Рішення 1 — селектор за атрибутом
a[href^="tel"] {
color: inherit;
text-decoration: none;
}
Рішення 2 (краще) — одразу робити посилання
<a href="tel:+380441234567">+38 (044) 123-45-67</a>
Стилізуйте посилання як потрібно — і на десктопі, і на мобільних пристроях воно виглядатиме однаково.
Рішення 3 — повне вимкнення автовизначення
<meta name="format-detection" content="telephone=no">
<a href="tel:..."> вручну.
8. Селектори за атрибутом
| Синтаксис | Опис | Приклад |
|---|---|---|
[attr="value"] |
Точне співпадіння | input[type="text"] |
[attr^="value"] |
Починається з... | a[href^="tel"] |
[attr$="value"] |
Закінчується на... | a[href$=".pdf"] |
[attr*="value"] |
Містить підрядок | a[href*="example"] |
[attr|="value"] |
Дорівнює value або починається з value- | [class|="button"] |
Спрощення класів-модифікаторів через [class|="..."]
Селектор [class|="button"] вибирає елемент, клас якого дорівнює
button або починається з button-. Це дозволяє писати базові стилі
один раз для всіх варіантів:
/* Застосується до class="button", class="button-primary", class="button-large" */
[class|="button"] {
padding: 1em 2em;
border: none;
border-radius: 4px;
}
/* Конкретний модифікатор */
.button-accent {
background-color: hotpink;
}
Замість <div class="button button-primary"> можна писати лише
<div class="button-primary"> — базові стилі підхопляться автоматично.
tel:, mailto: тощо).
9. Тестування верстки з динамічним контентом
Верстка повинна працювати з будь-якою кількістю контенту — коротким текстом, довгим текстом, різною кількістю елементів.
Що тестувати
- Багато тексту — чи не ламається макет?
- Мало тексту — чи не з'являються порожні простори?
- Різна кількість колонок / карток
- Відсутність зображень
margin-top для вертикального центрування! При
зміні контенту (більше/менше тексту) вирівнювання зламається. Використовуйте align-self: center
або margin: auto у flex.
10. Типи input для мобільних пристроїв
HTML5 додав нові типи для <input>, які змінюють віртуальну клавіатуру на мобільних
пристроях:
| Тип | Клавіатура | Додаткові можливості |
|---|---|---|
type="text" |
Звичайна текстова | — |
type="search" |
Текстова з кнопкою "Знайти" | Хрестик для очищення поля, кнопка пошуку замість Enter |
type="email" |
Латинська з символом @ | Перевірка формату з required |
type="tel" |
Цифрова з +, -, #, * | Зручний набір номерів |
type="number" |
Цифрова | Стрілки збільшення/зменшення, атрибут step |
Ці типи впливають тільки на віртуальні клавіатури. Фізична клавіатура комп'ютера не зміниться.
Вбудована валідація з required
Коли required поєднується з типізованим input, браузер перевіряє не тільки заповненість, а й
формат:
<input type="email" required>
<!-- Перевірить наявність @ та домену -->
<input type="tel" required>
<!-- Перевірить, що поле заповнене -->
Мінус: вигляд та текст повідомлень відрізняється між браузерами і не налаштовується. Для однакової поведінки потрібна валідація через JavaScript.
inputmode — альтернатива type="number"
type="number" має проблеми з UX: стрілки збільшення/зменшення заважають, випадковий скрол змінює
значення. Краща альтернатива — комбінація type="text" з атрибутом
inputmode:
<input
type="text"
inputmode="numeric"
pattern="[0-9]*"
placeholder="Введіть код"
>
inputmode="numeric" викликає цифрову клавіатуру на мобільних, а pattern забезпечує
валідацію — без зайвих стрілок та випадкових змін при скролі.
type="number" — для полів, де потрібні стрілки
(кількість товарів, крок). inputmode="numeric" — для кодів, PIN, номерів карток, де стрілки
заважають.
11. Атрибут pattern для валідації
Атрибут pattern дозволяє вказати регулярний вираз (regex) для перевірки введених даних:
<!-- Тільки цифри, мінімум 3 символи -->
<input type="text" pattern="[0-9]{3,}" required>
<!-- Міжнародний формат телефону -->
<input type="tel" pattern="\+[0-9]{10,13}" required>
HTML-валідація (required, pattern) легко обходиться через DevTools. Для надійної
перевірки потрібен JavaScript на клієнті та перевірка на сервері.
12. Підсумкова таблиця
| Тема | Ключові моменти |
|---|---|
| Retina та DPR | CSS-піксель ≠ фізичний піксель; DPR = фізичний / CSS; растр на Retina — розмивається |
| Іконковий шрифт | Іконки як символи шрифту; масштабується без втрат; застарілий підхід |
| SVG | Векторна графіка; найкраще рішення; inline — дозволяє fill та JS |
| Форми на мобільних | -webkit-appearance: none + явні стилі; стрілка select через SVG-фон |
| Телефони на iOS | Автовизначення; a[href^="tel"] для стилів; найкраще — робити <a href="tel:...">
одразу
|
| Селектори за атрибутом | [attr="val"], [attr^="val"], [attr$="val"], [attr*="val"], [attr|="val"]
|
| Типи input | search, email, tel, number — змінюють мобільну клавіатуру |
| inputmode | inputmode="numeric" — цифрова клавіатура без стрілок; краще за type="number" для кодів та PIN |
| pattern | Regex-валідація у HTML; обходиться через DevTools; потрібна серверна перевірка |