## Стили. Разработка под мобильные устройства
Слайды доступны по ссылке
frontend.tech-mail.ru

## Стили и CSS

## CSS is awesome

PLAY

## Сначала был... HTML

## CSS в здании

    		html {
    			font-size: 62.5%;
    			font-family: serif;
    		}
    		body {
    			font-size: 1.8rem;
    			line-height: 1.618;
    			max-width: 38em;
    			margin: auto;
    			color: #4a4a4a;
    			background-color: #f9f9f9;
    			padding: 13px;
    		}
    		h1, h2, h3, h4, h5, h6 {
    			line-height: 1.1;
    			font-family: Verdana, Geneva, sans-serif;
    			font-weight: 700;
    			overflow-wrap: break-word;
    			word-wrap: break-word;
    			word-break: break-word;
    			hyphens: auto;
    		}
    		...

## CSS для вёрстки

## Table Hell...

    		<table cellpadding="0" cellspacing="0" border="0">
    		    <tr>
    		        <td class="header" colspan="3" height="120px">....</td>
    		    </tr>
    		    <tr>
    		       <td class="menu" valign="top">...</td>
    		       <td class="content" valign="top">...</td>
    		       <td class="aSide" valign="top">...</td>
    		    </tr>
    		    <tr>
    		        <td class="footer" colspan="3">...</td>
    		    </tr>
    		</table>

## Мухи отдельно, котлеты отдельно...

## Float

## "Обтекаемость" изображений
в тексте

## Вёрстка макета страницы на
основе float

Пример

    				body {
    					padding-left: 200px;
    					padding-right: 190px;
    					min-width: 240px;
    				}
    				header, footer {
    					margin-left: -200px;
    					margin-right: -190px;
    				}
    				main, nav, aside {
    					position: relative;
    					float: left;
    				}
    				main {
    					padding: 0 20px;
    					width: 100%;
    				}
    				aside {
    					width: 130px;
    					padding: 0 10px;
    					margin-right: -100%;
    				}
    				footer {
    					clear: both;
    				}

## No Escape

## Flexbox layout

## Flexbox

    		.container-flex {
    		    display: flex;
    		    flex-direction: column;
    		    justify-content: space-between;
    		}

A Complete Guide to Flexbox

## Вёрстка макета страницы на
основе flex

Пример

    				body {
    					min-height: 100vh;
    					display: flex;
    					flex-direction: column;
    				}
    				.container {
    					display: flex;
    					flex: 1;
    				}
    				main {
    					flex: 1;
    					padding: 0 20px;
    				}
    				nav {
    					flex: 0 0 180px;
    					padding: 0 10px;
    					order: -1;
    				}
    				aside {
    					flex: 0 0 130px;
    					padding: 0 10px;
    				}

## Grid layout

## Вёрстка макета страницы на
основе Grid Layout

Пример

    				body {
    					display: grid;
    					min-height: 100vh;
    					grid-template-columns: 200px 1fr 150px;
    					grid-template-rows: min-content 1fr min-content;
    				}
    				header {
    					grid-row: 1;
    					grid-column: 1 / 4;
    				}
    				nav {
    					grid-row: 2;
    					grid-column: 1 / 2;
    					padding: 0 10px;
    				}
    				main {
    					grid-row: 2;
    					grid-column: 2 / 3;
    					padding: 0 20px;
    				}
    				aside {
    					grid-row: 2;
    					grid-column: 3 / 4;
    					padding: 0 10px;
    				}
    				footer {
    					grid-row: 3;
    					grid-column: 1 / 4;
    				}

## grid-column

## Современный CSS

## CSS-фильтры

    					.image {
    					    filter: value;
    					}

## CSS-фильтры

    					.image {
    					    filter: blur(5px);
    					}

## CSS-фильтры

    					.image {
    					    filter: brightness(0.5);
    					}

## CSS-фильтры

    					.image {
    					    filter: contrast(200%);
    					}

## CSS-фильтры

    					.image {
    					    filter: saturate(400%);
    					}

## CSS-фильтры

    					.image {
    					    filter: drop-shadow(16px 16px 10px black)
    					            grayscale(100%);
    					}

## CSS-транзиции

    					.box {
    					    transition-property: transform
    					                         background-color;
    					    transition-duration: 1s;
    					    transition-timing-function: ease;
    					}
    					.box:hover {
    					    transform: scale(2.5) rotate(180deg)
    					    background-color: palevioletred;
    					}

