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

Павел Ловцевич, LOVATA

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

Павел Ловцевич, LOVATA

Павел Ловцевич

Павел Ловцевич

CTO @ LOVATA
@zigzag_mcquack
p.lovtsevich@lovata.com

LOVATA

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

Результаты опроса использования возможностей CSS-препроцессоров

Преимущества переменных

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

Карен Менезес, Variables: The Backbone Of CSS Architecture

Переменные. Когда и какие?

Условие

18 лет!

Runtime
DOM
Cascading

Синтаксис

Свойство

			--variable: value;
		

Синтаксис

Свойство

			--variable: 💩💩💩;
		

Функция

				var(--variable);
			

Синтаксис

Свойство

			--variable: @#$%&!;
		

Функция

			background: var(--variable);
		

Синтаксис

Свойство

			--variable: 10px;
		

Функция

			background: var(--variable);
		

Синтаксис

Свойство

			--variable: 10px;
		

Функция

			background: trasparent;
		
CSS Custom Properties Browser Support

PostCSS CSS Variables

			:root {
				--variable: value;
			}
			selector {
				property: value; /* fallback */
				property: var(--variable); /* runtime */
			
			}
		
The status of CSS Variables in Microsoft Edge

Scope

Scope

				:root {
					--variable: value;
				}
			

Scope

			selector {
				--variable: value;
			}
		

Scope

Shadow DOM v1

				:host {
					--variable: value;
				}
			

$foo

Custom Property

Variable

$foo

$foo

Если бы мы использовали символ "$" для переменных, то не смогли бы его использовать для будущих новых более мощных сущностей, подобных на переменные.

Таб Аткинс, Let's Talk about CSS Variables

$foo

--property

				-webkit-property
				-moz-property
				-ms-property
				-o-property
			

var()

				url()
				rgb()
				calc()
				attr()
			

@media

@media

Gutter

@media

Gutter

@media

				:root {
					--gutter: 1rem;
				}
				.сontainer {
					margin: var(--gutter);
				}
				
			

@media (SASS)

			$gutter: 1rem;
				
			.сontainer {
				margin: $gutter;
			}
				
			@media (min-width: 1200px) {
				$gutter: 2rem;
			}

		

@media (SASS)

			$gutter: 1rem;
				
			.сontainer {
				margin: $gutter;
			}
				
			@media (min-width: 1200px) {
				$gutter: 2rem;
			}

		

@media (SASS)

Inheritance

Inheritance

Button

Inheritance

Button

Inheritance

			:root {
				--color: black;
			}
			button {
				background: var(--color);
			}
			
		

Inheritance

				:root {
					--color: black;
				}
				selector {
					background: var(--color);
				}
				
			

Inheritance

				* {
					--color: initial;
				}
			
				:root {
					--color: black;
				}
			
				selector {
					--color: black;
				}
			

Каскад?
Это шутка?

SOLID O

