CSS native variables not working in media queries

前端 未结 7 1480
情书的邮戳
情书的邮戳 2020-11-30 19:57

I am trying to use CSS variables in media query and it does not work.

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

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


        
7条回答
  •  悲哀的现实
    2020-11-30 20:38

    Short Answer

    You can use JavaScript to change the value of media queries and set it to the value of a css variable.

    // 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 = '..'
    


    Long Answer

    I wrote a small script which you can include on your page. It replaces every media rule with a value of 1px with the value of the css variable --replace-media-1px, rules with value 2px with --replace-media-2px and so on. This works for the media queries with, min-width, max-width, height, min-height and max-height even when they are connected using 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) {
      ...
    }
    

提交回复
热议问题