## CSS-анимации

    		@keyframes colors {
    		    from {
    		        background-color: green;
    		    }
    		    to {
    		        background-color: palevioletred;
    		        transform: scale(1.5);
    		    }
    		}

## CSS-анимации

    		.box {
    		    animation-name: colors;
    		    animation-duration: 2s;
    		    animation-direction: alternate;
    		    animation-iteration-count: infinite;
    		}

## CSS-анимации

## CSS Animations and Web Animations API

## 3D-трансформации

    		.box {
    		    transform-style: preserve-3d;
    		    transform: perspective(900px);
    		    transform: rotate3d(x, y, z, deg);
    		    transform: translate3d(x, y, z);

    		}

## 3D-трансформации

## CSS-variables

    			:root {
    			    --my-color: #FFF;
    			}
    			.color-picker {
    			    box-shadow: 0 0 5em var(--my-color, white);
    			}

## CSS-variables from JS

    			// get value
    			document.documentElement.style
    			     .getPropertyValue('--my-color');

    			// set value
    			document.documentElement.style
    			     .setProperty('--my-color', 'green');
    			document.documentElement.style
    			     .setProperty('--my-color', 'var(--fancy-color)');

##

## CSS Houdini

Проект CSS Houdini

CSS Paint API example

## Even More CSS Secrets

## Окей, новый CSS — это 🔥

## Препроцессоры CSS

## Тысячи их!

- SASS/SCSS — Syntactically Awesome Stylesheets sass-scss.ru
- LESS — lesscss.org
- Stylus — stylus-lang.com

## SASS

    		$dark-color: #4a4a4a
    		$light-color: #f9f9f9
    		$side-color: #eee
    		body
    		  color: $dark-color

    		header, footer
    		  background-color: $dark-color
    		  color: $light-color

    		main
    		  background: $light-color
    		nav, aside
    		  background: $side-color

## LESS

    		@dark-color: #4a4a4a;
    		@light-color: #f9f9f9;
    		@side-color: #eee;
    		body {
    		  color: @dark-color;
    		}

    		header, footer {
    		  background-color: @dark-color;
    		  color: @light-color;
    		}

    		main {
    		  background: @light-color;
    		}
    		nav, aside {
    		  background: @side-color;
    		}

## SCSS

    		$font-stack:    Helvetica, sans-serif
    		$primary-color: #333

    		.login-form {
    		    color: $primary-color;
    		    &__input {
    		        font: 18px $font-stack;
    		        &:active {
    		            background-color: white;
    		        }
    		    }
    		}

## SCSS — миксины

    		@mixin border-radius($radius) {
    		  -webkit-border-radius: $radius;
    		     -moz-border-radius: $radius;
    		      -ms-border-radius: $radius;
    		          border-radius: $radius;
    		}

    		.button {
    		    @include border-radius(10px);
    		}

## PostCSS

## Использование PostCSS

    		// postcss.config.js
    		module.exports = {
    		    plugins: [
    		        require('precss')({/* ...options */}),
    		        require('autoprefixer')({/* ...options */}),
    		        ...
    		    ]
    		}

    		// main.js
    		import 'styles.css';

## CSS директивa @supports

    		@supports (display: flex) {
    		    div { display: flex; }
    		}

    		@supports not (display: flex) {
    		    div { float: left; } /* задан альтернативный стиль */
    		}

## CSS директивa @supports

    		@supports (display: -webkit-flex) or
    		          (display: -moz-flex) or
    		          (display: flex) {

    		    /* добавляем сюда ваших клёвых стилей */
    		}

    		// использование в JS
    		const supportsFlex1 = CSS.supports('display', 'flex');
    		const supportsFlex2 = CSS.supports('(display: flex)');

## Не забываем про методологии!

## Компонентный подход!

## CSS Modules

## Использование CSS Modules

    		/* button.css */
    		.button {
    		    width: 200px;
    		    height: 48px;
    		    border-radius: 12px;
    		}

    		.primary {
    		    background-color: green;
    		    font-weight: 500;
    		}

## Использование CSS Modules

    		// button.js
    		import styles from './button.css';

    		export default function renderButton (title, primary) {
    		    return `
    		        <button class="${styles.button} ${primary ? styles.primary : ''}">
    		            ${title}
    		        </button>
    		    `;
    		}

