├── .gitignore
├── .npmignore
├── .github
└── FUNDING.yml
├── index.js
├── css-element-queries.d.ts
├── tsconfig.json
├── src
├── ElementQueries.d.ts
├── ResizeSensor.d.ts
├── ResizeSensor.js
└── ElementQueries.js
├── package.json
├── LICENSE
├── tests
├── late-trigger.html
├── mutation
│ ├── app.ts
│ ├── index.html
│ └── app.js
├── demo.js
├── demo.css
└── demo.html
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | tests
3 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: marcj
2 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ResizeSensor: require('./src/ResizeSensor'),
3 | ElementQueries: require('./src/ElementQueries')
4 | };
5 |
--------------------------------------------------------------------------------
/css-element-queries.d.ts:
--------------------------------------------------------------------------------
1 | export { ResizeSensor, ResizeSensorCallback, Size } from "./src/ResizeSensor";
2 | export { ElementQueries } from './src/ElementQueries';
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "downlevelIteration": true,
5 | "lib" : ["dom","es6","dom.iterable","scripthost", "es2015.iterable", "es2015.collection"]
6 | }
7 | }
--------------------------------------------------------------------------------
/src/ElementQueries.d.ts:
--------------------------------------------------------------------------------
1 | export declare class ElementQueries {
2 | /**
3 | * Attaches to DOMLoadContent
4 | */
5 | static listen(): void;
6 |
7 | /**
8 | * Parses all available CSS and attach ResizeSensor to those elements which have rules attached.
9 | * Make sure this is called after 'load' event, because CSS files are not ready when domReady is fired.
10 | */
11 | static init(): void;
12 | }
13 |
14 | export default ElementQueries;
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-element-queries",
3 | "version": "1.2.3",
4 | "description": "CSS-Element-Queries Polyfill. Proof-of-concept for high-speed element dimension/media queries in valid css.",
5 | "main": "index.js",
6 | "typings": "css-element-queries.d.ts",
7 | "directories": {
8 | "test": "test"
9 | },
10 | "scripts": {
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git@github.com:marcj/css-element-queries.git"
16 | },
17 | "author": "Marc J. Schmidt",
18 | "license": "MIT",
19 | "bugs": {
20 | "url": "https://github.com/marcj/css-element-queries/issues"
21 | },
22 | "homepage": "https://github.com/marcj/css-element-queries",
23 | "devDependencies": {
24 | "grunt": "^0.4.5",
25 | "grunt-bump": "^0.3.1"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Marc J. Schmidt
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/src/ResizeSensor.d.ts:
--------------------------------------------------------------------------------
1 | export declare interface Size {
2 | width: number;
3 | height: number;
4 | }
5 |
6 | export declare type ResizeSensorCallback = (size: Size) => void;
7 |
8 | export declare class ResizeSensor {
9 | /**
10 | * Creates a new resize sensor on given elements. The provided callback is called max 1 times per requestAnimationFrame and
11 | * is called initially.
12 | */
13 | constructor(element: Element | Element[], callback: ResizeSensorCallback);
14 |
15 | /**
16 | * Removes the resize sensor, and stops listening to resize events.
17 | */
18 | detach(callback?: ResizeSensorCallback): void;
19 |
20 | /**
21 | * Resets the resize sensors, so for the next element resize is correctly detected. This is rare cases necessary
22 | * when the resize sensor isn't initialised correctly or is in a broken state due to DOM modifications.
23 | */
24 | reset(): void;
25 |
26 | /**
27 | * Removes the resize sensor, and stops listening to resize events.
28 | */
29 | static detach(element: Element | Element[], callback?: ResizeSensorCallback): void;
30 |
31 | /**
32 | * Resets the resize sensors, so for the next element resize is correctly detected. This is rare cases necessary
33 | * when the resize sensor isn't initialised correctly or is in a broken state due to DOM modifications.
34 | */
35 | static reset(element: Element | Element[]): void;
36 | }
37 |
38 | export default ResizeSensor;
39 |
--------------------------------------------------------------------------------
/tests/late-trigger.html:
--------------------------------------------------------------------------------
1 |
2 |
');
86 | container.append(div);
87 |
88 | new ResizeSensor(div, function(){
89 | counter++;
90 | dynamicCounter.html(counter + ' changes.');
91 | });
92 | }
93 | }
94 | }
95 |
96 | function example3(){
97 | var logger = $('#example-3-log');
98 | var box = $('#example-3-box');
99 |
100 | $('#startStop3').on('click', function(){
101 | if (box.hasClass('example-3-box-start')) {
102 | box.removeClass('example-3-box-start');
103 | } else {
104 | box.addClass('example-3-box-start');
105 | }
106 | });
107 | new ResizeSensor(box, function(el){
108 | logger.html('Changed to ' + box[0].clientWidth+'px width.');
109 | });
110 |
111 | }
112 |
113 | function example4(){
114 | var logger = $('#example-4-log');
115 | var box = $('#example-4-box');
116 |
117 | $('#startStop4').on('click', function(){
118 | if (box.hasClass('example-4-box-start')) {
119 | box.removeClass('example-4-box-start');
120 | } else {
121 | box.addClass('example-4-box-start');
122 | }
123 | });
124 | new ResizeSensor(box, function(){
125 | logger.html('Changed to ' + box[0].clientHeight+'px height.');
126 | });
127 | }
128 |
129 | function example5(){
130 | var box = $('#example-5');
131 | var changed = 0;
132 | new ResizeSensor(box.parent(), function(){
133 | box[0].innerHTML = (++changed) + ' changes. ' + box.parent()[0].clientWidth+'px/'+box.parent()[0].clientHeight+'px';
134 | });
135 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSS Element Queries
2 |
3 |
4 | [](https://gitter.im/marcj/css-element-queries?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
5 |
6 | Element Queries is a polyfill adding support for element based media-queries to all new browsers (incl. IE7+).
7 | It allows not only to define media-queries based on window-size but also adds 'media-queries' functionality depending on element (any selector supported)
8 | size while not causing performance lags due to event based implementation.
9 |
10 | It's a proof-of-concept event-based CSS element dimension query with valid CSS selector syntax.
11 |
12 | Features:
13 |
14 | - no performance issues since it listens only on size changes of elements that have element query rules defined through css. Other element query polifills only listen on `window.onresize` which causes performance issues and allows only to detect changes via window.resize event and not inside layout changes like css3 animation, :hover, DOM changes etc.
15 | - no interval/timeout detection. Truly event-based through integrated ResizeSensor class.
16 | - automatically discovers new DOM elements. No need to call javascript manually.
17 | - no CSS modifications. Valid CSS Syntax
18 | - all CSS selectors available. Uses regular attribute selector. No need to write rules in HTML/JS.
19 | - supports and tested in webkit, gecko and IE(10+)
20 | - `min-width`, `min-height`, `max-width` and `max-height` are supported so far
21 | - works with any layout modifications: HTML (innerHTML etc), inline styles, DOM mutation, CSS3 transitions, fluid layout changes (also percent changes), pseudo classes (:hover etc.), window resizes and more
22 | - no Javascript-Framework dependency (works with jQuery, Mootools, etc.)
23 | - Works beautiful for responsive images without FOUC
24 |
25 | More demos and information: http://marcj.github.io/css-element-queries/
26 |
27 | ## Examples
28 |
29 | ### Element Query
30 |
31 | ```css
32 | .widget-name h2 {
33 | font-size: 12px;
34 | }
35 |
36 | .widget-name[min-width~="400px"] h2 {
37 | font-size: 18px;
38 | }
39 |
40 | .widget-name[min-width~="600px"] h2 {
41 | padding: 55px;
42 | text-align: center;
43 | font-size: 24px;
44 | }
45 |
46 | .widget-name[min-width~="700px"] h2 {
47 | font-size: 34px;
48 | color: red;
49 | }
50 | ```
51 |
52 | As you can see we use the `~=` [attribute selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
53 | Since this css-element-queries polyfill adds new element attributes on the DOM element
54 | (``) depending on your actual CSS and element's dimension,
55 | you should always use this attribute selector (especially if you have several element query rules on the same element).
56 |
57 | ```html
58 |
121 | Drag the gray line at the right to see it in action.
122 |
123 |
124 |
125 |
126 |
127 |
Responsive Text
128 |
129 |
130 |
131 |
Element responsiveness FTW!
132 |
133 |
134 |
Element started display: none
135 |
136 |
137 |
138 |
139 |
140 |
Element detachable
141 |
142 |
143 |
144 |
145 |
146 |
Dynamic element {{id}}
147 |
148 |
149 |
150 |
151 |
152 |
153 |
156 |
157 |
158 |
177 |
178 |
179 |
180 |
181 |
Responsive Image
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 | The image above has a default of 700px. Shrink or expend the container too see responsive image
191 | working.
192 | Thanks @placehold.it
193 |
194 |
195 |
196 |
201 |
202 |
203 |
204 |
205 |
Responsive Widget
206 |
207 |
208 |
Demo 1
209 | This is content from the first responsive demo without media queries. It uses the element
210 | queries
211 | provided by this library.
212 |
213 |
214 |
215 |
216 |
224 |
225 |
226 |
247 |
248 |
249 |
250 |
251 |
252 |
Responsive Layout
253 |
254 |
255 |
Demo 2
256 |
257 | Box
258 |
259 |
260 | First 1/2 box
261 |
262 |
263 | Second 1/2 box
264 |
265 |
266 |
267 |
268 |
269 |
284 |
285 |
286 |
329 |
330 |
331 |
332 |
333 |
Responsive Animation
334 |
335 |
336 |
Demo 3 - width
337 |
338 |
339 |
340 | This box is animated through css transitions.
341 | We attached a resize-listener to this box. See below.
342 |
343 |
344 | No changes.
345 |
346 |
347 |
348 |
349 |
350 |
Demo 4 - height
351 |
352 |
353 |
354 | This box is animated through css transitions.
355 | We attached a resize-listener to this box. See below.
356 |
357 |
358 | No changes.
359 |
360 |
361 |
362 |
363 |
364 |
365 |
ResizeSensor Demo
366 |
367 |
368 |
369 | 0 changes
370 |
371 |
372 |
373 |
374 | CSS-Element-Queries comes with a Javascript ResizeSensor class you can use in Javascript directly.
375 |