Русский
Русский
English
Статистика
Реклама

Крутые трюки с переменными CSS



Переменные в 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
К списку статей
Опубликовано: 02.04.2021 10:12:46
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании маклауд

Веб-дизайн

Разработка веб-сайтов

Css

Цветовые схемы

Switch-case

Цсс

Переменные css

Custom properties

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru