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!
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
.
- https://developer.mozilla.org/en-US/docs/Web/API/StyleSheetList
- https://developer.mozilla.org/en-US/docs/Web/API/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/
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()}();
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.