Skip to content Skip to sidebar Skip to footer

Control Which Css Media Queries Are Applied Via Javascript

Is a there way to control which css media query a browser obeys using javascript? For example, if have the following css: p { color : red; } @media (max-width: 320px) { p { col

Solution 1:

You can access the list of style sheets in the document via document.styleSheets. Each sheet is a CSSStyleSheet object, which has a list of rules. There's a kind of rule called a CSSMediaRule that contains the information for a media query, including the rules for that query and the media that it applies to. In theory, you could then change the media that it applies to.

MDN has some documentation on this, here's a starting point.

Here's a complete example that looks for a media rules matching (max-width: 320px) and changes them to (max-width: 2000px): Live Copy | Source

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Change Media Query</title>
<style type="text/css">
p { color: green }
@media (max-width: 320px) {
  p { color: red }
}
</style>
<meta charset="UTF-8">
</head>
<body>
<p>This is text turns red after two seconds</p>
<script>
setTimeout(function() {
    var sheets, sheetIndex, ruleIndex, sheet, rules, rule, media;

    sheets = document.styleSheets;
    for (sheetIndex = 0; sheetIndex < sheets.length; ++sheetIndex) {
      sheet = sheets[sheetIndex];
      rules = sheet.cssRules || sheet.rules;
      for (ruleIndex = 0; ruleIndex < rules.length; ++ruleIndex) {
        rule = rules[ruleIndex];
        if (rule.media && rule.media.mediaText === "(max-width: 320px)") {
          console.log("Changing 320px rule to 2000px");
          rule.media.mediaText = "(max-width: 2000px)";
        }
      }
    }
}, 2000);
</script>
</body>
</html>

Obviously that's very rough code, and I've only checked that it works on Chrome and Firefox. I know there are some differences in these objects in IE vs. others (see the rules = sheet.cssRules || sheet.rules; above, that's one of them). But it could be a starting point.


Solution 2:

I think users should have to resize a browser to see the different media queries. Especially if your media query is for devices below say 480px, then the people testing it should have to resize their browser to 480px to see what it will look like.

That's like saying I want to see what a site will look like on an Android phone but test it on an iPhone. It's just worth it to test the exact test case as closely as possible to the real scenario.


Solution 3:

You can't restrict media query from JavaScript, but this is not a problem; you solve this with more classes:

p { color : red; }
@media (max-width: 320px) {
    p { color: blue; }
    .force_red {
        color: red;
    }
}
@media (max-width: 480px) {
    p { color: green; }
    .force_blue p {
        color: green;
    }
}
.force_blue p {
    color: blue;
}

Minor disclaimer: don't name your class force_blue, that's a terrible name.

Script:

document.body.className = "force_blue";

Ideally, the only way your JavaScript affects your template is by adding or removing classes. This allows you make a template of each potential state and keeps it all nice and maintainable.


JSFiddle to demonstrate: http://jsfiddle.net/tafCC/1/

Text will go from green or red (depending on your viewport size), to blue. Once it's blue, it stays blue. Note: the max-width: 320px rule gets overriden by max-width: 480px, add a min-width too (fixed in my JSFiddle).


Post a Comment for "Control Which Css Media Queries Are Applied Via Javascript"