Трогательная вёрстка

Никита Дубко, Яндекс

Трогательная
вёрстка

Никита Дубко, Яндекс

Кто я?

2014

Html, CSS and JavaScript tricks for mobile websites
Типы устройств в Беларуси — Яндекс.Радар

Что такое «тач»?

Мобильные операционные системы

Mobile Operating System Market Share Worldwide
Apps for smart feature phones

Что такое «тач»?

Зачем нам знание про «тач»?

1
Отдавать
только нужное

UserAgent

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36

Отдаём только нужное! 😃

😤

JS + Cookie 💡

GDPR 😤

Поворот экрана 😭

38% пользователей прекратят пользоваться сайтом, если контент или разметка не привлекательны.
88% онлайн-потребителей скорее всего не вернутся на сайт после плохого впечатления.
27 Eye-Opening Website Statistics: Is Your Website Costing You Clients?

Адаптивная вёрстка

Адаптивная
Отзывчивая вёрстка

youtube.com/watch?v=srUZ9E4qQlQ

Брейкпоинты

/* Мониторы, ноутбуки */
@media (min-width: 1200px) {}

/* Планшеты в ландшафтном режиме, средние мониторы */
@media (min-width: 992px) and (max-width: 1199px) {}

/* Планшеты в портретном режиме, маленькие мониторы */
@media (min-width: 768px) and (max-width: 991px) {}

/* Телефоны в ландшафтном режиме, планшеты в портретном режиме */
@media (max-width: 767px) {}

/* Телефоны в портретном режиме */
@media (max-width: 480px) {}

1?

2?

10?

📱🖥

Самостоятельные компоненты! 🤘

Container Queries

.container:media(max-width: 400px) .card {
    /* тесно */
}

.container:media(max-width: 1024px) .card {
    /* просторно */
}
Responsive Components: a Solution to the Container Queries Problem

CSS Flexbox

.cards {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin-left: -1em;
}

.card {
    flex: 1 1;
    min-width: 200px;
    margin-left: 1em;
}

CSS Grid

.card-container {
    display: grid;
    padding: 1rem;
    grid-template-columns:
        repeat(auto-fit, minmax(320px, 1fr));
    grid-gap: 1rem;
}
How To: Use CSS Grid Layout to Make a Simple, Fluid Card Grid

Лишний трафик

<picture>
    <source media="(min-width: 1150px)"
            srcset="img-desktop@1x.jpg 1x,
                    img-desktop@2x.jpg 2x">
    <img src="img-mobile@1x.jpg"
         srcset="img-mobile@2x.jpg 2x"
         width="20"
         height="18">
</picture>

Не загружать CSS?

<link rel="stylesheet"
      href="mobile.css"
      type="text/css"
      media="handheld" />

❌ DEPRECATED ❌

Media Types

Не загружать CSS!

<link rel="stylesheet"
      href="mobile.css"
      type="text/css"
      media="(max-width: 720px)" />

Media Features

2
Использовать возможности

Вы не можете определить touchscreen 🤷‍♂️

You Can't Detect A Touchscreen

Но это и не надо 😎

<meta>

<meta name="viewport"
      content="width=device-width, initial-scale=1">

<meta>

@viewport {
    min-width: 640px;
    max-width: 800px;
}

@viewport {
    zoom: 0.75;
    min-zoom: 0.5;
    max-zoom: 0.9;
}

@viewport {
    orientation: landscape;
}
@viewport

touch-action

.e {
    touch-action: auto;
    touch-action: none;
    touch-action: pan-x;
    touch-action: pan-left;
    touch-action: pan-right;
    touch-action: pan-y;
    touch-action: pan-up;
    touch-action: pan-down;
    touch-action: pinch-zoom;
    touch-action: manipulation;
}
touch-action

-webkit-tap-highlight-color

.red-hl {
    -webkit-tap-highlight-color: red;
}

.no-hl {
    -webkit-tap-highlight-color: transparent;
}
-webkit-tap-highlight-color
Customizing Style Sheets

user-select

.e {
    user-select: none;
    user-select: auto;
    user-select: text;
    user-select: contain;
    user-select: all;
}
user-select
.unselectable {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

text-size-adjust

.e {
    text-size-adjust: none;
    text-size-adjust: auto;

    text-size-adjust: 80%;
}
text-size-adjust

-webkit-touch-callout

.e {
    -webkit-touch-callout: default;
    -webkit-touch-callout: none;
}

<a href="javascript:alert();">
    I am Batman!
</a>
-webkit-touch-callout
Audience Reacts to Steve Jobs Scrolling on an iPhone (2007)

-webkit-overflow-scrolling

.ios {
    -webkit-overflow-scrolling: touch;
    -webkit-overflow-scrolling: auto;
}
Momentum Scrolling on iOS Overflow Elements

«Липкий» скролл

body {
    scroll-snap-type: x mandatory;
}

section {
    height: 100vh;
    width: 100vw;
    scroll-snap-align: start;
}
Practical CSS Scroll Snapping

inputmode

<input type="text" inputmode="numeric" />
Everything You Ever Wanted to Know About inputmode
<input type="text" inputmode="tel" />
Everything You Ever Wanted to Know About inputmode
<input type="text" inputmode="email" />
Everything You Ever Wanted to Know About inputmode

3
Учитывать ограничения

Окружение

env()

env(safe-area-inset-top)
env(safe-area-inset-bottom)
env(safe-area-inset-left)
env(safe-area-inset-right)
Понимание вьюпорта WebView в iOS 11
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);
}

format-detection

<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="address=no">
<meta name="format-detection" content="date=no">
<meta name="format-detection" content="email=no">
How To Ban Blue Links on iOS Devices In Email
Loading web pages fast on a $20 feature phone
.disable-animation *,
.disable-animation *:before,
.disable-animation *:after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
}
Revisiting prefers-reduced-motion, the reduced motion media query

Шрифты

Preinstalled Fonts

Android

Default Fonts in Desktop & Mobile Operating Systems
Основы адаптивной типографики

CSS-шлюзы

h1 { font-size: 1.25rem; }

@media (min-width: 20em) {
    h1 {
        font-size: calc(1.25rem + 1.25 * (100vw - 20rem) / 40);
    }
}
@media (min-width: 60em) {
    h1 {
        font-size: calc(1.25rem + 1.25 * 1rem);
    }
}
Математика CSS-шлюзов

Визуальная часть

<style>
img {
    width: 100%;
    height: auto;
    aspect-ratio: attr(width) / attr(height);
}
</style>

<img src="hero_image.jpg"
     width="500"
     height="500">
Setting Height And Width On Images Is Important Again

44px — минимальный размер интерактивного элемента

UI Design Do’s and Don’ts
<head>
    <style>
        :root {
            --color-fg: #000;
            --color-bg: #fff;
        }
        @media (prefers-color-scheme: dark) {
            :root {
                --color-fg: #fff;
                --color-bg: #000;
            }
        }
    </style>
</head>
FOUDT: Flash of Unstyled Dark Theme
The ultimate guide to proper use of animation in UX

Закрепим

Touch First 📱

Отдавайте только нужное ⚖️

Используйте возможности ⚡️

Помните об ограничениях ☎️

Спасибо за внимание!

mefody.dev/talks/css-for-touch/
@dark_mefody
n.a.dubko@gmail.com