programing

CSS 네이티브 변수가 미디어 쿼리에서 작동하지 않음

subpage 2023. 10. 31. 22:06
반응형

CSS 네이티브 변수가 미디어 쿼리에서 작동하지 않음

미디어 쿼리에 CSS 변수를 사용하려고 하는데 작동이 안 됩니다.

:root {
  --mobile-breakpoint: 642px;
}

@media (max-width: var(--mobile-breakpoint)) {

}

스펙으로 봤을 때.

var()함수는 원소의 어떤 성질에 있는 값의 어떤 부분을 대신하여 사용될 수 있습니다. 그var()함수는 속성 이름, 선택기 또는 속성 값 이외의 다른 것으로 사용할 수 없습니다. 일반적으로 잘못된 구문을 생성하거나, 그렇지 않으면 의미가 변수와 연결되지 않는 값을 생성합니다.

아니요, 미디어 쿼리에 사용할 수 없습니다.

그것도 일리가 있습니다.설정할 수 있기 때문에--mobile-breakpoint예를 들어 에:root , ,<html>원소가 다른 원소들에게 상속됩니다.그러나 미디어 쿼리는 요소가 아니며 다음에서 상속되지 않습니다.<html>안 돼요,요.

이것은 CSS 변수가 달성하려는 것이 아닙니다.대신 CSS 전처리기를 사용할 수 있습니다.

Oriol이 답변한 바와 같이 CSS Variables Level 1's는 현재 미디어 쿼리에 사용할 수 없습니다.그러나, 이 문제를 해결할 수 있는 최근의 개발이 있습니다.CSS Environment Variables Module Level 1이 표준화되어 구현되면 모든 최신 브라우저에서 미디어 쿼리에 변수를 사용할 수 있게 됩니다.

CSS 는 CSSWG(CSS Working Group)를 했습니다.env()새로운 표준(현재 초안 단계에 있음): CSS Environment Variables Module Level 1 (자세한 내용은 이 GitHub 주석 및 주석 참조).초안은 미디어 쿼리의 변수를 명시적인 사용 사례로 제시합니다.

환경 변수는 특정 요소에서 추출한 값에 의존하지 않기 때문에 다음과 같이 명확한 요소가 없는 곳에서 사용할 수 있습니다.@media규칙, 여기서var()함수가 올바르지 않습니다.

사양을 읽고 문제가 있거나 미디어 쿼리 사용 사례에 대한 지원을 음성화하고 싶다면 issue #2627, issue #3578 또는 "css-env-1"로 레이블이 지정된 CSS GitHub 문제에서 그렇게 할 수 있습니다.

GitHub issue #2627GitHub issue #3578은 미디어 쿼리에서 사용자 지정 환경 변수에 대한 전용입니다.


2017-11-09 원답: 최근 CSS Working GroupCSS Variables Level 2가사용하여 사용자 정의 환경 변수를 지원할 것이며, 미디어 쿼리에서 유효하도록 노력할 것입니다.이 그룹은 2017년 9월 아이폰 X의 공식 발표 직전에 애플이 표준 사용자 에이전트 속성을 처음 제안한 후 이 문제를 해결했습니다(Timothy Horton의 WebKit: "아이폰 X를 위한 디자인 웹사이트" 참조).그리고 다른 브라우저 담당자들도 TV 디스플레이나 블리드 에지가 있는 잉크 인쇄와 같은 많은 장치에서 일반적으로 유용하다는 데 동의했습니다. (env()라고 불리던constant(), 하지만 그것은 이제 감가상각되었습니다.Peter-Paul Koch의 기사와 같이 옛 이름을 지칭하는 기사를 여전히 볼 수 있습니다.)몇 주가 지난 후, Mozilla의 Cameron McCormack은 이러한 환경 변수가 미디어 쿼리에서 사용할 수 있다는 것을 깨달았습니다. 그리고 Google의 Tab Atkins 주니어는 사용자 정의 환경 변수가 미디어 쿼리에서 사용할 수 있는 전역적이고 무시할 수 없는 루트 변수로 특히 유용할 것이라는 것을 깨달았습니다.이제 애플의 딘 "디노" 잭슨이 앳킨스와 함께 레벨 2를 편집할 입니다.

