미디어 쿼리에서 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-env-1]” .
원래 대답 2017년 11월 9일 : 최근에, CSS 워킹 그룹은 결정 하는 것이 CSS 변수 레벨 2를 사용하여 사용자 정의 환경 변수를 지원합니다 env()
, 그들은 그들이 미디어 쿼리에 유효하게하려고합니다 . 그룹 은 Apple 이 2017 년 9 월 iPhone X의 공식 발표 직전에 표준 사용자 에이전트 속성을 처음 제안한 후에 이를 해결했습니다 ( WebKit : Timothy Horton의“iPhone X 용 웹 사이트 디자인” 참조 ). 그런 다음 다른 브라우저 담당자는 일반적으로 텔레비전 디스플레이 및 블리드 가장자리가있는 잉크 인쇄와 같은 많은 장치에서 유용 할 것이라고 동의했습니다. (이전 env()
에는constant()
하지만 이제는 더 이상 사용되지 않습니다. Peter-Paul Koch의이 기사 와 같이 이전 이름을 가리키는 기사가 계속 표시 될 수 있습니다 . 몇 주가 지난 후 Mozilla의 Cameron McCormack은 있음 깨달았습니다. 와 레벨 2 편집에 입니다.이러한 환경 변수는 미디어 쿼리에서 사용할 수 있으며 Google의 Tab Atkins Jr.는 사용자 정의 환경 변수가 미디어 쿼리에서 사용할 수있는 재정의 할 수없는 전역 루트 변수로 특히 유용 하다는 것을 깨달았습니다 . 이제 Apple의 Dean "Dino"Jackson이 Atkins에 합류합니다
GitHub 문제 # 1693 에서이 문제에 대한 업데이트를 구독 할 수 있습니다.w3c/csswg-drafts
. (특히 관련 기록 세부 정보를 보려면 CSSWG Meeting Bot의 해상도에 포함 된 회의 로그를 확장하십시오. "미디어 쿼리"를 나타내는 "MQ"를 검색하십시오.)
앞으로 더 많은 개발이 진행될 때이 질문을 업데이트 할 계획입니다. 미래는 흥미 롭습니다.
2018 년 2 월 8 일 업데이트 :
Safari Technology Preview 49 는 calc()
미디어 쿼리의 구문 분석 기능을 추가로 지원 env()
합니다.
2018-04-27 업데이트 : Google의 Chromium 팀에서 작업을 시작하기로 결정했습니다 env()
. 이에 따라 Atkins는 env()
별도의 비공식 초안 표준 인 CSS 환경 변수 모듈 레벨 1 을 지정하기 시작했습니다 . ( w3c / csswg-drafts # 1693의 GitHub 주석 및 w3c / csswg-drafts # 1817의 주석을 참조하십시오 . 초안은 미디어 쿼리에서 변수를 명시 적 사용 사례로 호출합니다.
환경 변수는 특정 요소에서 가져온 것의 값에 의존하지 않기 때문에 함수 와 같이 유효하지 않은
@media
규칙 과 같이 명확한 요소가없는 곳에서 사용할 수 있습니다var()
.
사양을 읽고 우려 사항이 있거나 미디어 쿼리 사용 사례에 대한 지원을 표명하려는 경우 여전히 GitHub w3c / csswg-drafts # 1693 또는 접두사 "[ css-env-1]” .
2019-07-06 업데이트 : 사양에 대한 작업이 계속됩니다. GitHub 문제 # 2627 및 GitHub 문제 # 3578 은 미디어 쿼리의 사용자 지정 환경 변수에 전념합니다.
그러나 당신이 할 수있는 일은 @media query : : root statement입니다!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
이 게시물 기준으로 최소한 최신 프로덕션 버전 인 Chrome, Firefox 및 Edge에서 완전히 작동합니다.
var
하므로 다른 곳의 계산에 사용할 수있는 경우 css
에도 미디어 쿼리와 var 선언의 두 위치에 "마법의 값"(여기서는 479px)을 배치해야합니다.
분명히 네이티브 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) {}
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
.
자바 스크립트 :
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) {
...
}