I recently had the requirement to swap out all occurrences of the CSS media query max-device-width
with max-width
in Javascript. I wasn’t able to find any resources on how to go about this, so this may be of use for anyone needing to modify media queries on the client side.
My scenario was needing to give an indication of how HTML email content would display on mobile devices. Using IFrame-based tests (e.g. Matt Kersley’s Responsive Design Tests) worked well in most instances, but many responsive email designs use CSS media queries that included max-device-width
. As my IFrames were being viewed on desktop devices with high resolution displays these rules were not being triggered. As it isn’t possible to fake max-device-width
the only alternative was switch it for max-width
.
First we need to get hold of all the stylesheets that the document has loaded and loop through each of them. In turn, we need to loop through every CSS rule and check if any have their type property set to 4 (MEDIA_RULE). This is shown in this function, which returns an array of all the media rules found:
function getCSSMediaRules(doc) {
var stylesheets = doc.styleSheets;
var mediaRules = new Array();
// loop through all CSS files
for (var i in stylesheets) {
if (stylesheets.hasOwnProperty(i)) {
var stylesheets = stylesheets[i];
var stylesheetRules = stylesheets.cssRules;
// for every CSS file, loop through all CSS rules
for (var i in stylesheetRules) {
if (stylesheetRules.hasOwnProperty(i)) {
var stylesheetRule = stylesheetRules[i];
// check CSS rule is a type 4 'MEDIA_RULE'
if (stylesheetRule.type == 4) {
mediaRules.push(stylesheetRule);
}
}
}
}
}
return mediaRules;
}
The DOM only provides methods to add and remove CSS media rules. In my instance I needed to preserve the width value, so removing and adding wasn’t an option. Instead I found editing the rule’s mediaText
property had the desired effect:
function replaceMaxDeviceWidth(rule) {
rule.media.mediaText = rule.media.mediaText.replace(
"max-device-width",
"max-width"
);
}
Many of the properties such as mediaText
have pretty sparse documentation so it’s sometimes easier to debug the rules and mess with them in the console.