Препроцессор CSS с возможностью определения переменных в запросе @media
В настоящее время я использую LESS как мой основной предварительный процессор CSS. У меня (и я уверен, что многие люди нуждаются) для определения переменных в запросе @media
, например:
@media screen and (max-width: 479px) {
myVar: 10px;
}
@media screen and (min-width: 480px) and (max-width: 767px) {
myVar: 20px;
}
@media screen and (min-width: 768px) {
myVar: 30px;
}
.myElement {
padding: @myVar;
}
Это не работает в LESS из-за природы компиляции (@myVar
определяется только в рамках каждого конкретного @media
, но не глобально). Даже если я определяю @myVar
глобально перед медиа-запросами, он не обновляется в соответствии с медиа-запросами, а .myElement
получает это начальное значение независимо от того, что.
Итак, вопрос в том, можно ли добиться этого в любом другом предварительном процессоре CSS, или мы обречены переопределить .myElement
в каждом запросе на медиа? Не проблема в этом простейшем примере, но в реальных проектах это может сэкономить много времени и скопировать/вставить.
EDIT:
Не решение, а обходной путь для моего конкретного проекта:
- Установите размер шрифта на
<html>
на базовый размер шрифта
-
myVar
LESS переменная определяется в rem
вместо px
как производная от базового размера шрифта
- Используйте
@media
запросы для настройки базового размера шрифта для разных носителей.
- ДОПОЛНИТЕЛЬНО Используйте блок REM polyfill для браузеров, которые еще не поддерживают
rem
(http://caniuse.com/#search=rem). Это не будет работать в IE 8 и ниже, но не из-за отсутствия поддержки rem
- не поддерживает медиа-запросы. Таким образом, IE8 и ниже получают полноразмерную таблицу стилей без медиа-запросов.
Фрагмент кода:
@myVar: .77rem; // roughly 10px, 20px and 30px respectively
html { font-size: 13px }
@media screen and (min-width: 480px) and (max-width: 767px) {
html { font-size: 26px }
}
@media screen and (min-width: 768px) {
html { font-size: 39px }
}
.myElement {
padding: @myVar;
}
Вот JSBin с более обширным примером, который смешивает различные элементы размера шрифта с разным измеренным блоком.
Легко и гибко для моих нужд. Надеюсь, это будет полезно для кого-то еще.
Ответы
Ответ 1
Позвольте мне более непосредственно ответить на вопрос:
"Возможно ли достичь этого в любом другом предварительном процессоре CSS, или мы обречены на переопределение .myElement
в каждом запросе на медиа?"
Ответ на самом деле находится в вопросе. Поскольку LESS (и другие подобные инструменты) является "предварительным процессором", @media
ничего не значит для него во время компиляции, потому что он не смотрит на состояние мультимедиа браузера для его предварительной обработки. Состояние @media
имеет значение только после предварительной обработки, и в этот момент уже был вычислен любой @someVariable
. Вот почему то, что вы пытаетесь сделать, не может работать. Ваш @myVar
может выводиться только как одно значение в таблице стилей CSS, и этот вывод возникает до того, как состояние браузера будет оцениваться с помощью @media
.
Таким образом, это не связано с "глобальным" или "локальным" объемом медиа-запроса, но тот факт, что LESS компилирует код в CSS с использованием переменных, и это CSS (не МЕНЬШЕ), который платит внимание к информации о запросе @media
.
Для дальнейшего обсуждения создания медиа-запросов с LESS таким образом, что они все вместе и не разбросаны по всему коду, см. этот вопрос.
Ответ 2
Вы можете реорганизовать это, поставив медиа-запросы в переменные, а затем используя их внутри элементов.
Пример:
@phone: ~"screen and (max-width: 479px)";
@tablet: ~"screen and (min-width: 480px) and (max-width: 767px)";
@desktop: ~"screen and (min-width: 768px)";
.myElement {
@media @phone { padding: 10px; }
@media @tablet { padding: 20px; }
@media @desktop { padding: 30px; }
}
Что производит:
@media screen and (max-width: 479px) {
.myElement {
padding: 10px;
}
}
@media screen and (min-width: 480px) and (max-width: 767px) {
.myElement {
padding: 20px;
}
}
@media screen and (min-width: 768px) {
.myElement {
padding: 30px;
}
}
В целом, медиа-запрос неанализированный литеральный встраивание в переменную не совсем хорош, но также помогает стандартизировать медиа-запросы.
И это помогает читабельности, потому что все три поведения .myElement
содержатся в одном определении и не меняются где-то в другом месте (это может быть совсем другой файл), что затрудняет "отладку".
Ответ 3
как насчет:
@media screen and (max-width: 479px) {
.myElement(10px);
}
@media screen and (min-width: 768px) {
.myElement(30px);
}
.myElement(@myVar) {
.myElement {
padding: @myVar;
}
}