GitHub 호 #1693에서 이 문제에 대한 업데이트를 구독할 수 있습니다. (특히 관련된 자세한 내용은 CSSWG Meeting Bot의 결의에 포함된 회의 로그를 확장하고 "미디어 쿼리"를 의미하는 "MQ"를 검색하십시오.)

하지만 당신이 할 수 있는 것은 @media query your.:root성명서!

:root {
     /* desktop vars */
}
@media screen and (max-width: 479px) {
    :root {
        /* mobile vars */
    }
}

크롬, 파이어폭스, 엣지에서 적어도 이 게시물 현재 최신 제품 버전에서 완전히 작동합니다.

한 가지 제한 사항은 변수로서 값에 액세스해야 하는 경우(예를 들어 다른 곳의 계산에 사용하는 경우) 변수가 있어야 하며, 미디어 쿼리와 변수 선언의 두 가지 위치에서 변수를 정의해야 합니다.

그런 네이티브 CSS 변수를 사용하는 것은 불가능한 것 같습니다.그것이 한계 중 하나입니다.

미디어 쿼리의 변수를 변경하여 모든 스타일에 영향을 주는 것이 현명한 사용 방법입니다.는 이 기사를 추천합니다.

:root {
  --gutter: 4px;
}

section {
  margin: var(--gutter);
}

@media (min-width: 600px) {
  :root {
    --gutter: 16px;
  }
}

미디어 쿼리의 레벨 5 사양은 사용자가 찾고 있는 작업을 거의 수행하는 사용자 지정 미디어 쿼리를 정의합니다.CSS 변수를 사용하는 방법과 유사한 중단점을 정의하고 나중에 다른 장소에서 사용할 수 있습니다.

사양의 예:

@custom-media --narrow-window (max-width: 30em);

@media (--narrow-window) {
  /* narrow window styles */
}
@media (--narrow-window) and (script) {
  /* special styles for when script is allowed */
}

이 기능은 아직 지원되지 않기 때문에 이 기능을 사용하기 전에 기다려야 합니다.

원하는 것을 달성하기 위한 한가지 방법은 npm 패키지를 이용하는 것입니다.postcss-media-variables.

npm 패키지를 사용해도 괜찮으시다면 여기에서 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) {}

단답형

자바스크립트를 사용하여 미디어 쿼리 값을 변경하고 cs 변수 값으로 설정할 수 있습니다.

// 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) {
  ...
}

matchMedia:를 사용하여 프로그래밍 방식으로 미디어 쿼리를 작성할 수 있습니다.

const mobile_breakpoint = "642px";
const media_query = window.matchMedia(`(max-width: ${mobile_breakpoint})`);
function toggle_mobile (e) {
  if (e.matches) {
    document.body.classList.add("mobile");
  } else {
    document.body.classList.remove("mobile");
  }
}
// call the function immediately to set the initial value:
toggle_mobile(media_query);
// watch for changes to update the value:
media_query.addEventListener("change", toggle_mobile);

그런 다음 CSS 파일에서 미디어 쿼리를 사용하는 대신 다음과 같은 경우 원하는 규칙을 적용합니다.body가 있습니다.mobile클래스:

.my-div {
  /* large screen rules */
}

.mobile .my-div {
  /* mobile screen rules */
}

다른 답을 읽을 수 있지만, 여전히 그렇게 할 수는 없습니다.

어떤 사람이 커스텀 환경 변수를 언급했습니다(커스텀 CSS 변수 대신 커스텀 CSS 변수와 유사함).var()), 그리고 원칙은 건전하지만 여전히 두 가지 주요 문제가 있습니다.

  • 약한 브라우저 지원
  • 지금까지는 정의할 방법이 없습니다. (그러나 아마도 미래에 있을 것입니다. 왜냐하면 이것은 지금까지 비공식 초안에 불과하기 때문입니다.)

언급URL : https://stackoverflow.com/questions/40722882/css-native-variables-not-working-in-media-queries

반응형