Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Пользовательские свойства как основа архитектуры CSS

Пользовательские свойства как основа архитектуры CSS

Массовая имплементация пользовательских свойств CSS в большинстве популярных браузеров открыла простор для творчества и экспериментов над архитектурой CSS-кода, недостижимой ранее.

- Всесильны ли препроцессоры?
- Можно ли дать CSS второй шанс?
- Наследуемость или БЭМ?
- А что с обратной совместимостью? Решение есть!

В рамках доклада будут детально рассмотрены практические примеры применения CSS Custom Properties. Также будут рассмотрены новые спецификации CSS Extensions (Сustom selectors) и CSS @apply Rule в рамках перспективы отказа от препроцессоров.

Pavel Lautsevich

May 31, 2016
Tweet

More Decks by Pavel Lautsevich

Other Decks in Programming

Transcript

  1. Преимущества переменных Переменные — основа современного правильно сконструированного проекта. Карен

    Менезес, Variables: The Backbone Of CSS Architecture • Модульность. • Уменьшение повторяемости. • Сокращение объема. • Повышение читаемости. • Стайлгайд. “
  2. Переменные. Когда и какие? Условие • Значение встречается в коде

    два и более раз. • Значение в будущем может изменяться. Тип • Измерения (размеры, отступы, радиусы скругления и т.п.). • Цветовые схемы. • Типографика. • Наборы иконок. • Брейкпойнты.
  3. Переменные в CSS • 2008 — первая реализация в Safari.

    • 2012 — CSS Variables Module Level 1. • 2013 — CSS Custom Properties for Cascading Variables Module Level 1. • 2014 — первая реализация по спецификации в Chrome и Firefox. • 2015 — W3C Candidate Recommendation. • 2016 — массовое внедрение в браузерах.
  4. Преимущества переменных CSS • Работают в runtime и доступны для

    чтения и изменения. • Существуют в DOM'е и ограничены областью видимости узла. • Наследуются до последнего потомка узла DOM!
  5. Переменные Пользовательские свойства CSS Пользователькое свойство Особая разновидность свойств CSS

    с префиксом -- , объявляющим имя переменной, и заданным значением. --Variable: value; Переменная Функция CSS, связывающая идентификатор -- variable и его значение. var(--Variable);
  6. V V Переменные Пользовательские свойства CSS Пользователькое свойство Особая разновидность

    свойств CSS с префиксом -- , объявляющим имя переменной, и заданным значением. -- ariable: value; Переменная Функция CSS, связывающая идентификатор -- variable и его значение. var(-- ariable);
  7. html { } Область видимости SASS $variable: value; CSS :root

    { --variable: value; } Альтернативная запись: --variable: value; 01. 02. 03. 01. 02. 03. 01. 02. 03.
  8. ; !global Область видимости SASS $variable: value; Глобальная из локальной:

    selector { $variable: value } CSS :root { --variable: value; } Альтернативная запись: html { --variable: value; } 01. 02. 03. 01. 02. 03. 04. 01. 02. 03. 01. 02. 03.
  9. Ограничение области видимости SASS selector { $variable: value; } CSS

    selector { --variable: value; } А также: • вложенный селектор; • @mixin. А также: • псевдокласс; • @media. 01. 02. 03. 01. 02. 03.
  10. Синтаксис SASS Объявление: $variable: value; Вызов: selector { property: $variable;

    } CSS Объявление: :root { --variable: value; } Вызов: selector { property: var(--variable); } 01. 02. 03. 01. 02. 03. 01. 02. 03. 01. 02. 03.
  11. $variable: value; selector { property: $variable; } Голосуем за вариант

    SASS SASS Объявление: Вызов: CSS Объявление: :root { --variable: value; } Вызов: selector { property: var(--variable); } 01. 02. 03. 01. 02. 03. 01. 02. 03. 01. 02. 03.
  12. :root { --variable: value; } selector { property: var(--variable); }

    Голосуем за вариант CSS SASS Объявление: $variable: value; Вызов: selector { property: $variable; } CSS Объявление: Вызов: 01. 02. 03. 01. 02. 03. 01. 02. 03. 01. 02. 03.
  13. Причины выбранного синтаксиса Если бы мы использовали символ "$" для

    переменных, то не смогли бы его использовать для будущих новых вещей, подобных на переменные. Таб Аткинс, Let's Talk about CSS Variables На самом деле: • совместимость с препроцессорами; • нативные "грамматика" и "пунктуация" CSS. “
  14. all-in-one.css Один большой CSS HTML <head> <link rel="stylesheet" href=" ">

    </head> <body> <div class="block">…</> … </body> 01. 02. 03. 04. 05. 06. 07.
  15. Много мелких CSS HTML <head> <link rel="stylesheet" href="main.css"> <link rel="stylesheet"

    href="block.css"> … </head> <body> <div class="block">…</> … </body> 01. 02. 03. 04. 05. 06. 07. 08. 09.
  16. main.css Много мелких CSS HTML <head> <link rel="stylesheet" href=" ">

    <link rel="stylesheet" href="block.css"> … </head> <body> <div class="block">…</> … </body> 01. 02. 03. 04. 05. 06. 07. 08. 09.
  17. block.css Много мелких CSS HTML <head> <link rel="stylesheet" href="main.css"> <link

    rel="stylesheet" href=" "> … </head> <body> <div class="block">…</> … </body> 01. 02. 03. 04. 05. 06. 07. 08. 09.
  18. block.css Много мелких CSS HTML <head> <link rel="stylesheet" href="main.css"> …

    </head> <body> <link rel="stylesheet" href=" "> <div class="block">…</> … </body> 01. 02. 03. 04. 05. 06. 07. 08. 09.
  19. Блокировка отображения HTML <head> <link rel="stylesheet" href="main.css"> </head> main.css :root

    { --block-display: none; } .block { display: var(--block-display); } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05. 06. 07.
  20. main.css Блокировка отображения HTML <head> <link rel="stylesheet" href=" "> </head>

    main.css :root { --block-display: none; } .block { display: var(--block-display); } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05. 06. 07.
  21. none display Блокировка отображения HTML <head> <link rel="stylesheet" href="main.css"> </head>

    main.css :root { --block-display: ; } .block { : var(--block-display); } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05. 06. 07.
  22. block.css Снятие блокировки HTML <body> <link rel="stylesheet" href=" "> <div

    class="block"> …</div> </body> block.css .block { --block-display: block; } 01. 02. 03. 04. 05. 06. 07. 01. 02. 03.
  23. block Снятие блокировки HTML <body> <link rel="stylesheet" href="block.css"> <div class="block">

    …</div> </body> block.css .block { --block-display: ; } 01. 02. 03. 04. 05. 06. 07. 01. 02. 03.
  24. Переменные в @media CSS :root { --gutter: 1em; } .сontainer

    { padding: var(--gutter); } CSS глазами браузера 01. 02. 03. 04. 05. 06.
  25. 1em 2em Переменные в @media CSS :root { --gutter: ;

    } .сontainer { padding: var(--gutter); } @media (min-width: 1200px) { :root { --gutter: ; } } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09.
  26. 1em 2em 1em 2em Переменные в @media CSS :root {

    --gutter: ; } .сontainer { padding: var(--gutter); } @media (min-width: 1200px) { :root { --gutter: ; } } CSS глазами браузера .сontainer { padding: ; } @media (min-width: 1200px) { .сontainer { padding: ; } } 01. 02. 03. 04. 05. 06. 07. 08. 09. 01. 02. 03. 04. 05. 06. 07. 08. 09.
  27. 1em Переменные в @media (SASS) SASS $gutter: 1em; .сontainer {

    padding: $gutter; } @media (min-width: 1200px) { $gutter: 2em; } CSS .сontainer { padding: ; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 01. 02. 03.
  28. @media (min-width: 1200px) { $gutter: 2em; } 1em Переменные в

    @media (SASS) SASS $gutter: 1em; .сontainer { padding: $gutter; } CSS .сontainer { padding: ; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 01. 02. 03.
  29. button Наследование переменных CSS :root { --main-color: black; } {

    background: var(--main-color); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07.
  30. black white black white Наследование переменных CSS :root { --main-color:

    ; } button { background: var(--main-color); } .black-box { --main-color: ; } CSS глазами браузера button { background: ; } .black-box button { background: ; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 01. 02. 03. 04. 05. 06. 07.
  31. Принцип открытости/закрытости Программные сущности (классы, модули, функции и т.д.) должны

    быть открыты для расширения, но закрыты для изменения. Плохо .button { background: black; } .header .button { background: white; } Хорошо .button { background: var(--main-color, black); } .header { --main-color: white; } 01. 02. 03. 04. 05. 06. 07. 01. 02. 03. 04. 05. 06. 07.
  32. black Принцип открытости/закрытости Программные сущности (классы, модули, функции и т.д.)

    должны быть открыты для расширения, но закрыты для изменения. Плохо .button { background: black; } .header .button { background: white; } Хорошо .button { background: var(--main-color, ); } .header { --main-color: white; } 01. 02. 03. 04. 05. 06. 07. 01. 02. 03. 04. 05. 06. 07.
  33. .header { --main-color: white; } Принцип открытости/закрытости Программные сущности (классы,

    модули, функции и т.д.) должны быть открыты для расширения, но закрыты для изменения. Плохо .button { background: black; } .header .button { background: white; } Хорошо .button { background: var(--main-color, black); } 01. 02. 03. 04. 05. 06. 07. 01. 02. 03. 04. 05. 06. 07.
  34. Локальный fallback CSS :root { --main-color: initial; } button {

    background: var(--main-color, green); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08.
  35. initial Локальный fallback CSS :root { --main-color: ; } button

    { background: var(--main-color, green); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08.
  36. green green Локальный fallback CSS :root { --main-color: initial; }

    button { background: var(--main-color, ); } CSS глазами браузера button { background: ; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03.
  37. red red Локальный fallback CSS :root { --main-color: ; }

    button { background: var(--main-color, green); } CSS глазами браузера button { background: ; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03.
  38. Глобальный fallback CSS :root { --main-color: var(--main-color-custom, green); --main-color-custom: initial;

    } button { background: var(--main-color); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  39. --main-color Глобальный fallback CSS :root { : var(--main-color-custom, green); --main-color-custom:

    initial; } button { background: var(--main-color); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  40. --main-color-custom Глобальный fallback CSS :root { --main-color: var(--main-color-custom, green); :

    initial; } button { background: var(--main-color); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  41. --main-color-custom --main-color-custom Глобальный fallback CSS :root { --main-color: var( ,

    green); : initial; } button { background: var(--main-color); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  42. green Глобальный fallback CSS :root { --main-color: var(--main-color-custom, ); --main-color-custom:

    initial; } button { background: var(--main-color); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  43. green green Глобальный fallback CSS :root { --main-color: var(--main-color-custom, );

    --main-color-custom: initial; } button { background: var(--main-color); } CSS глазами браузера button { background: ; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 01. 02. 03.
  44. red red Глобальный fallback CSS :root { --main-color: var(--main-color-custom, green);

    --main-color-custom: ; } button { background: var(--main-color); } CSS глазами браузера button { background: ; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 01. 02. 03.
  45. Fallback в SASS SASS $color: null; $color: green !default; button

    { background: $color; } CSS 01. 02. 03. 04. 05. 06.
  46. $color $color Fallback в SASS SASS : null; : green

    !default; button { background: $color; } CSS 01. 02. 03. 04. 05. 06.
  47. null Fallback в SASS SASS $color: ; $color: green !default;

    button { background: $color; } CSS 01. 02. 03. 04. 05. 06.
  48. !default Fallback в SASS SASS $color: null; $color: green ;

    button { background: $color; } CSS 01. 02. 03. 04. 05. 06.
  49. green green Fallback в SASS SASS $color: null; $color: !default;

    button { background: $color; } CSS button { background: ; } 01. 02. 03. 04. 05. 06. 01. 02. 03.
  50. red red Fallback в SASS SASS $color: ; $color: green

    !default; button { background: $color; } CSS button { background: ; } 01. 02. 03. 04. 05. 06. 01. 02. 03.
  51. « » “ ” I18n HTML <html lang="ru"> <body> <q>Чебурашка</q>

    </body> </html> CSS q { quotes: var(--quotes-l) var(--quotes-r); } :root:lang(ru) { --quotes-l: " "; --quotes-r: " "; } :root:lang(en) { --quotes-l: " "; --quotes-r: " "; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  52. ru « » « » I18n HTML <html lang=" ">

    <body> <q>Чебурашка</q> </body> </html> Результат Чебурашка CSS q { quotes: var(--quotes-l) var(--quotes-r); } :root:lang(ru) { --quotes-l: " "; --quotes-r: " "; } :root:lang(en) { --quotes-l: "“"; --quotes-r: "”"; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  53. en “ ” “ ” I18n HTML <html lang=" ">

    <body> <q>Чебурашка</q> </body> </html> Результат Чебурашка CSS q { quotes: var(--quotes-l) var(--quotes-r); } :root:lang(ru) { --quotes-l: "«"; --quotes-r: "»"; } :root:lang(en) { --quotes-l: " "; --quotes-r: " "; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10.
  54. Вычисляемые значения CSS :root { --line-height: 1.5; } p {

    margin-bottom: var(--line-height)rem; } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08.
  55. margin-bottom Вычисляемые значения CSS :root { --line-height: 1.5; } p

    { : var(--line-height)rem; } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08.
  56. --line-height: 1.5; Вычисляемые значения CSS :root { } p {

    margin-bottom: var(--line-height)rem; } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08.
  57. rem 1.5 rem Вычисляемые значения CSS :root { --line-height: 1.5;

    } p { margin-bottom: var(--line-height) ; } CSS глазами браузера p { margin-bottom: ; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03.
  58. Вычисляемые значения CSS :root { --line-height: 1.5; } p {

    margin-bottom: calc(var(--line-height) * 1rem); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09.
  59. var(--line-height) Вычисляемые значения CSS :root { --line-height: 1.5; } p

    { margin-bottom: calc( * 1rem); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09.
  60. 1rem Вычисляемые значения CSS :root { --line-height: 1.5; } p

    { margin-bottom: calc(var(--line-height) * ); } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07. 08. 09.
  61. 1rem 1rem Вычисляемые значения CSS :root { --line-height: 1.5; }

    p { margin-bottom: calc(var(--line-height) * ); } CSS глазами браузера p { margin-bottom: ; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 01. 02. 03.
  62. Цветовые схемы и SVG SVG <svg height="100" width="100"> <circle cx="50"

    cy="50" r="50" fill="red" /> </svg> 01. 02. 03. 04. 05.
  63. red Цветовые схемы и SVG SVG <svg height="100" width="100"> <circle

    cx="50" cy="50" r="50" fill=" " /> </svg> 01. 02. 03. 04. 05.
  64. --main-color --main-color Цветовые схемы и SVG SVG <svg height="100" width="100">

    <circle cx="50" cy="50" r="50" fill="var( )" /> </svg> CSS :root { : var(--main-color-custom, green); --main-color-custom: red; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05.
  65. green Цветовые схемы и SVG SVG <svg height="100" width="100"> <circle

    cx="50" cy="50" r="50" fill="var(--main-color)" /> </svg> CSS :root { --main-color: var(--main-color-custom, ); --main-color-custom: red; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05.
  66. --main-color-custom Цветовые схемы и SVG SVG <svg height="100" width="100"> <circle

    cx="50" cy="50" r="50" fill="var(--main-color)" /> </svg> CSS :root { --main-color: var(--main-color-custom, green); : red; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05.
  67. red red Цветовые схемы и SVG SVG глазами браузера <svg

    height="100" width="100"> <circle cx="50" cy="50" r="50" fill=" " /> </svg> CSS :root { --main-color: var(--main-color-custom, green); --main-color-custom: ; } 01. 02. 03. 04. 05. 01. 02. 03. 04. 05.
  68. get has set delete API CSSVariablesMap el.style.var. ('variable'); el.style.var. ('variable');

    el.style.var. ('variable', 'value'); el.style.var. ('variable'); 01. 02. 03. 04.
  69. Проверка поддержки в CSS CSS @supports (--a: 0) { /*

    стили с поддержкой переменных */ } @supports not (--a: 0) { /* стили без поддержки переменных */ } 01. 02. 03. 04. 05. 06. 07.
  70. @supports (--a: 0) { } Проверка поддержки в CSS CSS

    /* стили с поддержкой переменных */ @supports not (--a: 0) { /* стили без поддержки переменных */ } 01. 02. 03. 04. 05. 06. 07.
  71. @supports not (--a: 0) { } Проверка поддержки в CSS

    CSS @supports (--a: 0) { /* стили с поддержкой переменных */ } /* стили без поддержки переменных */ 01. 02. 03. 04. 05. 06. 07.
  72. Проверка поддержки в CSS CSS @supports (--a: 0) { /*

    стили с поддержкой переменных */ } @supports not (--a: 0) { /* стили без поддержки переменных */ } Не работает в IE! 01. 02. 03. 04. 05. 06. 07.
  73. Проверка поддержки в JS CSS if (window.CSS && window.CSS.supports &&

    window.CSS.supports('--a', 0)) { // сценарии с поддержкой переменных } else { // сценарии бех поддержки переменных } 01. 02. 03. 04. 05.
  74. Ограничения переменных CSS • нельзя использовать в: • в именах

    обычных свойств CSS: var(--side): 10px ; • в значениях медиа-запросов: @media screen and (min-width: var(--desktop- breakpoint) { } ; • в подстановке URL: url(var(--image-url)) ; • будьте осторожны с вычислениями calc() : • со сложными вычислениями в принципе; • в Chrome с умножением/делением дробных значений; • в Firefox с вычислениями внутри функций rgba() . • нельзя одномоментно cбрасывать значения всех переменных: --: initial .
  75. @apply CSS :root { --clearfix: { display: table; clear: both;

    content: ''; } } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07.
  76. :root { } @apply CSS --clearfix: { display: table; clear:

    both; content: ''; } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07.
  77. --clearfix @apply CSS :root { : { display: table; clear:

    both; content: ''; } } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07.
  78. display: table; clear: both; content: ''; @apply CSS :root {

    --clearfix: { } } CSS глазами браузера 01. 02. 03. 04. 05. 06. 07.
  79. @apply --clearfix; display: table; clear: both; content: ''; @apply CSS

    :root { --clearfix: { display: table; clear: both; content: ''; } } .box:after { } CSS глазами браузера .box:after { } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 01. 02. 03. 04. 05.
  80. @custom-selector CSS article h1 + p, article h2 + p,

    article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } CSS @custom-selector :--heading { expansion: h1, h2, h3, h4, h5, h6; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03. 04.
  81. @custom-selector @custom-selector CSS article h1 + p, article h2 +

    p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } CSS :--heading { expansion: h1, h2, h3, h4, h5, h6; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03. 04.
  82. :--heading @custom-selector CSS article h1 + p, article h2 +

    p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } CSS @custom-selector { expansion: h1, h2, h3, h4, h5, h6; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03. 04.
  83. expansion: h1, h2, h3, h4, h5, h6; @custom-selector CSS article

    h1 + p, article h2 + p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } CSS @custom-selector :--heading { } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03. 04.
  84. :--heading @custom-selector CSS article h1 + p, article h2 +

    p, article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } CSS @custom-selector :--heading { expansion: h1, h2, h3, h4, h5, h6; } article + p { margin-top: 0; } 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03. 04. 05. 06. 07. 08.
  85. @custom-selector CSS article h1 + p, article h2 + p,

    article h3 + p, article h4 + p, article h5 + p, article h6 + p { margin-top: 0; } CSS @custom-selector :--heading { expansion: h1, h2, h3, h4, h5, h6; } article :--heading + p { margin-top: 0; } Полифил PostCSS Custom Selectors. 01. 02. 03. 04. 05. 06. 07. 08. 01. 02. 03. 04. 05. 06. 07. 08.
  86. Подытоживая • Новые способы решения старых задач. • Решение невозможных

    для препроцессоров задач. • Расширение компонентов через наследование. • Широкая поддержка в браузерах. • Простой нативный способ взаимодействия с JS, SVG и т.п. • Начало конца эры препроцессоров :-P