Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support data- custom HTML attributes #273

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Features:
- no CSS modifications. Valid CSS Syntax
- all CSS selectors available. Uses regular attribute selector. No need to write rules in HTML/JS.
- supports and tested in webkit, gecko and IE(10+)
- `min-width`, `min-height`, `max-width` and `max-height` are supported so far
- `data-min-width`, `data-min-height`, `data-max-width` and `data-max-height` are supported so far and
- for backwards compatibility the HTML non-compliant attributes `min-width`, `min-height`, `max-width` and `max-height` are still supported
- 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
- no Javascript-Framework dependency (works with jQuery, Mootools, etc.)
- Works beautiful for responsive images without FOUC
Expand All @@ -33,25 +34,25 @@ More demos and information: http://marcj.github.io/css-element-queries/
font-size: 12px;
}

.widget-name[min-width~="400px"] h2 {
.widget-name[data-min-width~="400px"] h2 {
font-size: 18px;
}

.widget-name[min-width~="600px"] h2 {
.widget-name[data-min-width~="600px"] h2 {
padding: 55px;
text-align: center;
font-size: 24px;
}

.widget-name[min-width~="700px"] h2 {
.widget-name[data-min-width~="700px"] h2 {
font-size: 34px;
color: red;
}
```

As you can see we use the `~=` [attribute selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors).
Since this css-element-queries polyfill adds new element attributes on the DOM element
(`<div class="widget-name" min-width="400px 700px"></div>`) depending on your actual CSS and element's dimension,
(`<div class="widget-name" data-min-width="400px 700px"></div>`) depending on your actual CSS and element's dimension,
you should always use this attribute selector (especially if you have several element query rules on the same element).

```html
Expand All @@ -64,9 +65,9 @@ you should always use this attribute selector (especially if you have several el

```html
<div data-responsive-image>
<img data-src="http://placehold.it/350x150"/>
<img min-width="350" data-src="http://placehold.it/700x300"/>
<img min-width="700" data-src="http://placehold.it/1400x600"/>
<img data-src="http://placehold.it/350x150"/>
<img data-min-width="350" data-src="http://placehold.it/700x300"/>
<img data-min-width="700" data-src="http://placehold.it/1400x600"/>
</div>
```

Expand Down
20 changes: 11 additions & 9 deletions src/ElementQueries.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
this.element = element;
var key, option, elementSize, value, actualValue, attrValues, attrValue, attrName;

var attributes = ['min-width', 'min-height', 'max-width', 'max-height'];
var attributes = ['min-width', 'data-min-width', 'min-height', 'data-min-height', 'max-width', 'data-max-width', 'max-height', 'data-max-height'];

/**
* Extracts the computed width/height and sets to min/max- attribute.
Expand All @@ -133,7 +133,7 @@
value = convertToPx(this.element, option.value);

actualValue = option.property === 'width' ? elementSize.width : elementSize.height;
attrName = option.mode + '-' + option.property;
attrName = option.attrName;
attrValue = '';

if (option.mode === 'min' && actualValue >= value) {
Expand Down Expand Up @@ -185,8 +185,9 @@
* @param {String} mode min|max
* @param {String} property width|height
* @param {String} value
* @param {String} attrName
*/
function queueQuery(selector, mode, property, value) {
function queueQuery(selector, mode, property, value, attrName) {
if (typeof(allQueries[selector]) === 'undefined') {
allQueries[selector] = [];
// add animation to trigger animationstart event, so we know exactly when a element appears in the DOM
Expand All @@ -200,6 +201,7 @@
allQueries[selector].push({
mode: mode,
property: property,
attrName: attrName,
value: value
});
}
Expand Down Expand Up @@ -336,8 +338,8 @@
}
}

var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mgi;
var attrRegex = /\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi;
var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:data-)?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mgi;
var attrRegex = /\[[\s\t]*?((?:data-)?(min|max)-(width|height))[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi;

/**
* @param {String} css
Expand All @@ -351,7 +353,7 @@
attrs = match[2];

while (null !== (attrMatch = attrRegex.exec(attrs))) {
queueQuery(smatch, attrMatch[1], attrMatch[2], attrMatch[3]);
queueQuery(smatch, attrMatch[2], attrMatch[3], attrMatch[4], attrMatch[1]);
}
}
}
Expand All @@ -368,16 +370,16 @@

if ('string' === typeof rules) {
rules = rules.toLowerCase();
if (-1 !== rules.indexOf('min-width') || -1 !== rules.indexOf('max-width')) {
if (-1 !== rules.indexOf('min-width') || -1 !== rules.indexOf('data-min-width') || -1 !== rules.indexOf('max-width') || -1 !== rules.indexOf('data-max-width')) {
extractQuery(rules);
}
} else {
for (var i = 0, j = rules.length; i < j; i++) {
if (1 === rules[i].type) {
selector = rules[i].selectorText || rules[i].cssText;
if (-1 !== selector.indexOf('min-height') || -1 !== selector.indexOf('max-height')) {
if (-1 !== selector.indexOf('min-height') || -1 !== selector.indexOf('data-min-height') || -1 !== selector.indexOf('max-height') || -1 !== selector.indexOf('data-max-height')) {
extractQuery(selector);
} else if (-1 !== selector.indexOf('min-width') || -1 !== selector.indexOf('max-width')) {
} else if (-1 !== selector.indexOf('min-width') || -1 !== selector.indexOf('data-min-width') || -1 !== selector.indexOf('max-width') || -1 !== selector.indexOf('data-max-width')) {
extractQuery(selector);
}
} else if (4 === rules[i].type) {
Expand Down
40 changes: 20 additions & 20 deletions tests/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@
/*}*/
/*}*/

.widget-name[min-width~="400px"] h2 {
.widget-name[data-min-width~="400px"] h2 {
font-size: 18px;
animation: 1s element ;
}

.widget-name[min-width~="600px"] h2 {
.widget-name[data-min-width~="600px"] h2 {
padding: 55px;
text-align: center;
font-size: 24px;
}

.widget-name[min-width~="700px"] h2 {
.widget-name[data-min-width~="700px"] h2 {
font-size: 34px;
color: red;
}
Expand All @@ -65,18 +65,18 @@
transition:all .2s ease;
}

.example-1[min-width~="400px"] {
.example-1[data-min-width~="400px"] {
padding: 80px;
}

.example-1[min-width~="200px"] {
.example-1[data-min-width~="200px"] {
text-align: left;
font-size: 12px;
}


.example-2[max-width~="300px"] .example-2-first,
.example-2[max-width~="300px"] .example-2-second {
.example-2[data-max-width~="300px"] .example-2-first,
.example-2[data-max-width~="300px"] .example-2-second {
float: none;
background-color: #4186ff;
width: auto;
Expand All @@ -86,15 +86,15 @@
background-color: #ba000d;
}

.example-2[min-width~="200px"] .example-2-box {
.example-2[data-min-width~="200px"] .example-2-box {
background-color: #ba6377;
}

.example-2[min-width~="300px"] .example-2-box {
.example-2[data-min-width~="300px"] .example-2-box {
background-color: #ba9196;
}

.example-2[min-width~="400px"] .example-2-box {
.example-2[data-min-width~="400px"] .example-2-box {
background-color: gray;
}
</style>
Expand Down Expand Up @@ -151,17 +151,17 @@ <h2>Element responsiveness FTW!</h2>
font-size: 12px;
}

.widget-name[min-width~="400px"] h2 {
.widget-name[data-min-width~="400px"] h2 {
font-size: 18px;
}

.widget-name[min-width~="600px"] h2 {
.widget-name[data-min-width~="600px"] h2 {
padding: 55px;
text-align: center;
font-size: 24px;
}

.widget-name[min-width~="700px"] h2 {
.widget-name[data-min-width~="700px"] h2 {
font-size: 34px;
color: red;
}</textarea>
Expand Down Expand Up @@ -226,11 +226,11 @@ <h2>Demo 1</h2>
transition:all .2s ease;
}

.example-1[min-width~="400px"] {
.example-1[data-min-width~="400px"] {
padding: 80px;
}

.example-1[min-width~="200px"] {
.example-1[data-min-width~="200px"] {
text-align: left;
font-size: 12px;
}
Expand Down Expand Up @@ -295,8 +295,8 @@ <h2>Demo 2</h2>
padding: 2px;
}

.example-2[max-width~="300px"] .example-2-first,
.example-2[max-width~="300px"] .example-2-second {
.example-2[data-max-width~="300px"] .example-2-first,
.example-2[data-max-width~="300px"] .example-2-second {
float: none;
background-color: #4186ff;
width: auto;
Expand All @@ -306,15 +306,15 @@ <h2>Demo 2</h2>
background-color: #ba000d;
}

.example-2[min-width~="200px"] .example-2-box {
.example-2[data-min-width~="200px"] .example-2-box {
background-color: #ba6377;
}

.example-2[min-width~="300px"] .example-2-box {
.example-2[data-min-width~="300px"] .example-2-box {
background-color: #ba9196;
}

.example-2[min-width~="400px"] .example-2-box {
.example-2[data-min-width~="400px"] .example-2-box {
background-color: gray;
}</textarea>
</div>
Expand Down