## Использование CSS Modules

    		// main.js
    		import renderButton from './button.js';

    		document.body.innerHTML = `
    		    ${renderButton('Вжух!', true)}
    		    ${renderButton('Очистить')}
    		`;

## Использование CSS Modules

    		<!-- результирующий HTML -->

    		<button class="button-213ge1hw primary-jh4gd318">
    		    Вжух!
    		</button>
    		<button class="button-213ge1hw">
    		    Очистить
    		</button>

## JSS

## Использование JSS

    		// main.js
    		import jss from 'jss';
    		import preset from 'jss-preset-default';
    		import color from 'color';

    		// One time setup with default plugins and settings
    		jss.setup(preset());
    		const styles = {
    		    button: {
    		        width: 200,
    		        background: color('blue').darken(0.3).hex(),
    		    },
    		};

## Использование JSS

    		// ...
    		const { classes } = jss.createStyleSheet(styles).attach();

    		document.body.innerHTML = `
    		    <button class="${classes.button}">
    		        Button
    		    </button>
    		`;

## Кто придумывает WEB?

## W3C — www.w3.org

> W3C (World Wide Web Consortium — Консорциум Всемирной паутины) — организация, разрабатывающая и внедряющая технологические стандарты для Всемирной паутины. Консорциум возглавляет Тимоти Джон Бернерс-Ли

Любой стандарт W3C проходит 5 стадий согласования:

- Черновик спецификации (Draft)
- Рабочий проект (Working Draft);
- Последний созыв (Last Call);
- Возможная рекомендация (Candidate Recommendation);
- Предлагаемая рекомендация (Proposed Recommendation);

и только после этого официально становится рекомендацией W3C

## WHATWG — whatwg.org

> WHATWG (Web Hypertext Application Technology Working Group) — сообщество людей, заинтересованных в развитии Интернета. Было основано в 2004 году производителями браузеров: Apple, Mozilla Foundation и Opera Software. Основным направлением сообщества является развитие HTML и API, необходимого для веб-приложений.

По сути, является форком W3C. WHATWG была недовольна медленными темпами развития стандартов и уклоном W3C в сторону HTML, основанного на XML-синтаксисе

Сейчас WHATWG активно разрабатывает спецификации: HTML, DOM Standard, Fetch Standard, Web workers, Storage Standard, Streams Standard...

## CSS — Cascading Style Sheets

CSS одна из широкого спектра технологий, одобренных консорциумом W3C и получивших общее название «стандарты Web»

wiki.csswg.org — рабочая группа CSS в рамках консорциума W3C

- CSS level 1 — декабрь 1996
- CSS level 2 — май 1998
- CSS level 3 — c июня 2012 ... (по сути, ещё не принята)

Все CSS-спецификации — www.w3.org/Style/CSS/specs.en.html

## CSS is awesome

CSS is awesome
CSS is awesome
CSS is awesome
CSS is awesome

## Кроссплатформенная разработка

## Статистика по платформам от StatCounter

## Подходы к разработке под
мобильные устройства

- Отдельная мобильная версия
  - отдельный домен
  - серверный рендеринг
- Резиновый ( liquid ) дизайн
- Отзывчивый или адаптивный ( responsive ) дизайн
- Mobile-first подход
- Прогрессивные веб-приложения
  - graceful degradation
  - progressive enhancement

## Как определить возможности
устройства?

- Какой тип устройства (экран, телевизор, часы, микроволновка...)?
- Какая плотность пикселей?
- Какое разрешение у дисплея
- Какой размер устройства?
- Многое другое...

## Медиа-запросы (Media Queries)

> A `media query` is a method of testing certain aspects of the user agent or device that the document is being displayed in

    		@media screen and (max-width: 1900px) {
    		    .container {
    		        width: 70vw;
    		        max-width: 1200px;
    		    }
    		}

## Использование в CSS

    		@media screen and (color) { /* Для цветных экранов */
    		    body { background: whitesmoke; }
    		}

    		/* Для широкоформатных экранов */
    		@media screen and (min-device-aspect-ratio: 16/10) {
    		    ...
    		}

## Использование в CSS

    		@media projection { /* проектор */ }
    		@media handheld { /* смартфоны и носимые устройства */ }
    		@media tv { /* телевизоры */ }
    		@media braille { /* устройства для слабовидящих */ }

    		@media (hover) { /* если на устройстве работает hover */ }

    		@media (pointer: coarse) { /* тачскрины (низкая точность) */ }
    		@media (pointer: fine) { /* мышь или стилус (высокая точность) */ }
    		@media (pointer: none) { /* нет курсора (и такое бывает!) */ }