Программные сущности (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для изменения.

Бертран Мейер

SOLID O

Плохо

				.button {
					background: black;
				}
					
				.black-box .button {
					background: white;
				}
			

Хорошо

				.button {
					background: var(--color,
					black);
				}
				.black-box {
					--color: white;
				}
			

SOLID O

Плохо

				.button {
					background: black;
				}
					
				.black-box .button {
					background: white;
				}
			

Хорошо

				.button {
					background: var(--color,
					black);
				}
				.black-box {
					--color: white;
				}
			

SOLID O

Плохо

				.button {
					background: black;
				}
					
				.black-box .button {
					background: white;
				}
			

Хорошо

				.button {
					background: var(--color,
					black);
				}
				.black-box {
					--color: white;
				}
			

SOLID O

Плохо

				.button {
					background: black;
				}
					
				.black-box .button {
					background: white;
				}
			

Хорошо

				.button {
					background: var(--color,
					black);
				}
				.black-box {
					--color: white;
				}
			

SOLID O

Плохо

				.button {
					background: black;
				}
					
				.black-box .button {
					background: white;
				}
			

Хорошо

				.button {
					background: var(--color,
					black);
				}
				.black-box {
					--color: white;
				}
			

SOLID O

Плохо

				.button {
					background: black;
				}
					
				.black-box .button {
					background: white;
				}
			

Хорошо

				.button {
					background: var(--color,
					black);
				}
				.black-box {
					--color: white;
				}
			

Fallback

Fallback

			:root {
				--color:;
			}
				
			.button {
				background: var(--color, black);
			}
		

Fallback

				:root {
					--color:;
					--color-default: black;
				}
					
				.button {
					background: var(--color, var(--color-default));
				}
			

Fallback

				:root {
					--color:;
					--color-default: black;
					
				}
				.button {
					background: var(--color, var(--color-default));
				}
			

Fallback

				:root {
					--color: ;
					--color-default: black;
					
				}
				.button {
					background: var(--color, var(--color-default));
				}
			

Fallback

				:root {
					--color: initial;
					--color-default: black;
					
				}
				.button {
					background: var(--color, var(--color-default));
				}
			

Fallback

				:root {
					--color: var(--color-custom, black);
					--color-custom: initial;
					
				}
				.button {
					background: var(--color);
				}
			

I18n

“en”
«ru»

I18n

			<html lang="ru">
			
				<body>
					<q>Чебурашка</q>
				</body>
			</html>
		

I18n

			<html lang="ru">
			
				<body>
					<q>Чебурашка</q>
				</body>
			</html>
		

I18n

			:root:lang(en) {
			  --quotes-l: "“"; --quotes-r: "”";
			}
			q {
				quotes: var(--quotes-l, "«")
						var(--quotes-r, "»");
			}
		

I18n

			:root:lang(en) {
			  --quotes-l: ""; --quotes-r: "";
			}
			q {
				quotes: var(--quotes-l, "«")
						var(--quotes-r, "»");
			}
		

calc()

calc()

			:root {
				--line-height: 1.5;
				--paragraph-margin: calc(var(--line-height) * 2);
			}
				
			p {
				margin-bottom: calc(var(--paragraph-margin, 0) * 1px);
			}
		

calc()

			:root {
				--line-height: 1.5;
				--paragraph-margin: calc(var(--line-height) * 2);
			}
				
			p {
				margin-bottom: calc(var(--paragraph-margin, 0) * 1px);
			}
		

calc()

			:root {
				--line-height: 1.5;
				--paragraph-margin: calc(var(--line-height) * 2);
			}
				
			p {
				margin-bottom: calc(var(--paragraph-margin, 0) * 1px);
			}
		

<SVG>

<SVG>

			<svg height="100" width="100">
				<style>
					:root {
						--color: black;
					}
				</style>
				<circle cx="50" cy="50" r="50" fill="var(--color)" />
			</svg>
		

<SVG>

CSS

			:root {
				--color: black;
			}
		

SVG

			<svg height="100" width="100">
				<circle cx="50" cy="50" r="50" fill="var(--color)" />
			</svg>
		

JavaScript

API CSSStyleDeclaration

Получаем

			getComputedStyle(document.documentElement)
			.getPropertyValue('--variable');
		

Назначаем

			element.style.setProperty('--variable', 'value');
		

Удаляем

			element.style.removeProperty('--variable');
		

API CSSStyleDeclaration

See the Pen css variables by Daniel David (@danield770) on CodePen.

@supports

@supports

			@supports (--a: 0) {
				/* Progressive Enhancement */
			}
		

@supports

			@supports not (--a: 0) {
				/* Graceful Degradation */
			}
		

CSS.supports

CSS.supports

			if (window.CSS && window.CSS.supports && 
			window.CSS.supports('--a', 0)) {
				// сценарии с поддержкой переменных
			} else {
				// сценарии без поддержки переменных
			}
		

Рекомендации

И еще…

Thx Tab!

Tab Atkins

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

Вопросы?

Fork me on GitHub