Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Simple support for EM units in media queries #63

Closed
wants to merge 1 commit into from

1 participant

@jayf

Added support for em units in media queries, with hardcoded conversion of 1em = 16px. Also added: support for decimals in widths, e.g., 55.5em

@jayf

Closing this, as I'm working on this now in the em-support branch. All of the features in this pull request are now rolled up in this newer pull request.

@jayf jayf closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 26, 2011
  1. @jayf
This page is out of date. Refresh to see the latest.
Showing with 20 additions and 4 deletions.
  1. +10 −0 README.md
  2. +2 −2 respond.min.js
  3. +8 −2 respond.src.js
View
10 README.md
@@ -66,6 +66,8 @@ Some notes to keep in mind:
- As you might guess, this implementation is quite dumb in regards to CSS parsing rules. This is a good thing, because that allows it to run really fast, but it's looseness may also cause unexpected behavior. For example: if you enclose a whole media query in a comment intending to disable its rules, you'll probably find that those rules will end up enabled in non-media-query-supporting browsers.
+- WARNING: Really, you need to delete all commented-out media queries from your CSS
+
- Respond.js doesn't parse CSS refrenced via @import, nor does it work with media queries within style elements, as those styles can't be re-requested for parsing.
- Due to security restrictions, some browsers may not allow this script to work on file:// urls (because it uses xmlHttpRequest). Run it on a web server.
@@ -74,6 +76,14 @@ Some notes to keep in mind:
- WARNING: Do not include @font-face rules inside a media query. This will crash IE7 and IE8. Simply place @font-face rules in the wide open, as a sibling to other media queries. Isolated test here to demostrate (note: test crashes IE 7&8): http://jsfiddle.net/scottjehl/Ejyj5/1/
+- Now supporting media queries in EM units, but with a fixed conversion of 1em = 16px
+
+<pre>
+ @media screen and (min-width: 55.5em){
+ ...styles for 55.5em (55.5 x 16 = 888px) and up go here
+ }
+</pre>
+
How's it work?
======
View
4 respond.min.js
@@ -1,2 +1,2 @@
-/*! Respond.js v1.0.1pre: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
-(function(e,h){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=h;if(h){return}var u=e.document,r=u.documentElement,i=[],k=[],p=[],o={},g=30,f=u.getElementsByTagName("head")[0]||r,b=f.getElementsByTagName("link"),d=[],a=function(){var B=b,w=B.length,z=0,y,x,A,v;for(;z<w;z++){y=B[z],x=y.href,A=y.media,v=y.rel&&y.rel.toLowerCase()==="stylesheet";if(!!x&&v&&!o[x]){if(y.styleSheet&&y.styleSheet.rawCssText){m(y.styleSheet.rawCssText,x,A);o[x]=true}else{if(!/^([a-zA-Z]+?:(\/\/)?)/.test(x)||x.replace(RegExp.$1,"").split("/")[0]===e.location.host){d.push({href:x,media:A})}}}}t()},t=function(){if(d.length){var v=d.shift();n(v.href,function(w){m(w,v.href,v.media);o[v.href]=true;t()})}},m=function(G,v,x){var E=G.match(/@media[^\{]+\{([^\{\}]+\{[^\}\{]+\})+/gi),H=E&&E.length||0,v=v.substring(0,v.lastIndexOf("/")),w=function(I){return I.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+v+"$2$3")},y=!H&&x,B=0,A,C,D,z,F;if(v.length){v+="/"}if(y){H=1}for(;B<H;B++){A=0;if(y){C=x;k.push(w(G))}else{C=E[B].match(/@media ([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1;k.push(RegExp.$2&&w(RegExp.$2))}z=C.split(",");F=z.length;for(;A<F;A++){D=z[A];i.push({media:D.match(/(only\s+)?([a-zA-Z]+)(\sand)?/)&&RegExp.$2,rules:k.length-1,minw:D.match(/\(min\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/)&&parseFloat(RegExp.$1),maxw:D.match(/\(max\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/)&&parseFloat(RegExp.$1)})}}j()},l,q,j=function(E){var v="clientWidth",x=r[v],D=u.compatMode==="CSS1Compat"&&x||u.body[v]||x,z={},C=u.createDocumentFragment(),B=b[b.length-1],w=(new Date()).getTime();if(E&&l&&w-l<g){clearTimeout(q);q=setTimeout(j,g);return}else{l=w}for(var y in i){var F=i[y];if(!F.minw&&!F.maxw||(!F.minw||F.minw&&D>=F.minw)&&(!F.maxw||F.maxw&&D<=F.maxw)){if(!z[F.media]){z[F.media]=[]}z[F.media].push(k[F.rules])}}for(var y in p){if(p[y]&&p[y].parentNode===f){f.removeChild(p[y])}}for(var y in z){var G=u.createElement("style"),A=z[y].join("\n");G.type="text/css";G.media=y;if(G.styleSheet){G.styleSheet.cssText=A}else{G.appendChild(u.createTextNode(A))}C.appendChild(G);p.push(G)}f.insertBefore(C,B.nextSibling)},n=function(v,x){var w=c();if(!w){return}w.open("GET",v,true);w.onreadystatechange=function(){if(w.readyState!=4||w.status!=200&&w.status!=304){return}x(w.responseText)};if(w.readyState==4){return}w.send(null)},c=(function(){var v=false;try{v=new XMLHttpRequest()}catch(w){v=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return v}})();a();respond.update=a;function s(){j(true)}if(e.addEventListener){e.addEventListener("resize",s,false)}else{if(e.attachEvent){e.attachEvent("onresize",s)}}})(this,(function(f){if(f.matchMedia){return true}var e,i=document,c=i.documentElement,g=c.firstElementChild||c.firstChild,h=!i.body,d=i.body||i.createElement("body"),b=i.createElement("div"),a="only all";b.id="mq-test-1";b.style.cssText="position:absolute;top:-99em";d.appendChild(b);b.innerHTML='_<style media="'+a+'"> #mq-test-1 { width: 9px; }</style>';if(h){c.insertBefore(d,g)}b.removeChild(b.firstChild);e=b.offsetWidth==9;if(h){c.removeChild(d)}else{d.removeChild(b)}return e})(this));
+/* Respond.js v1.0.1pre: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
+(function(e,h){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=h;if(h){return}var v=e.document,s=v.documentElement,i=[],k=[],q=[],p={},g=30,n=16,f=v.getElementsByTagName("head")[0]||s,b=f.getElementsByTagName("link"),d=[],a=function(){var C=b,x=C.length,A=0,z,y,B,w;for(;A<x;A++){z=C[A],y=z.href,B=z.media,w=z.rel&&z.rel.toLowerCase()==="stylesheet";if(!!y&&w&&!p[y]){if(z.styleSheet&&z.styleSheet.rawCssText){m(z.styleSheet.rawCssText,y,B);p[y]=true}else{if(!/^([a-zA-Z]+?:(\/\/)?)/.test(y)||y.replace(RegExp.$1,"").split("/")[0]===e.location.host){d.push({href:y,media:B})}}}}u()},u=function(){if(d.length){var w=d.shift();o(w.href,function(x){m(x,w.href,w.media);p[w.href]=true;u()})}},m=function(H,w,y){var F=H.match(/@media[^\{]+\{([^\{\}]+\{[^\}\{]+\})+/gi),I=F&&F.length||0,w=w.substring(0,w.lastIndexOf("/")),x=function(J){return J.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+w+"$2$3")},z=!I&&y,C=0,B,D,E,A,G;if(w.length){w+="/"}if(z){I=1}for(;C<I;C++){B=0;if(z){D=y;k.push(x(H))}else{D=F[C].match(/@media ([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1;k.push(RegExp.$2&&x(RegExp.$2))}A=D.split(",");G=A.length;for(;B<G;B++){E=A[B];i.push({media:E.match(/(only\s+)?([a-zA-Z]+)(\sand)?/)&&RegExp.$2,rules:k.length-1,minw:E.match(/\(min\-width:[\s]*([\s]*[0-9]+\.*[0-9]*)(em|px)[\s]*\)/)&&(RegExp.$2=="px"?parseFloat(RegExp.$1):n*parseFloat(RegExp.$1)),maxw:E.match(/\(max\-width:[\s]*([\s]*[0-9]+\.*[0-9]*)(em|px)[\s]*\)/)&&(RegExp.$2=="px"?parseFloat(RegExp.$1):n*parseFloat(RegExp.$1))})}}j()},l,r,j=function(F){var w="clientWidth",y=s[w],E=v.compatMode==="CSS1Compat"&&y||v.body[w]||y,A={},D=v.createDocumentFragment(),C=b[b.length-1],x=(new Date()).getTime();if(F&&l&&x-l<g){clearTimeout(r);r=setTimeout(j,g);return}else{l=x}for(var z in i){var G=i[z];if(!G.minw&&!G.maxw||(!G.minw||G.minw&&E>=G.minw)&&(!G.maxw||G.maxw&&E<=G.maxw)){if(!A[G.media]){A[G.media]=[]}A[G.media].push(k[G.rules])}}for(var z in q){if(q[z]&&q[z].parentNode===f){f.removeChild(q[z])}}for(var z in A){var H=v.createElement("style"),B=A[z].join("\n");H.type="text/css";H.media=z;if(H.styleSheet){H.styleSheet.cssText=B}else{H.appendChild(v.createTextNode(B))}D.appendChild(H);q.push(H)}f.insertBefore(D,C.nextSibling)},o=function(w,y){var x=c();if(!x){return}x.open("GET",w,true);x.onreadystatechange=function(){if(x.readyState!=4||x.status!=200&&x.status!=304){return}y(x.responseText)};if(x.readyState==4){return}x.send(null)},c=(function(){var w=false;try{w=new XMLHttpRequest()}catch(x){w=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return w}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this,(function(f){if(f.matchMedia){return true}var e,i=document,c=i.documentElement,g=c.firstElementChild||c.firstChild,h=!i.body,d=i.body||i.createElement("body"),b=i.createElement("div"),a="only all";b.id="mq-test-1";b.style.cssText="position:absolute;top:-99em";d.appendChild(b);b.innerHTML='_<style media="'+a+'"> #mq-test-1 { width: 9px; }</style>';if(h){c.insertBefore(d,g)}b.removeChild(b.firstChild);e=b.offsetWidth==9;if(h){c.removeChild(d)}else{d.removeChild(b)}return e})(this));
View
10 respond.src.js
@@ -20,6 +20,7 @@
appendedEls = [],
parsedSheets = {},
resizeThrottle = 30,
+ pixelsToEm = 16,
head = doc.getElementsByTagName( "head" )[0] || docElem,
links = head.getElementsByTagName( "link" ),
requestQueue = [],
@@ -121,8 +122,8 @@
mediastyles.push( {
media : thisq.match( /(only\s+)?([a-zA-Z]+)(\sand)?/ ) && RegExp.$2,
rules : rules.length - 1,
- minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/ ) && parseFloat( RegExp.$1 ),
- maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/ ) && parseFloat( RegExp.$1 )
+ minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9]+\.*[0-9]*)(em|px)[\s]*\)/ ) && (RegExp.$2=='px' ? parseFloat( RegExp.$1 ) : pixelsToEm * parseFloat( RegExp.$1 )),
+ maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9]+\.*[0-9]*)(em|px)[\s]*\)/ ) && (RegExp.$2=='px' ? parseFloat( RegExp.$1 ) : pixelsToEm * parseFloat( RegExp.$1 ))
} );
}
}
@@ -232,6 +233,11 @@
//expose update for re-running respond later on
respond.update = ripCSS;
+ //maybe someday expose for adjusting pixelToEm ratio?
+ //would need to re-run translate to be effective
+ //TBD
+ //respond.pixelsToEm = 16;
+
//adjust on resize
function callMedia(){
applyMedia( true );
Something went wrong with that request. Please try again.