## Использование в HTML

    		<link rel="stylesheet"
    		   <l media="all and (orientation : portrait)"
    		   <l href="portrait.css">

    		<link rel="stylesheet"
    		   <l media="all and (orientation : landscape)"
    		   <l href="landscape.css">

## Единицы измерения длины CSS

## Единицы измерения CSS
подробнее

Относительные

- `em` — font size of the element
- `ex` — x-height of the element’s font
- `ch` — width of the "0" (ZERO, U+0030) glyph in the element’s font
- `rem` — font size of the root element
- `vw` — 1% of viewport’s width
- `vh` — 1% of viewport’s height
- `vmin` — 1% of viewport’s smaller dimension
- `vmax` — 1% of viewport’s larger dimension
- `%` — size as relative to an element's parent object
- `fr` — represents a fraction of the leftover space in the grid container

## Единицы измерения CSS
подробнее

Абсолютные

- `cm` — 1cm = 96px/2.54
- `mm` — 1mm = 1/10th of 1cm
- `Q` — 1q = 1/40th of 1cm
- `in` — 1in = 2.54cm = 96px
- `pc` — 1pc = 1/6th of 1in
- `pt` — 1pt = 1/72th of 1in
- `px` — 1px = 1/96th of 1in (со звёздочкой)

## Типы пикселей — подробнее

- Аппаратные пиксели — физический пиксель матрицы дисплея
- Аппаратно-независимые пиксели (Device-independent pixels, dip) — пиксели дисплея, приведённые к единому масштабу, чтобы соответствовать примерно одинаковому углу зрения на всех девайсах (с учётом расстояния, на котором мы их держим)
- Пиксель CSS — единица измерения вёрстки

## Пиксели? Пиксели!

## HTML-тег <picture>

    		<picture>
    				<source
    					srcset="<список URL c дескрипторами>"
    					[sizes="<ваши размеры в зависимости от раскладки>"]
    					[media="<медиавыражение>"]
    					[type="<mime/type>"]
    				>
    				<source ...>
    				<img src="image.jpg" alt="My image"
    		</picture>

## HTML-тег <picture>

    		<img
    				src="images/400.jpg"
    				srcset=" 400w, images/800.jpg 800w, images/1200.jpg 1200w"
    				sizes="(min-width: 700px) 75vw, 100vw"
    		>

Retina

    		<img
    				src="images/400.jpg"
    				srcset="images/800.jpg 2x, images/1200.jpg 3x"
    				width="400" height="300"
    		>

## HTML-тег <picture>

    		<picture>
    				<source
    					media="(min-width: 900px)"
    					srcset="images/original.jpg 1200w"
    					sizes="100vw"
    				>
    				<source
    					media="(min-width: 700px)
    					srcset="images/800crop.jpg 800w"
    					sizes="100vw"
    				>
    				<source ...>
    				<img srcset="images/400crop.jpg 400w" sizes="100vw">
    		</picture>

## Адаптивность?

Увеличивается в зависимости от media query

    		h1 { font-size: 14px; }
    		@media (min-width: 320px) {
    			h1 { font-size: 20px }
    		}
    		@media (min-width: 960px) {
    		  h1 { font-size: 40px; }
    		}

Увеличивается в зависимости от размера экрана

    		h1 { font-size: calc(14px + 5vw); }

## CSS-locks (или CSS-шлюзы)

    		h1 { font-size: 20px; }
    		@media (min-width: 320px) {
    			h1 { font-size: calc( 3.125vw + 10px ); }
    		}
    		@media (min-width: 960px) {
    		  h1 { font-size: 40px; }
    		}

CSS шлюзы пример
CSS шлюзы еще пример
CSS шлюзы и еще пример

## Функция clamp()

При помощи этой функции можно реализовать CSS шлюз встроенными средствами языка.

    			clamp(min, value, max)

    			/* Статические значения */
    			width: clamp(200px, 40%,  400px);
    			width: clamp(20rem, 30vw, 70rem);
    			width: clamp(10vw,  20em, 100vw);

    			/* Вычисляемые значения */
    			width: clamp(min(10vw, 20rem), 300px, max(90vw, 55rem));
    			width: clamp(100px, calc(30% / 2rem + 10px), 900px);

