Переменные в Less | WebReference
Переменные нужны для организации и упрощения написания кода и позволяют предварительно задать популярные значения, а затем повторно использовать их в любом месте кода просто написав имя переменной. Это удобно, потому что нам при необходимости не придётся отыскивать и править множество значений, достаточно изменить его в одном месте и значения везде заменятся автоматически.
Переменные начинаются с символа @, затем идёт имя переменной, оно может включать в себя латинские символы, символ подчёркивания (_) и дефис (-). После имени пишем двоеточие и любое значение допустимое в CSS, либо имя другой переменной. Всё это похоже на синтаксис CSS, так что должно быть знакомо.
@dark-color: #333; @light-color: #f0f0f0; .creature { background-color: @dark-color; color: @light-color; }
Теперь в любом месте кода можем вызвать переменную подставляя её имя. В CSS вместо переменной будет написано её значение. Вот что в итоге получится.
.creature { background-color: #333; color: #f0f0f0; }
На деле переменные не ограничиваются подстановкой значений, переменные можно добавлять в качестве имён селекторов, путей и др. В этом случае синтаксис вызова переменной немного изменится и обращаться к ней надо как @{var}. Ниже показано, как это делается.
@dark-color: #333; @light-color: #f0f0f0; @path-img: "../img"; @block: block; .@{block} { background: url("@{path-img}/pic.png") no-repeat; } .@{block}-title { background:@dark-color; color: @light-color; } .@{block}-content { padding: 10px; }
Вот что мы получим на выходе.
.block { background: url("../img/pic.png") no-repeat; } .block-title { background: #333333; color: #f0f0f0; } .block-content { padding: 10px; }
Вычисления
Переменные могут участвовать в математических выражениях и их можно складывать, вычитать, умножать и делить между собой или с другими значениями. Разумеется, правильный результат будет только в том случае, если данные сочетаются, так что складывать проценты с пикселями не получится. Ниже используется деление, сложение и вычитание переменных.
@num-columns: 3; @bg-color: #3ac; @column-width: 100% / @num-columns; @size: 100% - 20px; @bg-new: @bg-color + 30;
В результате вычисления мы получим следующие значения:
@num-columns: 3; @bg-color: #3ac; @column-width: 33.33333333%; @size: 80%; @bg-new: #51c8ea;
Как видите, Less при отнимании пикселей из процентов не выдаёт ошибку, а просто заменяет одни единицы на другие. В итоге он вычитает 20% от 100%, а никак не пиксели. Так что учитывайте этот момент в своих вычислениях.
Ленивая загрузка
Паша дал Маше два яблока, а Петя ей три. Сколько яблок стало у Маши? Нет, не пять, потому что мы не знаем, сколько яблок было у Маши первоначально. Мораль: обнуляйте переменные. Этот программистский анекдот справедлив при работе с языками вроде JavaScript, но не с Less.
В этом примере мы вначале присваиваем свойству color значение переменной, которое на этот момент не известно. Затем уже ниже определяем саму переменную и её значение.
body { color: @bg-color; } @bg-color: #3ac;
См. также
Документация по переменным Less
http://lesscss.org/features/#variables-feature
Автор: Влад Мержевич
Последнее изменение: 23.03.2016
Как правильно использовать переменные в препроцессорах Less и Sass | by Павел Радьков
8 min read·
Jul 7, 2017История архитектурной ошибки, её последствия, и три правила, благодаря которым вы сможете держать исходный код в порядке и снизить стоимость внесения изменений.
В 2014 году в компании начали редизайн проекта и в основу вёрстки мы положили свежий на тот момент Bootstrap 3.0.1. Использовали мы его не как отдельную стороннюю библиотеку, а тесно заинтегрировали с нашим собственным кодом: отредактировали переменные под наш дизайн и компилировали кастомизированный Бутстрап из Less исходников самостоятельно. Проект оброс собственными модулями, которые использовали бутстраповские переменные и добавляли в файл с настройками свои новые переменные.
В тот момент я думал, что это правильный подход. Ведь код сразу компилируется с нужными значениями без переопределения стилей. CSS чистый, компактный и без повторений. Компоненты стилизованы с помощью глобальных настроек.
Через год с небольшим редизайн закончился, проект вышел в продакшн, и мы взялись за технический долг. При попытке обновить Бутстрап до версии 3.6.x выяснилось, что смержить новый variables.less с нашим файлом настроек будет нелегко. В Бутстрапе переименовали или убрали часть переменных, добавили новые. Собственные компоненты Бутстрапа обновились без проблем, а вот наши компоненты падали при компиляции из-за этих изменений.
Мы проанализировали ситуацию и сформулировали проблемы.
- Слишком связанный код. Сами компоненты лежали в отдельных файлах. Это создавало иллюзию, что компоненты независимые. Но компоненты использовали переменные, объявленные во внешнем файле variables.less, и без этого файла не работали. Нельзя было просто так взять и переместить компонент в другой проект. Приходилось тянуть за собой файл с настройками, который со временем превратился в помойку.
- Слишком много глобальных переменных. У Бутстрапа было ≈400 переменных. Мы отключили неиспользуемые компоненты Бутстрапа, но переменные оставили в конфиге на случай, если снова понадобятся. Еще мы добавили сотню или полторы своих переменных. Все названия не запомнить, трудно быстро находить нужные. Даже с правилами именования и комментариями ориентироваться в конфиге из 500+ переменных тяжело.
- Имена глобальных переменных вышли из-под контроля. Одна и та же переменная могла использоваться в разных файлах и отслеживать все её появления в коде было долго и трудно. Когда меняли значение переменной в одном компоненте, был риск поломать другие компоненты. Разработчики хардкодили, создавали новые переменные с похожими названиями и значениями и уже не следили за логикой именования.
Я придумал три правила, которые помогли побороть наши проблемы:
1) Переменная используется только в том файле, в котором объявлена.
Правильно создавать все нужные переменные в файле самого компонента и не использовать переменные из других файлов. Тогда компоненты станут независимыми, их можно будет подключать и перемещать между проектами без поломок при компиляции. У каждого компонента собственный набор переменных, которые запрещено использовать в других компонентах и вызывать в других файлах. Когда переменные не выходят за пределы одного файла, легко увидеть, как они используются и на что влияют.
2) Все переменные внутри компонента — локальные.
Раз у каждого компонента свои переменные, пусть они будут локальными. Это избавит от проблем с именованием: в компонентах можно использовать переменные с одинаковыми именами и разными значениями — они не будут конфликтовать друг с другом.
3) Глобальные переменные используются только внутри файла настроек.
Благодаря первым двум правилам мы сильно сократим количество глобальных переменных, но они всё равно нужны. Глобальные переменные объявляются в главном файле проекта или в файле типа config.less. К ним тоже применяется правило №1 — переменные не используются за пределами своего файла. Это значит, что нельзя использовать глобальные переменные внутри файлов компонентов. Но существует способ не нарушая первого правила прокинуть значение глобальной переменной внутрь компонента. Как это сделать мы рассмотрим на примерах далее.
Третье правило избыточное. Соблюдая первые два, вы автоматически соблюдаете третье. Но в реальной жизни есть очень большой соблазн пойти по простейшему пути, не создавать локальную переменную, а по-быстрому использовать глобальную. Третье правило напоминает, что так делать вредно, что это создаёт ненужные зависимости и приводит к связыванию кода.
Применим правила на практике.
Представим простейший компонент для стилизации страницы. Согласно правилу №1 создадим переменные внутри файла компонента.
Было. Пример кода компонента.Стало. Переменные объявлены в глобальной области видимости и у них слишком общие имена. Это плохо.Правило 1
Переменная используется только в том файле, в котором объявлена.
В примере выше мы объявили переменные в глобальной области видимости и из-за этого они подвержены конфликту имён. Если в соседнем компоненте появится переменная с таким же именем, то компоненты поломают друг друга.
Локальные переменные
Область видимости — это «пространство» между фигурными скобками селектора: { и } . Объявленные внутри фигурных скобок переменные работают только внутри этих скобок и внутри дочерних скобок, но их нельзя использовать снаружи.
Если скобок вокруг нет, то это самый верхний уровень — глобальная область видимости.
У переменной из дочерней области видимости приоритет выше, чем у одноименной переменной из родительской области видимости. У глобальных переменных самый низкий приоритет при совпадении имён.
По правилу №2 сделаем переменные локальными — переместим их внутрь селектора.
Переменные объявлены внутри селектора и не создают конфликта имён, потому что теперь они локальные.Правило 2
Все переменные внутри компонента — локальные.
Теперь конфликта имен с другими компонентами не будет. Мы решили первую и вторую проблемы: получился изолированный сниппет без внешних зависимостей. Но я не знаю способа переопределить локальные переменные компонента в таком виде извне. Поэтому, чтобы кастомизировать компоненты глобальными переменными проекта, придумал другую форму записи.
Миксины как функции
В Less можно использовать миксины как функции. Если внутри миксина создать переменные, а потом вызвать миксин внутри селектора, то переменные будут доступны в области видимости этого селектора.
Читайте про миксины как функции в документации Less.
Вынесем объявление переменных внутрь миксина .page-settings()
, а потом вызовем его внутри селектора .page
:
Переменные локализованы внутри глобального миксина. Когда мы вызвали миксин в коде, переменные стали доступны в области видимости селектора .page
, но по прежнему остались локальными.
Такой миксин не генерирует CSS код, его единственная задача — доставить переменные в нужную область видимости. Например, если вызвать этот миксин в глобальной области видимости, то и переменные станут глобальными. Но это то же самое, что сразу объявить переменные глобально.
Вместо нескольких глобальных переменных с распространёнными именами мы создали один глобальный миксин. В проекте не должно быть двух одноименных компонентов, значит имя миксина будет уникальным.
Слияние миксинов
В Less существует «ленивое вычисление» переменных: не обязательно объявлять Less-переменную перед её использованием, можно объявить после. В момент компиляции парсер Less найдет определение переменной и отрендерит значение этой переменной в CSS.
Смотрите примеры «Lazy Evaluation» и переопределения дефолтных переменных в документации Less.
Если переопределить переменную, то во всех местах её использования в силу вступит значение из самого последнего определения, так как оно приоритетнее по порядку следования в исходном коде. В этом смысле переменные ведут себя как константы.
Итак, переменные можно объявлять и до, и после использования, а миксины — это разновидность переменных. Если создать два миксина с одним и тем же именем и разным содержанием, то они объединяют свои внутренности. А если внутри миксинов есть переменные с одинаковыми именами, то происходит переопределение. Приоритет выше у последнего миксина.
Рассмотрим три файла:
Главный файл. Импортируем компоненты и конфиг. Конфиг — последним.Компонент. Все переменные локальные и хранятся в миксине.Конфиг проекта. Переопределяем параметры компонента с помощью миксина настроек.Всё самое интересное происходит в конфиге. Мы создали глобальные переменные и использовали их в этом же файле для кастомизации компонента.
Миксин .page-settings()
объявлен два раза. Первый раз внутри файла page.less
с дефолтными значениями, второй раз в файле config.less
с новыми значениями. На этапе компиляции миксины склеиваются, новые переменные переопределяют дефолтные и CSS рендерится с новыми значениями из файла конфигурации.
Правило 3
Глобальные переменные используются только внутри файла настроек.
Обратите внимание, что config.less
инклюдится последним в списке. Это нужно, чтобы объявление миксина в конфиге имело больший приоритет, чем исходное объявление в файле самого компонента. Настройки не применятся, если поставить config.less
до компонента, потому что на миксины тоже действуют правило «последнее определение — самое сильное».
Таким способом мы прокинули значения глобальных переменных внутрь файла компонента, не меняя исходный код компонента. При этом были соблюдены все три правила:
- переменные использовались только в своём файле, даже глобальные переменные не вызывались за пределами файла
config.less
; - переменные компонента остались локальными и не засорили глобальную область видимости;
- глобальные переменные не использовались внутри компонента напрямую, но значения глобальных переменных хитрым способом попали внутрь компонента.
Ограничения
Нельзя, чтобы имя глобальной переменной совпадало с именем локальной — получим рекурсию и CSS не скомпилируется. Чтобы не ошибиться, лучше все глобальные переменные записывать с префиксом.
Неправильно. Рекурсивное определение переменной вызывает ошибку компиляции.Правильно. У глобальных переменных свой префиксglob-
, что исключает совпадение имён.Sass отличается от Less и больше похож на скриптовый язык программирования: нет «ленивых вычислений» и переменная должна быть обязательно объявлена до её использования в коде. Если определить переменную и использовать её в коде, а потом переопределить и использовать ещё раз, то в первый вызов получим исходное значение в CSS, а во второй вызов новое значение. Трюк с миксинами, как в Less, не пройдет. Но есть другие пути решения.
Наборы переменных для настройки компонента удобно хранить в map-объектах. Это массив из пар «ключ: значение». Метод map-get извлекает конкретное значение из массива, метод map-mergeобъединяет два массива в один, дополняя или переписывая исходный массив.
Читайте про Maps в документации Sass.
Простейший компонент без возможности переопределения извне будет выглядеть так:
Настройки хранятся в map-объекте и вызываются в коде с помощью map-getЧтобы настраивать компонент из другого файла, нужно предусмотреть возможность смержить внешний конфиг с исходными настройками. Рассмотрим три файла:
Главный файл.Сначала импортируем конфиг, потом компоненты.Настройки.
Создаём глобальные переменные и переопределяем параметры компонента.Компонент.
Добавили проверку: а не существуют ли уже настройки, чтобы переопределить компонент?
[1]
— В компоненте мы сначала объявили переменную с пустым массивом $page-override
.
[2]
— Потом проверили, а не существует ли уже переменная $page-settings
. И если она уже была объявлена в конфиге, то присвоили её значение переменной $page-override
.
[3]
— И потом смержили исходный конфиг и $page-override
в переменную $page-settings
.
Если массив $page-settings
был объявлен ранее в глобальном конфиге, то $page-override
перепишет настройки при слиянии. Иначе в переменной $page-override
будет пустой массив, и в настройках останутся исходные значения.
Я не знаю всех тонкостей Sass, может есть способ реализовать эту методику более красивым способом.
В результате, мы получаем всё те же преимущества, только в отличие от Less нам приходится переопределять все настройки заранее, перед их использованием в коде.
Не важно на чем вы пишете — на Less, Sass, CSS c кастомными свойствами или Javascript — глобальных переменных должно быть как можно меньше.
С CSS препроцессорами используйте три правила, которые помогут избежать хаоса:
- Переменная используется только в том файле, в котором объявлена.
- Все переменные внутри компонента — локальные.
- Глобальные переменные используются только внутри файла настроек.
Чтобы прокинуть глобальные настройки внутрь компонента, собирайте переменные в миксин (Less) или map-объект (Sass).
Переопределяйте настройки в правильном месте: в Less — после инклюда, в Sass — перед инклюдом.
Я сформулировал эту методику в декабре 2015 года для Less и с тех пор применяю её на рабочих и личных проектах.
За полтора года появилось несколько публичных npm-пакетов. Посмотрите исходный код для лучшего понимания, как это работает в реальных ситуациях.
bettertext.css — типографика для сайтов. Настраивается при помощи 11 переменных, остальные 40 вычисляются по формулам. Вычисления идут отдельными миксином, чтобы была возможность переопределять формулы. У компонента нет ни одного класса, все стили применяются к тегам. Чтобы создать локальную область видимости, я поместил все селекторы по тегам в переменную — в Less это называется «detached ruleset».
Читайте про detached ruleset в документации Less.
links.less — стили для ссылок с фокусом, анимацией и бледным подчеркиванием. У компонента кроме миксина с настройками есть дополнительные глобальные миксины для раскрашивания ссылок внутри ваших собственных селекторов.
flxgrid.css — генератор HTML-сеток на флексах. Настраивается при помощи 5 переменных, генерирует классы для адаптивной сетки с любыми брейкпоинтами и любым количеством колонок. В компоненте вычисления и служебные миксины спрятаны внутрь локальной области видимости. Глобально виден только миксин с настройками.
space.less — инструмент для управления отступами в вёрстке. Создан, чтобы работать в паре с сеткой flxgrid.css. Адаптивность у них настраивается одинаково, но space.less использует собственный миксин настройки и собственные локальные переменные — в коде space.less никак не связан с flxgrid.css.
Если бы мне сейчас понадобилось использовать на новом проекте Bootstrap 3.x.x — тот, который на Less, — я бы все импортируемые модули Бутстрапа завернул в переменную (в «detached ruleset»), а все настройки из файла variables.less
в миксин bootsrtap-settings
. Глобальные переменные Бутстрапа перестали бы быть глобальными и их невозможно было бы использовать внутри собственного кода. Настройки Бутстрапа я бы кастомизировал по мере необходимости, вызывая миксин bootsrtap-settings
в конфиге проекта, так же как в примерах выше. Тогда при обновлениях Бутстрапа пришлось бы поправить только миксин с кастомизированными настройкам.
Less.js Variables Multiple & Selector
LESS (Leaner Style Sheets) — это простой препроцессор CSS, который упрощает создание управляемых, настраиваемых и многократно используемых таблиц стилей для веб-сайтов. Это динамический язык таблиц стилей, который расширяет возможности CSS. LESS поддерживает кросс-браузерную совместимость. Препроцессор CSS — это язык сценариев, который улучшает CSS и компилируется в обычный синтаксис CSS, чтобы его можно было использовать в веб-браузере. Это также обратно совместимое языковое расширение для CSS, которое предоставляет такие функции, как переменные, функции, примеси и операции, которые позволяют нам создавать динамический CSS.
Описание для переменных: Переменные в LESS.js управляют общими значениями, используемыми в одном месте, т. е. известно, что они хранят в себе значения и могут использоваться в любом месте определения кода. LESS позволяет использовать эти переменные для изменения конкретного значения во всем коде. Это может вызвать проблемы, когда нам нужно изменить одно конкретное значение в нашем коде CSS, но с помощью переменных это легко сделать.
Множественный и родительский селектор:
В множественном селекторе & оператор & используется для неоднократного обращения к родительскому селектору без использования его имени. Таким образом, множественный и родительский селектор указывает, что оператор селектора и можно использовать более одного раза. Может быть полезно добавить селектор к унаследованным (родительским) селекторам. Это можно сделать, поставив и после текущего селектора. Например, при использовании Modernizr вы можете указать разные правила в зависимости от поддерживаемых функций:
Синтаксис:
.ссылка { & + & { } }
Пример 1: В следующих примерах демонстрируется использование множественных переменных Less. js и селектора в файле Less.
HTML
< html > 9 0036 ссылка rel = "таблица стилей" href = "style.css" type = "text/css" /> 9003 4 головка > < корпус > < h2 класс = "ссылка" > Добро пожаловать в GeeksforGeeks!! h2 > < h4 class = "linksh" >< б > Множественные переменные Less. js и селектор b > h4 > 9003 4 корпус > html > |
стиль. меньше: Создайте файл Less.
CSS
@rd: зеленый ; @синий: синий ; @bg: голубой; .link { & + & { 90 035 цвет : @bg; } & & { 9 0036 |