Подтвердить что ты не робот

Препроцессор 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 с более обширным примером, который смешивает различные элементы размера шрифта с разным измеренным блоком.

Легко и гибко для моих нужд. Надеюсь, это будет полезно для кого-то еще.

4b9b3361

Ответ 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;
    }
}