4

How could I remove media query loaded from external css file (<link rel="stylesheet" type="text/css" href="XXXX.css" media="screen">)? Note that I cant disable the entire link tag because other important styles are included out of that media query:

body{...}
.container{...}
...
@media(min-width:XXXpx) {
....
}
...

Thank you!

0

3 Answers 3

4

I strongly recommend pure CSS solution for this problem, such as defining a new stylesheet overwritting rules you don't want.

#selector {
    color: #000;
}

.some-classs-you-want-to-reserve {/*..*/}

@media only screen and (min-width: 600px) {
    /* unwanted */
    #selector {
        display: none;
    }
}

For example, if you want to mute rules inside @media only screen and (min-width: 600px), simply add a new stylesheet overwritting them to default values:

@media only screen and (min-width: 600px) {
    /* unwanted */
    #selector {
        display: block;
    }
}

If you insist on using Javascript, you can access and modify css rules by iterating document.styleSheets.

document.styleSheets

This is an instance of StyleSheetList, an array-like object. Each item of it represents an external or inline css stylesheet. All rules including media queries can be found inside it.

A brief tree structure:

- document.styleSheets
   |- CSSStyleSheet
       |- cssRules
       |- media

So here's an example showing how to remove all rules defined inside @media only screen and (min-width: 600px) block:

function removeRule() {
    if(typeof window.CSSMediaRule !== "function") 
        return false; //Your browser doesn't support media query feature

    var s = document.styleSheets, r,
        i, j, k;

    if(!s) return false; //no style sheets found

    // walk throuth css sheets
    for(i=0; i<s.length; i++) {
        // get all rules
        r = s[i].cssRules; 
        if(!r) continue;

        for(j=0; j<r.length; j++) {
            //If there's a rule for media query
            if(r[j] instanceof CSSMediaRule &&
                    r[j].media.mediaText == "only screen and (min-width: 600px)") {
                for(k=0; k<r[j].cssRules.length; k++) {
                    // remove all rules of it
                    r[j].deleteRule(r[j].cssRules[k]);
                }
                return true;
            }
        }
    }
}
removeRule();

Or live fiddle: http://jsfiddle.net/e4h41qm2/

Sign up to request clarification or add additional context in comments.

Comments

2

The fact is, if you delete one media query, another one get's activated. So you have to do a loop till no media query is found:

function removeRule() {
    if (typeof window.CSSMediaRule !== 'function') {
        return false;
    }
    var styleSheets = document.styleSheets;
    var number = 0;

    if (!styleSheets) {
        return false;
    }

    for (i = 0; i < styleSheets.length; i++) {
        var styleSheet = styleSheets[i];
        var rules = styleSheet.cssRules;
        if (!rules) {
            continue;
        }
        for (var j = 0; j < rules.length; j++) {
            var cssText = rules[j].cssText;
            if (cssText.indexOf('@media') === 0) {
                number++;
                styleSheet.deleteRule(j);
            }
        }
    }
    if (number) {
        return number;
    }
    return 0;
}

function removeMediaQueries() {
    var num = removeRule();
    var total = num;
    while (num) {
        num = removeRule();
        total += num;
    }
    if (total) {
        console.info(total + ' media quer' + (total == 1 ? 'y' : 'ies' + ' removed'));
    } else {
        console.info('No media queries removed');
    }
}
removeMediaQueries();

If you put all this in one line you can generate a bookmark in your browser and have a fast way to test the design without media queries. Very useful for newsletter.

javascript:!function(){function e(){if("function"!=typeof window.CSSMediaRule)return!1;var e=document.styleSheets,n=0;if(!e)return!1;for(i=0;i<e.length;i++){var o=e[i],r=o.cssRules;if(r)for(var t=0;t<r.length;t++){var f=r[t].cssText;0===f.indexOf("@media")&&(n++,o.deleteRule(t))}}return n?n:0}function n(){for(var i=e(),n=i;i;)i=e(),n+=i;n?console.info(n+" media quer"+(1==n?"y":"ies removed")):console.info("No media queries removed")}n()}();

Comments

0

You're probably better off overriding it instead of trying to delete it, but if you must:

style = document.styleSheets[0]; // or whatever stylesheet you want

[].forEach.call(style.cssRules || [], function(rule, i) {
    if (!rule.cssText.indexOf('@media(min-width:XXXpx') {
        style.deleteRule(i);
    }
});

Untested.

1 Comment

StyleSheetList doesn't have forEach method. You should use for loop or [].forEach.call(document.styleSheets, function() { /*...*/ });

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.