Кто я?
- доброжелюбный бородач
- пятый голос подкаста «Веб-стандарты»
- редактор ленты новостей по фронтенду
- организатор митапов, конференций и воркшопов
- разработчик интерфейсов в Яндекс.Поиске
Что такое
тач-устройство?
Что нам даёт знание про тип устройства?
1 Эксабайт
=
1 000 000 000 Гигабайт
🇷🇺 |
Модель |
|
1 |
iPhone 7 |
6.76% |
2 |
iPhone 6 |
4.22% |
3 |
iPhone 6S |
3.90% |
4 |
iPhone SE |
3.70% |
5 |
iPhone X |
3.40% |
6 |
iPhone 5S |
2.84% |
7 |
iPhone 7 Plus |
2.51% |
8 |
iPhone 8 |
2.47% |
9 |
iPhone 8 Plus |
2.23% |
10 |
Xiaomi Redmi Note 4 |
1.48% |
The most popular
smartphones in 2019
🇺🇸 |
Модель |
|
1 |
iPhone 7 |
7.85% |
2 |
iPhone 8 Plus |
7.67% |
3 |
iPhone 8 |
6.59% |
4 |
iPhone X |
6.04% |
5 |
iPhone 7 Plus |
5.91% |
6 |
iPhone XR |
5.06% |
7 |
iPhone 6S |
4.23% |
8 |
iPhone XS Max |
3.00% |
9 |
Samsung Galaxy S8 |
2.98% |
10 |
Samsung Galaxy S9 |
2.95% |
The most popular
smartphones in 2019
Motorola Moto G4
Размер |
5.5 дюймов |
Разрешение |
1080 x 1920 |
ОС |
Android 6.0.1 (Marshmallow) |
CPU |
Octa-core (4x1.5 GHz Cortex-A53) |
GPU |
Adreno 405 |
Память |
Внутрення 16GB, 2GB RAM |
Батарея |
Li-Ion 3000 mAh |
Цена |
130 EUR |
Время парсинга 1МБ JavaScript (мс)
Ожидание
⬋ ⬊
пассивное активное
➞
35%
12px
=
Минимальный размер
текста
Возможность отменить действие ✅
←
←
const PRECACHE = 'precache-v1';
const RUNTIME = 'runtime';
const PRECACHE_URLS = ['index.html', './', 'styles.css', 'demo.js'];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(PRECACHE)
.then(cache => cache.addAll(PRECACHE_URLS))
.then(self.skipWaiting())
);
});
self.addEventListener('activate', event => {
const currentCaches = [PRECACHE, RUNTIME];
event.waitUntil(
caches.keys().then(cacheNames => {
return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
}).then(cachesToDelete => {
return Promise.all(cachesToDelete.map(cacheToDelete => {
return caches.delete(cacheToDelete);
}));
}).then(() => self.clients.claim())
);
});
Basic Service Worker Sample
self.addEventListener('fetch', event => {
if (event.request.url.startsWith(self.location.origin)) {
event.respondWith(
caches.match(event.request).then(cachedResponse => {
if (cachedResponse) {
return cachedResponse;
}
return caches.open(RUNTIME).then(cache => {
return fetch(event.request).then(response => {
return cache.put(event.request, response.clone()).then(() => {
return response;
});
});
});
})
);
}
});
Basic Service Worker Sample
Как переоткрыть вкладку на смартфоне? 🤔
Можно не спрашивать — не спрашивайте.
Конфуций этого не говорил
prefers-reduced-motion
.animation {
-webkit-animation: boom 0.3s linear infinite both;
animation: boom 0.3s linear infinite both;
}
@media (prefers-reduced-motion: reduce) {
.animation {
animation: none;
-webkit-animation: none;
}
}
prefers-reduced-motion
Battery Status API
navigator.getBattery().then(battery => {
battery.addEventListener('levelchange', () => {
if (battery.level < 0.2) {
// сделать добро
}
});
});
Battery Status API
header {
/* Высота статус-бара в iOS 10 */
padding-top: 20px;
/* Высота статус-бара в iOS 11.0 */
padding-top: constant(safe-area-inset-top);
/* Высота статус-бара в iOS 11+ */
padding-top: env(safe-area-inset-top);
}
@media (spanning: single-fold-vertical) {
body {
flex-direction: row;
}
.map {
flex: 1 1 env(fold-left);
}
.locations-list {
flex: 1;
}
}
<meta name="viewport"
content="user-scalable=no">
<meta name="viewport"
content="maximum-scale=1">
<meta name="viewport"
content="width=device-width, initial-scale=1">
Помогите им!
Разметьте формы!
<form id="login" action="/login" method="post">
<input type="email" autocomplete="username">
<input type="password" autocomplete="current-password">
<input type="submit" value="Пусти!">
</form>
Password Form Styles that Chromium Understands
Touch-свойства
- touch-action
- text-size-adjust
- -webkit-tap-highlight-color
- -webkit-touch-callout
- -webkit-overflow-scrolling
У смартфонов есть
- камера —
Media Capture and Streams API
- гироскоп —
Gyroscope API
- батарея —
Battery Status API
- динамик —
Web Audio API
- Bluetooth —
Web Bluetooth API
- GPS —
Geolocation API
- ...
Ambient Light Sensor API
window.addEventListener("devicelight", function (event) {
var luminosity = event.value;
// 10 ~ 50 lux : тусклое освещение
// 100 ~ 1000 lux : нормальное
// > 10000 lux : яркое
});
Using light sensors
if ('AmbientLightSensor' in window) {
const sensor = new AmbientLightSensor();
sensor.onreading = () => {
console.log('Светит на ' + sensor.illuminance);
};
sensor.onerror = (event) => {
console.log(event.error.name, event.error.message);
};
sensor.start();
}
AmbientLightSensor
Vibration API
window.navigator.vibrate([200, 100, 200]);
Vibration API
Делать ли отдельную версию?
Отдельная версия
- Facebook
- VK
- Twitter
- Google
- Яндекс
Адаптив
- Medium
- BBC
- CSS-Tricks
- Smashing Magazine
/* laptop/desktop */
@media (hover: hover) {}
/* smartphones/touchscreens */
@media (hover: none) and (pointer: coarse) {}
/* device with stylus */
@media (hover: none) and (pointer: fine) {}
/* Wii/Kinect/etc */
@media (hover: hover) and (pointer: coarse) {}
/* mouse/touchpad */
@media (hover: hover) and (pointer: fine) {}
Twitter: Adam Argyle
Поисковики учитывают мобильную версию
1. Исследуйте статистику 📈