Развернутая документация на MDN

## Математика CSS-шлюзов

## Область просмотра (viewport)

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

- width — ширина области просмотра
- height — высота области просмотра
- initial-scale — начальный масштаб страницы
- minimum-scale — минимальный масштаб страницы
- maximum-scale — максимальный масштаб страницы
- user-scalable — возможность масштабировать страницу

Развернутая документация на MDN

## CSS-правило @viewport

    		@viewport {
    		     width: device-width;
    		     height: device-height;
    		     zoom: 2;
    		     user-zoom: fixed;
    		}

Это правило считается устаревшим. Тем не менее, иногда может встречаться в коде.
Развернутая документация на MDN

## Оптимизация графики для Retina-экранов

## Нативное взаимодействие

Проблемы:

- Зоопарк событий
- 300-ms задержка
- Нет нужных событий

## Проблема: зоопарк событий

События mouse-events:

- mousedown
- mouseup
- mouseover
- mousemove
- mouseout
- click
- dblclick
- contextmenu

## Проблема: зоопарк событий

События touch-events:

- touchstart
- touchmove
- touchcancel
- touchend

## Проблема: зоопарк событий

События pointer-events:

- pointerdown
- pointerup
- pointercancel
- pointermove
- pointerover
- pointerout
- gotpointercapture
- lostpointercapture

## pointer-events

## Проблема: 300-ms задержка

Между событием touchend и click проходит 300-350ms

    		html {
    		    touch-action: manipulation;
    		    touch-action: auto;
    		    touch-action: pan-y; /* pan-x */
    		    touch-action: pinch-zoom;
    		}

## Проблема: нет нужных событий

- pan
- swipe
- rotate
- pinch/zoom
- doubletap

## Проблема: нет нужных событий

    		// HammerJS - http://hammerjs.github.io/
    		const hammertime = new Hammer(element, options);
    		hammertime.on('swipe', function(event) {
    		    console.log(event);
    		});

## Accessibility — тред на Habr

## ARIA — Accessible Rich Internet
Applications — MDN

    		<!-- роли ARIA -->
    		<header role="banner">
    		<div role="alert">Алерт!</div>

    		<!-- атрибуты ARIA -->
    		<input type="radio" aria-checked="true">
    		<button aria-hidden="true" style="display: none;">
    		    Эта кнопка скрыта
    		</button>

## Семантика для циников, Вадим Макеев

## What Makes a Good Mobile Site?

## Mobile Web App Checklist

## Что ещё?

## Web App Manifest

Progressive Web App

    		<link rel=manifest href="/manifest.json">

## Web App Manifest

    		{
    		    "name": "Calculator",
    		    "short_name": "Calc",
    		    "lang": "ru-RU",
    		    "start_url": "/index.html",
    		    "display": "fullscreen", // standalone, minimal-ui, browser
    		    "orientation": "landscape", // portrait, any
    		    "background_color": "#0F0848",
    		    "theme_color": "#0F0848",
    		    "related_applications": [ ... ]
    		    "prefer_related_applications": false
    		    "icons": [ ... ]
    		}

## Web App Manifest

    		{
    		    "icons": [ {
    		            "src": "/imgs/icon-16.png",
    		            "type": "image/png",
    		            "sizes": "16x16"
    		        }, {
    		            "src": "/imgs/icon-24.png",
    		            "type": "image/png",
    		            "sizes": "24x24"
    		        } ]
    		}

## Add to Home Screen (A2HS)

## Apple meta-tags

    		<link rel=apple-touch-icon href="/imgs/icon-152.png">
    		<meta name=theme-color content=#0F0848>

    		<meta name=application-name content="Calc">
    		<meta name=apple-mobile-web-app-title content="Calc">

    		<meta name=mobile-web-app-capable content=yes>
    		<meta name=apple-mobile-web-app-capable content=yes>
    		<meta name=apple-mobile-web-app-status-bar-style content=#0F0848>

Apple Meta Tags Insanity

## Полезные ссылки

- Семантика для циников, Вадим Макеев
- Полное руководство по Flexbox
- Гриды и доклад Вадима Макеева по гридам
- 3D-трансформации средствами CSS
- Использование CSS-переменных
- Доклад Вадима Макеева про CSS
- Доклад Вадима Макеева про пиксели
- Пол-пикселя?
- CSS Evolution

## Всем спасибо!