14

I have a style.css with a media query. In my javascript-file, I have a value for the desired mobile-width stored in a variable.

By changing the variable, I want to change the value of the media query automatically. Is it somehow possible to alter the contents of the .css-file with javascript like I can change the DOM? Adding a HTML <style>-element to the DOM using javascript is not my desired solution, because I want to keep all css in the .css-file

4
  • No it is not possibile. Why don't you write different media queries for different width? Commented Sep 21, 2016 at 7:16
  • 4
    As far as I'm aware, no you cannot. What you can do, however, is add or remove a css class via javascript on the targeted element. Commented Sep 21, 2016 at 7:16
  • 1
    You can use window.matchMedia() to detect any change in media query in JS Commented Sep 21, 2016 at 7:24
  • 1
    @asprin "As far as I'm aware, no you cannot." It is possible by setting .media.mediaText of document.styleSheets[0].cssRules plnkr.co/edit/qzLO5J4KlWZLQnjMIy7i?p=preview Commented Sep 21, 2016 at 8:30

5 Answers 5

9

The best option would be to have two sets of media queries which are only applied based on a parent class being present.

@media (max-width: 600px) {

  .w600 .myDiv{
    color:red;
  }

}

@media (max-width: 400px) {

  .w400 .myDiv{
    color:red;
  }

}

You could then add/remove w600 or w400 to the body class to allow the required media query to work.

Using jQuery this could be done like:

$("body").addClass("w600")
         .removeClass("w400");

I appreciate you may have more than just one style and would therefore like to reduce code duplication.

In which case you could use a CSS transpiler such as Less with mixins:

@mediaqueryruleset:{
  .myDiv{
    color:red;
  }
  .myOtherDiv{
    color:blue;
  }
}

@media (max-width: 600px) {

  .w600 {
    @mediaqueryruleset();
  }

}

@media (max-width: 400px) {

  .w400 {
    @mediaqueryruleset();
  }

}

Which would output:

@media (max-width: 600px) {
  .w600 .myDiv {
    color: red;
  }
  .w600 .myOtherDiv {
    color: blue;
  }
}
@media (max-width: 400px) {
  .w400 .myDiv {
    color: red;
  }
  .w400 .myOtherDiv {
    color: blue;
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

@Curt "You cannot dynamically change a media query variable within a CSS file (without injecting the whole stylesheet again through javascript" The media query variable can be dynamically changed using .media.mediaText of document.styleSheet .cssRules plnkr.co/edit/qzLO5J4KlWZLQnjMIy7i?p=preview
@guest271314 Thanks I wasn't aware you could do that. I still wouldn't suggest it as a viable option however. There's a lot of dependencies on the order of the stylesheets / media queries.
7

You can set the rule directly using .media.mediaText of document.styleSheets[0].cssRules

document.styleSheets[0].cssRules[0].media.mediaText = /* new media rule here */;

plnkr http://plnkr.co/edit/qzLO5J4KlWZLQnjMIy7i?p=preview

2 Comments

There's an error when setting that property, Error: Permission denied to access property "mediaText", but I am able to set conditionText. document.styleSheets[0].cssRules[0].conditionText = "(min-width: 0px)";
Beware that this can fail due to CORS security policy stackoverflow.com/questions/49993633/…
1

You can write by using $(window).width()

value=959;

if($(window).width() < value)
{
    $(".classname").css("color","white");
}

1 Comment

Yes, but since there are hundreds of values in that media query, I would need to make hundreds of css-changes in javascript. Can I say somethign like $(MEDIAQUERY).maxWidth(variableValue); ?
1

Yes. Maybe. Inspired by @guest271314 answer. This seems to allow the changing of the media query conditions via JavaScript.

document.styleSheets[0].cssRules[0].conditionText = "(min-width: 0px)";

Of course, check if the rule has media query applied:

var currentQuery = {index:0,rule:null,mediaText:null};
var inclusionQuery = "(min-width: 0px)";
var exclusionQuery = "(min-width: 99999px)";
var numberOfMediaQueries = 0;

function hideAllMediaQueries() {
    var rules = document.styleSheets[0].cssRules;
    var firstQueryIndex = 0; // show this query
    var queryIndex = 0;
    var numberOfRules = rules!=null ? rules.length : 0;

    // loop through rules and hide media queries except selected
    for (var i=0;i<numberOfRules;i++) {
        var rule = rules[i];

        if (rule.media!=null) {

            if (queryIndex==firstQueryIndex) {
                currentQuery.mediaText = rule.conditionText;
                currentQuery.index = firstQueryIndex;
                currentQuery.rule = rule;
                rule.conditionText = inclusionQuery;
            }
            else {
                rule.conditionText = exclusionQuery;
            }

            queryIndex++;
        }
    }

    numberOfMediaQueries = queryIndex;
}

Note: The example above only applies to existing media queries in your CSS. It does not add or remove queries. It checks if media query exists by checking that the rule.media property is not null.

Comments

0

You can use Enquire.js jQuery plugin.

It is a JavaScript library for dealing with media queries in JavaScript.

This is quick start code sample:

enquire.register("screen and (max-width:45em)", {

    // OPTIONAL
    // If supplied, triggered when a media query matches.
    match : function() {},      

    // OPTIONAL
    // If supplied, triggered when the media query transitions 
    // *from a matched state to an unmatched state*.
    unmatch : function() {},    

    // OPTIONAL
    // If supplied, triggered once, when the handler is registered.
    setup : function() {},    

    // OPTIONAL, defaults to false
    // If set to true, defers execution of the setup function 
    // until the first time the media query is matched
    deferSetup : true,

    // OPTIONAL
    // If supplied, triggered when handler is unregistered. 
    // Place cleanup code here
    destroy : function() {}

});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.