element-match-media
Version:
Like window.matchMedia() but for HTML elements
226 lines (200 loc) • 5.03 kB
HTML
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Element Query Property (with jsincss)</title>
<style>
body style {
display: block;
width: 100%;
padding: 1em;
margin: 1em 0px 2em;
border-radius: 3px;
font-size: 12pt;
font-family: monospace;
word-break: break-word;
white-space: pre-wrap;
font-kerning: auto;
color: rgba(0, 0, 0, 0.7);
background: transparent;
border: 1px solid rgba(0, 0, 0, 0.3);
}
* {
box-sizing: border-box;
text-rendering: optimizelegibility;
-webkit-font-smoothing: antialiased;
font-kerning: auto;
}
body {
margin: 1em;
font-family: sans-serif;
}
[data-button] {
display: block;
margin: 1em 0px;
}
div {
display: inline-block;
border-radius: 0.2em;
padding: 1.5em;
color: rgb(85, 85, 85);
font-size: 12pt;
line-height: 1.4;
background: rgb(238, 238, 238);
border: 4px solid rgb(204, 204, 204);
}
input,
textarea {
display: block;
min-width: 250px;
border-radius: 0.2em;
margin: 1em;
padding: 0.5em;
color: rgb(85, 85, 85);
font-size: 12pt;
background: white;
border: 4px solid rgb(204, 204, 204);
}
section {
height: 300px;
display: inline-block;
border: 4px dotted lightskyblue;
padding: 1em;
}
img {
max-width: 50px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 0.2em 0.5em;
}
img + img {
margin-left: 1em;
}
p {
font-size: 10pt;
color: rgb(85, 85, 85);
}
[class*="-scroll-x"] {
overflow-x: scroll;
}
[class*="-scroll-x"] p {
width: 200%;
}
[class*="-scroll-y"] {
height: 100px;
overflow-y: scroll;
}
[data-drag] {
overflow: auto;
}
[data-drag="horizontal"] {
resize: horizontal;
}
[data-drag="vertical"] {
resize: vertical;
}
[data-drag="both"] {
resize: both;
}
</style>
<h1>Element Query Property (with jsincss)</h1>
<h2>Width Queries</h2>
<h3 id=min-width>min-width</h3>
<div class=minwidth data-drag=horizontal>class="minwidth"</div>
<h3 id=max-with>max-width</h3>
<div class=maxwidth data-drag=horizontal>class="maxwidth"</div>
<h2>Height Queries</h2>
<h3 id=min-height>min-height</h3>
<div class=minheight data-drag=vertical>class="minheight"</div>
<h3 id=max-height>max-height</h3>
<div class=maxheight data-drag=vertical>class="maxheight"</div>
<h2>Aspect Ratio queries</h2>
<h3 id=orientation>orientation</h3>
<div class=portrait style="width: 100px; height: 200px;">100 × 200</div>
<div class=landscape style="width: 200px; height: 100px;">200 × 100</div>
<h3 id=min-aspect-ratio>min-aspect-ratio</h3>
<div class=minaspectratio data-drag=both>class="minaspectratio"</div>
<h3 id=max-aspect-ratio>max-aspect-ratio</h3>
<div class=maxaspectratio data-drag=both>class="maxaspectratio"</div>
<style>
/* Min-width */
.minwidth {
--breakpoint: (min-width: 300px) {
border-color: limegreen;
background: greenyellow;
};
}
/* Max-width */
.maxwidth {
--breakpoint: (max-width: 300px) {
border-color: limegreen;
background: greenyellow;
};
}
/* Min-height */
.minheight {
--breakpoint: (min-height: 300px) {
border-color: limegreen;
background: greenyellow;
};
}
/* Max-height */
.maxheight {
--breakpoint: (max-height: 300px) {
border-color: limegreen;
background: greenyellow;
};
}
/* Portrait Orientation */
.portrait {
--breakpoint: (orientation: portrait) {
border-color: teal;
background: darkturquoise;
};
}
/* Landscape Orientation */
.landscape {
--breakpoint: (orientation: landscape) {
border-color: darkorchid;
background: orchid;
};
}
/* Min-aspect ratio */
.minaspectratio {
--breakpoint: (min-aspect-ratio: 16/9) {
border-color: limegreen;
background: greenyellow;
};
}
/* Max-aspect-ratio */
.maxaspectratio {
--breakpoint: (max-aspect-ratio: 16/9) {
border-color: limegreen;
background: greenyellow;
};
}
</style>
<script type=module>
import jsincss from 'https://unpkg.com/jsincss/index.vanilla.js'
import {process, property} from 'https://unpkg.com/cssomtools'
import elementMatchMedia from '../index.js'
function eqProp() {
let css = ''
process(
property('--breakpoint'),
rule => {
const [query, declaration] = rule.style
.getPropertyValue('--breakpoint')
.split('{')
document.querySelectorAll(rule.selectorText).forEach((tag, index) => {
const attr = (rule.selectorText + query).replace(/\W+/g, '')
if (elementMatchMedia(tag, query).matches) {
tag.dataset[attr] = index
css += `${rule.selectorText}[data-${attr}="${index}"] { ${declaration}`
} else {
tag.dataset[attr] = false
}
})
}
)
return css
}
jsincss(eqProp)
</script>