Я намагаюся використовувати змінні CSS в медіа-запитах, і це не працює.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Я намагаюся використовувати змінні CSS в медіа-запитах, і це не працює.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Відповіді:
З специфікації ,
var()
Функція може бути використана замість будь-якій частині значення в будь-який власності на елементі.var()
Функція не може бути використана в якості імен властивостей, селектор, або що - небудь ще , крім значень властивостей. (Так зазвичай утворюється недійсний синтаксис, або ж значення, значення якого не має зв'язку зі змінною.)
Тому ні, ви не можете використовувати його в медіа-запиті.
І це має сенс. Тому що ви можете встановити, --mobile-breakpoint
наприклад :root
, <html>
елемент, тобто елемент, а звідти успадкувати інші елементи. Але медіа-запит не є елементом, він не успадковує <html>
, тому він не може працювати.
Цього не намагаються виконати змінні CSS. Натомість ви можете використовувати препроцесор CSS.
Як відповів Oriol , в даний час CSS змінних рівня 1 var()
не можна використовувати в медіа-запитах . Однак останнім часом були розроблені проблеми, які вирішують цю проблему. Через кілька років, як тільки модуль CSS середовища змінних довкілля рівень 1 буде стандартизований та впроваджений, ми зможемо використовувати env()
змінні в медіа-запитах у всіх сучасних браузерах.
Якщо ви читаєте специфікацію і маєте занепокоєння, або якщо ви хочете озвучити вашу підтримку випадку використання медіа-запитів, ви все одно можете зробити це в GitHub w3c / csswg-drafts # 1693 або в будь-якому випуску CSS GitHub з префіксом "[ css-env-1] ” .
Оригінальна відповідь 2017-11-09 : Нещодавно Робоча група CSS вирішила, що змінні CSS рівня 2 підтримуватимуть визначені користувачем змінні середовища з використанням env()
, і вони намагатимуться зробити їх дійсними в запитах медіа . Група вирішила це після того, як Apple вперше запропонувала стандартні властивості агент-користувачів , незадовго до офіційного оголошення iPhone X у вересні 2017 року (див. Також WebKit: "Проектування веб-сайтів для iPhone X" Тімоті Хортона ). Інші представники веб-переглядачів погодилися, що вони можуть бути корисними для багатьох пристроїв, таких як телевізійні дисплеї та друк із чорнилом. ( env()
раніше називалиconstant()
, але це тепер застаріло. Ви могли б ще побачити статті , які відносяться до старої назви, наприклад, цієї статті Peter-Paul Koch .) Після того, як кілька тижнів пройшли, Камерон Маккормак з Mozilla зрозумів , що ці змінні оточення буде використовуватися в запитах медіа, і Tab Atkins, Jr. Тоді компанія Google зрозуміла, що визначені користувачем змінні середовища будуть особливо корисні як глобальні кореневі змінні, що не можна перезаписати, які можна використовувати в медіа-запитах. Тепер Дін "Діно" Джексон від Apple приєднається до Аткінса в редагуванні рівня 2.
Ви можете підписатися на оновлення з цього питання у w3c/csswg-drafts
випуску GitHub № 1693 . (Для особливо релевантних історичних деталей розгорніть журнали зустрічей, вбудовані в резолюції CSSWG Bot Meeting Bot, і знайдіть "MQ", що означає "медіа-запити".)
Планую оновити це питання в майбутньому, коли відбуватиметься більше подій. Майбутнє захоплююче.
Оновлення 2018-02-08 :
Технологія попереднього перегляду Safari 49 додала підтримку для розбору calc()
в медіа-запитах, що може бути передумовою для підтримки і env()
в них.
Оновлення 2018-04-27 : Команда Chromium від Google вирішила розпочати роботу env()
. У відповідь Аткінс почав конкретизувати env()
в окремому, неофіційному проекті стандарту: модуль змінних середовищ CSS, рівень 1 . (Дивіться його коментар GitHub у w3c / csswg-drafts # 1693 та його коментар у w3c / csswg-drafts # 1817. ) Проект залучає змінні в медіа-запитах як виразний випадок використання:
Оскільки змінні середовища не залежать від значення всього, що складається з певного елемента, їх можна використовувати в місцях, де немає очевидного елемента, з якого можна взяти, наприклад, у
@media
правилах, деvar()
функція не була б дійсною.
Якщо ви читаєте специфікацію і маєте занепокоєння, або якщо ви хочете озвучити вашу підтримку випадку використання медіа-запитів, ви все одно можете зробити це в GitHub w3c / csswg-drafts # 1693 або в будь-якому випуску CSS GitHub з префіксом "[ css-env-1] ” .
Оновлення 2019-07-06 : Робота над технічними умовами продовжується. Випуск GitHub №2627 та випуск GitHub №3578 присвячені спеціальним змінним середовищам у медіа-запитах.
Що ви МОЖИТЕ зробити, це @media запитати ваш: root заява!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Цілком працює в Chrome, Firefox та Edge принаймні в останніх виробничих версіях станом на цю публікацію.
var
, щоб його можна було використовувати в обчисленнях в іншому місці css
, для цього все ж потрібно поставити "магічне значення" (тут, 479 пікселів) у двох місцях: медіа-запит та заява var.
Мабуть, просто не вдається використовувати подібні змінні CSS. Це одне з обмежень .
Розумний спосіб використовувати це - змінити свої змінні в медіа-запиті, щоб вплинути на весь ваш стиль. Я рекомендую цю статтю .
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
Один із способів досягти того, що ви хочете, - це використання пакету npm postcss-media-variables
.
Якщо ви все добре використовуєте npm-пакети, тут ви можете ознайомитись із документальним документом для того ж
Приклад
/* input */
:root {
--min-width: 1000px;
--smallscreen: 480px;
}
@media (min-width: var(--min-width)) {}
@media (max-width: calc(var(--min-width) - 1px)) {}
@custom-media --small-device (max-width: var(--smallscreen));
@media (--small-device) {}
Як ви можете прочитати інші відповіді, досі це зробити неможливо .
Хтось згадав про власні змінні середовища (подібні до користувацьких змінних css env()
замість var()
), і принцип є здоровим, хоча все ж є 2 основні проблеми:
Ви можете використовувати JavaScript, щоб змінити значення медіа-запитів і встановити його на значення змінної css.
// get value of css variable
getComputedStyle(document.documentElement).getPropertyValue('--mobile-breakpoint'); // '642px'
// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];
// update media rule
mediaRule.media.mediaText = '..'
Я написав невеликий сценарій, який можна включити на свою сторінку. Він замінює все правила ЗМІ із значенням 1px
зі значенням змінної Css --replace-media-1px
, правила зі значенням 2px
з --replace-media-2px
і так далі. Це працює для запитів ЗМІ with
, min-width
, max-width
, height
, min-height
і max-height
навіть тоді , коли вони пов'язані з використанням and
.
JavaScript:
function* visitCssRule(cssRule) {
// visit imported stylesheet
if (cssRule.type == cssRule.IMPORT_RULE)
yield* visitStyleSheet(cssRule.styleSheet);
// yield media rule
if (cssRule.type == cssRule.MEDIA_RULE)
yield cssRule;
}
function* visitStyleSheet(styleSheet) {
try {
// visit every rule in the stylesheet
var cssRules = styleSheet.cssRules;
for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
yield* visitCssRule(cssRule);
} catch (ignored) {}
}
function* findAllMediaRules() {
// visit all stylesheets
var styleSheets = document.styleSheets;
for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
yield* visitStyleSheet(styleSheet);
}
// collect all media rules
const mediaRules = Array.from(findAllMediaRules());
// read replacement values
var style = getComputedStyle(document.documentElement);
var replacements = [];
for (var k = 1, value; value = style.getPropertyValue('--replace-media-' + k + 'px'); k++)
replacements.push(value);
// update media rules
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
for (var k = 0; k < replacements.length; k++) {
var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): ' + (k+1) + 'px\\)', 'g');
var replacement = '($1: ' + replacements[k] + ')';
mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
}
}
CSS:
:root {
--mobile-breakpoint: 642px;
--replace-media-1px: var(--mobile-breakpoint);
--replace-media-2px: ...;
}
@media (max-width: 1px) { /* replaced by 642px */
...
}
@media (max-width: 2px) {
...
}