[Веб-дизайн, Разработка веб-сайтов, CSS] Крутые трюки с переменными CSS
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Переменные в CSS (или custom properties, кому как удобнее) изначально задумывались для хранения повторяющихся свойств вроде цветовой палитры или шрифтов в одном месте. В препроцессорах работа с переменными куда более гибкая, но магия SASS/SCSS применима не всегда и не везде, и в реальном мире часто обходятся без них, что нередко ведёт к раздуванию и размазыванию кодовой базы по разным файлам и форматам. В этой статье мы рассмотрим несколько интересных хаков, которые позволяют построить на механизме custom properties вещи, кажущиеся невозможными без препроцессоров или вмешательства JS.
Избегаем повторного определения цветов
Определять темы в чистом CSS не самое приятное занятие: обычно переключение на тёмную палитру требует смены сразу многих цветов для многих элементов: фоны, текст, ссылки, кнопки и так далее. Исходные предпочтения пользователя получаются медиа-запросом prefers-color-scheme, внутри которого нужно расставить новые цвета для всех селекторов, что приводит к раздуванию:
:root {
--background: #fff;
--text-color: #000;
--link-color: #0089c7;
--primary-color: #165fb9;
/* ... */
}
@media (prefers-color-scheme: dark) {
:root {
--background: #1b1b1b;
--text-color: #eaeaea;
--link-color: #b76c10;
--primary-color: #8916b9;
/* и в том же духе на десятки строк в разных скоупах */
}
}
В CSS нет другого механизма для изменения переменных, но повторения всё же можно избежать с помощью дополнительных значений:
--background: var(--light, #fff) var(--dark, #1b1b1b);
Если использовать переменную --light со значением initial, а в --dark передать валидное, но неприменимое значение, то --background получит цвет #fff. Для этой ситуации у CSS такое значение есть, и это… пробел. Таким образом, для белой темы строка распарсится так:
--background: #fff ;
А для тёмной так:
--background: #1b1b1b);
Обратите внимание на пробелы, они не ломают синтаксис (что сбросило бы определение всей строки). Теперь осталось только вынести переключатель состояния в отдельные переменные:
:root {
/* --ON и --OFF заменяют двоичную переменную */
--ON: initial;
--OFF: ;
}
/* выбираем светлую тему по умолчанию */
.theme-default,
.theme-light {
--light: var(--ON);
--dark: var(--OFF);
}
.theme-dark {
--light: var(--OFF);
--dark: var(--ON);
}
/* медиа-запрос теперь нужен только для переключения */
@media (prefers-color-scheme: dark) {
.theme-default {
--light: var(--OFF);
--dark: var(--ON);
}
}
Теперь цветовые схемы можно определять в одном месте, выглядеть это будет так:
:root {
--background: var(--light, #fff) var(--dark, #1b1b1b);
--text-color: var(--light, #000) var(--dark, #eaeaea);
--link-color: var(--light, #0089c7) var(--dark, #b76c10);
--primary-color: var(--light, #165fb9) var(--dark, #8916b9);
/* ... */
}
Такой код менее нагляден по сравнению с классическим определением, но к нему легко привыкнуть, и он не только экономит кучу места, но и уменьшает шанс ошибиться при изменении.
Используем switch-case в языке без логики
Как мы помним, в CSS не существует явных условных операторов для управления состоянием кроме медиа-запросов. Но структура этого языка иногда подбрасывает возможности там, где их никто не планировал. Встречайте: switch-case на анимации!
Для свойства animation можно создавать любое количество ключевых кадров (@keyframes), которые можно использовать как постоянное хранилище состояния, если держать анимацию остановленной. Для каждого кадра нужно знать точную задержку, чтобы остановленная анимация показывала нужный момент, а не фиксировалась на первом кадре. Вот наглядный пример:
Извините, данный ресурс не поддреживается. :(
Разберём принцип работы:
- Анимация остановлена через animation-play-state: paused.
- Отрицательная задержка в animation-delay заставляет анимацию останавливаться на конкретном кадре (или между двумя определёнными кадрами, так работает градиент на первом ползунке). Значения на ползунке — от -100s до 0s.
- В animation-duration можно указать любое удобное число, но нужно помнить, что при проигрывании последнего кадра анимация выключается, поэтому максимальная длительность не должна совпадать по времени с последним определённым кадром (case). Поэтому в примере выше разброс ползунка 100 секунд при длительности 100.001s.
Бинарная логика на функции calc()
В первом трюке мы уже использовали переменные --ON --OFF вместо двоичной переменной. В custom properties можно хранить числовые значения, и с помощью вычислений разных параметров через calc() и clamp() можно получать 0 или 1 в самых разных сценариях (подробнее в этой статье). Довольно неудобно даже инвертировать значение явным присваиванием, как в примере выше, а пытаться строить на этом какую-то логику и вовсе кошмар. Хорошо, что основные логические операции можно выполнять прямо в объявлении переменных!
not
Тут всё просто, 1 — 0 = 1, 1 — 1 = 0
--not: calc(1 - var(--j))
and
Простое умножение:
0 * 0 = 0
1 * 0 = 0
0 * 1 = 0
1 * 1 = 0
--and: calc(var(--k)*var(--i))
nand
1 — and = инвертированный and
--nand: calc(1 - var(--k)*var(--i))
or
Если хотя бы один из операндов равен единице, or возвращает единицу:
k or i = (not k) nand (not i)
--or: calc(1 - (1 - var(--k))*(1 - var(--i)))
nor
Аналогично с nand, nor = 1 — or:
--nor: calc((1 - var(--k))*(1 - var(--i)))
xor
Возвращает единицу, если ровно один из операндов равен единице:
--xor: calc((var(--k) - var(--i))*(var(--k) - var(--i)))
Заключение
Имея на руках бинарную логику и условные операторы, в CSS можно реализовать кучу вещей, которые раньше казалось возможным делать только через грубое вмешательство со стороны JS. Но есть один нюанс — чем глубже в дебри, тем менее читаемым становится код и тем сложнее его писать и поддерживать. Поэтому список подобных трюков можно продолжать ещё очень долго, но большинство приёмов из него почти наверняка не пригодятся в реальном мире. Зато основные концепции вроде switch и or помогут обойтись красивым CSS-only решением там, где раньше это казалось невозможным.
Облачные серверы от Маклауда подходят для размещения веб-проектов любой сложности! Вы можете создать собственную конфигурацию сервера в течение минуты и менять эти параметры в любой момент через удобную панель управления.
Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!
оригинал
===========
Источник:
habr.com
===========
Похожие новости:
- [Настройка Linux, Open source, Системное администрирование, *nix] Почему стоит использовать exa вместо привычной консольной утилиты ls (перевод)
- [Разработка веб-сайтов] FrontEnd разработка в Docker
- [Разработка веб-сайтов, Open source, JavaScript, Node.JS] Создатель Node.js анонсирует замену — Deno (перевод)
- [Разработка веб-сайтов, PHP, Yii] История о модульном подходе в digital агентстве
- [Исследования и прогнозы в IT, Разработка под Windows, Софт] Какие изменения ждут разработчиков после выхода новой Windows 10X (перевод)
- [Разработка веб-сайтов, Управление разработкой, Микросервисы] История Учи.ру: от мини-монолитов до микросервисной архитектуры
- [Разработка веб-сайтов, JavaScript] Опыт разработки виджетов для сторонних сайтов
- [Firefox, CSS, Google Chrome] Как освободиться от Яндекс-дзена и прилипшей строки в поиске
- [Веб-дизайн, Интерфейсы] Найди меня, если сможешь
- [Разработка веб-сайтов, Тестирование IT-систем, PHP, Тестирование веб-сервисов] Юнит-тестирование на PHP в примерах (перевод)
Теги для поиска: #_vebdizajn (Веб-дизайн), #_razrabotka_vebsajtov (Разработка веб-сайтов), #_css, #_tsvetovye_shemy (цветовые схемы), #_css, #_switchcase, #_tsss (цсс), #_peremennye_css (переменные css), #_custom_properties, #_blog_kompanii_maklaud (
Блог компании Маклауд
), #_vebdizajn (
Веб-дизайн
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_css
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:45
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Переменные в CSS (или custom properties, кому как удобнее) изначально задумывались для хранения повторяющихся свойств вроде цветовой палитры или шрифтов в одном месте. В препроцессорах работа с переменными куда более гибкая, но магия SASS/SCSS применима не всегда и не везде, и в реальном мире часто обходятся без них, что нередко ведёт к раздуванию и размазыванию кодовой базы по разным файлам и форматам. В этой статье мы рассмотрим несколько интересных хаков, которые позволяют построить на механизме custom properties вещи, кажущиеся невозможными без препроцессоров или вмешательства JS. Избегаем повторного определения цветов Определять темы в чистом CSS не самое приятное занятие: обычно переключение на тёмную палитру требует смены сразу многих цветов для многих элементов: фоны, текст, ссылки, кнопки и так далее. Исходные предпочтения пользователя получаются медиа-запросом prefers-color-scheme, внутри которого нужно расставить новые цвета для всех селекторов, что приводит к раздуванию: :root {
--background: #fff; --text-color: #000; --link-color: #0089c7; --primary-color: #165fb9; /* ... */ } @media (prefers-color-scheme: dark) { :root { --background: #1b1b1b; --text-color: #eaeaea; --link-color: #b76c10; --primary-color: #8916b9; /* и в том же духе на десятки строк в разных скоупах */ } } В CSS нет другого механизма для изменения переменных, но повторения всё же можно избежать с помощью дополнительных значений: --background: var(--light, #fff) var(--dark, #1b1b1b);
Если использовать переменную --light со значением initial, а в --dark передать валидное, но неприменимое значение, то --background получит цвет #fff. Для этой ситуации у CSS такое значение есть, и это… пробел. Таким образом, для белой темы строка распарсится так: --background: #fff ;
А для тёмной так: --background: #1b1b1b);
Обратите внимание на пробелы, они не ломают синтаксис (что сбросило бы определение всей строки). Теперь осталось только вынести переключатель состояния в отдельные переменные: :root {
/* --ON и --OFF заменяют двоичную переменную */ --ON: initial; --OFF: ; } /* выбираем светлую тему по умолчанию */ .theme-default, .theme-light { --light: var(--ON); --dark: var(--OFF); } .theme-dark { --light: var(--OFF); --dark: var(--ON); } /* медиа-запрос теперь нужен только для переключения */ @media (prefers-color-scheme: dark) { .theme-default { --light: var(--OFF); --dark: var(--ON); } } Теперь цветовые схемы можно определять в одном месте, выглядеть это будет так: :root {
--background: var(--light, #fff) var(--dark, #1b1b1b); --text-color: var(--light, #000) var(--dark, #eaeaea); --link-color: var(--light, #0089c7) var(--dark, #b76c10); --primary-color: var(--light, #165fb9) var(--dark, #8916b9); /* ... */ } Такой код менее нагляден по сравнению с классическим определением, но к нему легко привыкнуть, и он не только экономит кучу места, но и уменьшает шанс ошибиться при изменении. Используем switch-case в языке без логики Как мы помним, в CSS не существует явных условных операторов для управления состоянием кроме медиа-запросов. Но структура этого языка иногда подбрасывает возможности там, где их никто не планировал. Встречайте: switch-case на анимации! Для свойства animation можно создавать любое количество ключевых кадров (@keyframes), которые можно использовать как постоянное хранилище состояния, если держать анимацию остановленной. Для каждого кадра нужно знать точную задержку, чтобы остановленная анимация показывала нужный момент, а не фиксировалась на первом кадре. Вот наглядный пример: Извините, данный ресурс не поддреживается. :( Разберём принцип работы:
Бинарная логика на функции calc() В первом трюке мы уже использовали переменные --ON --OFF вместо двоичной переменной. В custom properties можно хранить числовые значения, и с помощью вычислений разных параметров через calc() и clamp() можно получать 0 или 1 в самых разных сценариях (подробнее в этой статье). Довольно неудобно даже инвертировать значение явным присваиванием, как в примере выше, а пытаться строить на этом какую-то логику и вовсе кошмар. Хорошо, что основные логические операции можно выполнять прямо в объявлении переменных! not Тут всё просто, 1 — 0 = 1, 1 — 1 = 0 --not: calc(1 - var(--j))
and Простое умножение: 0 * 0 = 0 1 * 0 = 0 0 * 1 = 0 1 * 1 = 0 --and: calc(var(--k)*var(--i))
nand 1 — and = инвертированный and --nand: calc(1 - var(--k)*var(--i))
or Если хотя бы один из операндов равен единице, or возвращает единицу: k or i = (not k) nand (not i) --or: calc(1 - (1 - var(--k))*(1 - var(--i)))
nor Аналогично с nand, nor = 1 — or: --nor: calc((1 - var(--k))*(1 - var(--i)))
xor Возвращает единицу, если ровно один из операндов равен единице: --xor: calc((var(--k) - var(--i))*(var(--k) - var(--i)))
Заключение Имея на руках бинарную логику и условные операторы, в CSS можно реализовать кучу вещей, которые раньше казалось возможным делать только через грубое вмешательство со стороны JS. Но есть один нюанс — чем глубже в дебри, тем менее читаемым становится код и тем сложнее его писать и поддерживать. Поэтому список подобных трюков можно продолжать ещё очень долго, но большинство приёмов из него почти наверняка не пригодятся в реальном мире. Зато основные концепции вроде switch и or помогут обойтись красивым CSS-only решением там, где раньше это казалось невозможным. Облачные серверы от Маклауда подходят для размещения веб-проектов любой сложности! Вы можете создать собственную конфигурацию сервера в течение минуты и менять эти параметры в любой момент через удобную панель управления. Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации! оригинал =========== Источник: habr.com =========== Похожие новости:
Блог компании Маклауд ), #_vebdizajn ( Веб-дизайн ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ), #_css |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:45
Часовой пояс: UTC + 5