├── demo.html ├── readme.md ├── responsive-containers.min.js ├── src └── responsive-containers.js ├── test ├── index.html └── tests.js └── tools └── closure ├── compile.sh └── compiler.jar /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Responsive Containers Test Page 6 | 7 | 8 | 86 | 87 | 88 | 89 |
90 | 91 |

Responsive Containers Test Page

92 |

The two menus below both have identical HTML but are presented differently depending on their current width. At a 'typical' browser width and font size the menu in the smaller column simply lists the links. In the larger column it displays extra images and lays out the options in a grid.

93 |

This is achieved with a small piece of JavaScript, which is activated by the code shown below.

94 |

<ul class="my-list" data-squery="min-width:30em=wide">

95 |

Adding the data-squery attribute above causes a class value of wide to be added to the element when it is wider than 30 ems, and extra CSS is applied to the element based on that class value.

96 |

Currently you can use em or px units.

97 | 98 |
99 | 100 |

Menu

101 | 102 | 124 | 125 |
126 | 127 |
128 | 129 |

Menu

130 | 152 |
153 | 154 | 155 |

Find the code: https://github.com/ahume/selector-queries

156 | 157 |
158 | 159 | 160 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Selector queries and responsive containers 2 | ========================================== 3 | 4 | This script allows you to apply different class values to an HTML element based on its width. Use it as follows: 5 | 6 |
7 |

Content here

8 |
9 | 10 | This will apply a class of `wide` when the element is wider than 400 pixels and a class of `small` when it is narrower than 10 ems. It works in all modern browsers back to and including IE6. 11 | 12 | That's all. -------------------------------------------------------------------------------- /responsive-containers.min.js: -------------------------------------------------------------------------------- 1 | (function(e){function q(){if(p){var b=[];if(f.querySelectorAll)b=f.querySelectorAll("[data-squery]");else for(var a=f.getElementsByTagName("*"),c=0,m=a.length;cel.className.indexOf(d[4])&&(el.className+=" "+d[4]):(d=el.className.replace(RegExp("(^| )"+d[4]+"( |$)"),"$1"), 3 | d=d.replace(/ $/,""),el.className=d)}}}function l(){if(!o){o=!0;q();k();e.addEventListener&&e.addEventListener("resize",k,!1);var b=n(1,f.body);e.setInterval(function(){var a=n(1,f.body);a!==b&&(k(),b=a)},100)}}var f=e.document,j=[],p=!0,o=!1,r={"min-width":function(b,a){return b>a},"max-width":function(b,a){return b b; 113 | }, 114 | "max-width": function(a, b) { 115 | return a < b; 116 | } 117 | } 118 | 119 | function contentReady() { 120 | if (loaded) { 121 | return; 122 | } 123 | loaded = true; 124 | findContainerQueries(); 125 | applyRules(); 126 | if (win.addEventListener) { 127 | win.addEventListener("resize", applyRules, false); 128 | } 129 | // Allow for resizing text after the page has loaded. 130 | var current_em = emsToPixels(1, doc.body); 131 | win.setInterval(function() { 132 | var new_em = emsToPixels(1, doc.body); 133 | if (new_em !== current_em) { 134 | applyRules(); 135 | current_em = new_em; 136 | } 137 | }, 100); 138 | } 139 | 140 | function memoize( f ) { 141 | return function () { 142 | var args = Array.prototype.slice.call(arguments); 143 | f.memoize = f.memoize || {}; 144 | return (args in f.memoize) ? f.memoize[args] : f.memoize[args] = f.apply(this, args); 145 | }; 146 | } 147 | 148 | var emsToPixels = memoize(function(em, scope) { 149 | var test = doc.createElement("div"); 150 | test.style.fontSize = "1em"; 151 | test.style.margin = "0"; 152 | test.style.padding = "0"; 153 | test.style.border = "none"; 154 | test.style.width = "1em"; 155 | scope.appendChild(test); 156 | var val = test.offsetWidth; 157 | scope.removeChild(test); 158 | return Math.round(val * em); 159 | }); 160 | 161 | var getDefaultWidth = function(el, class_name) { 162 | var test = el.cloneNode(true); 163 | test.className = (" " + test.className + " ").replace(" " + class_name + " ", " "); 164 | test.style.height = 0; 165 | test.style.visibility = "hidden"; 166 | test.style.overflow = "hidden"; 167 | test.style.clear = "both"; 168 | var parent = el.parentNode; 169 | parent.insertBefore(test, el); 170 | var val = test.offsetWidth; 171 | parent.removeChild(test); 172 | return val; 173 | } 174 | 175 | if (doc.addEventListener) { 176 | doc.addEventListener("DOMContentLoaded", contentReady, false); 177 | // or 178 | win.addEventListener("load", contentReady, false); 179 | } 180 | // If old IE 181 | else if (doc.attachEvent) { 182 | doc.attachEvent("onreadystatechange", contentReady); 183 | // or 184 | win.attachEvent("onload", contentReady); 185 | } 186 | 187 | 188 | win["SelectorQueries"] = { 189 | "add": add, 190 | "ignoreDataAttributes": ignoreDataAttributes 191 | } 192 | 193 | })(this); 194 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Selector Queries Test Suite 6 | 7 | 8 | 9 | 10 | 22 | 23 | 24 | 25 |

Selector Queries Test Suite

26 |

27 |
28 |

29 |
    30 | 31 | 32 |
    33 |
    34 | 35 | 36 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | window.onload = function() { 2 | 3 | var test_small = document.getElementById("test-small"); 4 | var test_big = document.getElementById("test-big"); 5 | 6 | test("big element has a wide class name", function() { 7 | ok(test_big.className.indexOf("wide"), "Value should be wide"); 8 | }); 9 | 10 | test("small element has no wide class name", function() { 11 | equal(test_small.className.indexOf("wide"), -1, "Value should not be wide"); 12 | }); 13 | } -------------------------------------------------------------------------------- /tools/closure/compile.sh: -------------------------------------------------------------------------------- 1 | java -jar compiler.jar --js ../../src/responsive-containers.js --js_output_file ../../responsive-containers.min.js -------------------------------------------------------------------------------- /tools/closure/compiler.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahume/selector-queries/41683510ecb9ec33618a5c91fd4783e4a5207316/tools/closure/compiler.jar --------------------------------------------------------------------------------