-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.html
431 lines (412 loc) · 19.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
<!DOCTYPE html>
<meta name=viewport content="width=device-width, initial-scale=1">
<meta name=description content="CSSplus is a family of CSS reprocessor plugins that give you more power when writing CSS.">
<meta name=keywords content="cssplus, css reprocessor, reprocessor, plugin, polyfill, aspecty, cursory, scrollery, selectory, varsity, xpathy element queries, container queries, scoped styles, css variables, variables, parent selector, attribute">
<link href="https://fonts.googleapis.com/css?family=Fruktur|Source+Code+Pro:400,500,600,700,900|Source+Sans+Pro:400,400i,600,600i,700,700i,900,900i" rel=stylesheet>
<title>CSSplus - A family of CSS Reprocessor Plugins</title>
<style>
* {
box-sizing: border-box;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-kerning: auto;
}
body {
margin: 0;
}
html {
font-family: 'Source Sans Pro', sans-serif;
font-weight: 400;
font-size: 10pt;
line-height: 1.7;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0 auto;
padding: 1em;
max-width: 800px;
}
code,
pre {
color: white;
font-size: 14pt;
font-weight: 600;
position: relative;
background-color: rgba(0,0,0,.4);
text-shadow: rgba(0,0,0,.2) .1em .1em 0;
font-family: 'Source Code Pro', monospace;
}
pre code {
background: none;
}
pre code:before {
display: none;
}
code:before,
pre:before {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: hsl(var(--cursorY), 100%, 75%);
z-index: -1;
opacity: .2;
}
code {
display: inline-block;
padding: .125em .5em;
word-break: break-word;
}
p code {
margin: -.125em .125em;
}
li code {
padding: .5em;
}
pre {
width: 100%;
padding: 1em;
word-break: break-all;
word-wrap:break-word;
overflow-x: auto;
}
li {
margin: .25em;
}
a {
color: hsl(var(--cursorY), 50%, 25%);
font-size: 14pt;
}
a:hover {
color: hsl(var(--cursorY), 50%, 15%);
}
:target {
color: hsl(var(--cursorY), 75%, 50%);
}
svg {
display: block;
margin: 3em auto;
width: 350px;
fill: hsl(var(--cursorY), 75%, 75%);
}
h1, h2, h3, h4, h5, h6 {
font-weight: 600;
line-height: 1.2;
margin: 0 0 .5em 0;
font-family: 'Fruktur', cursive;
}
h1 {
text-align: center;
font-weight: 700;
font-size: 50pt;
margin: 0 0 .125em 0;
}
.tagline {
display: block;
text-align: center;
font-size: 14pt;
opacity: .5;
}
h2 {
font-size: 24pt;
margin: 1em 0 .5em 0;
}
h3 {
font-size: 20pt;
margin: 1em 0 .5em 0;
}
h3 span {
font-family: 'Source Code Pro', sans-serif;
font-size: 80%;
margin-left: .25em;
opacity: .6;
}
p, ul {
font-size: 14pt;
}
footer {
color: rgba(0,0,0,.6);
margin-top: 1em;
padding: 1em;
text-align: center;
}
footer, footer a {
font-size: 12pt;
}
footer span {
display: block;
}
@media (min-width: 700px) {
h1 {
font-size: 64pt;
}
.tagline {
font-size: 18pt;
}
h2 {
font-size: 34pt;
}
h3 {
font-size: 24pt;
}
footer span {
display: inline;
}
footer span + span:before {
content: ', ';
}
}
</style>
<svg id=logo xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 300">
<path d="M 100 0 H 300 V 100 H 200 V 200 H 300 V 300 H 100 V 200 H 0 V 100 H 100 Z"/>
<path d="M 400 0 H 700 V 100 H 600 V 300 H 400 V 200 H 500 V 100 H 400 Z"/>
</svg>
<h1>CSSplus</h1>
<span class=tagline>A family of CSS Reprocessor Plugins</span>
<h2 id=about>About CSSplus</h2>
<p>CSSplus is a family of CSS reprocessing plugins that give you more power when writing CSS. It's called “CSSplus” because it's CSS <em>plus</em> JavaScript, the method most of these plugins use to add power to CSS is by having JavaScript dynamically update CSS variables with information about the browser and elements.</p>
<p>By creating a library of single-purpose plugins, CSSplus makes it simple to use only what you need. Each plugin has been designed with the other plugins in mind, so you can use them in tandem in any combination with each other without worry that they will conflict.</p>
<p>If you're looking for a little <em>more</em> power than what CSSplus offers or you want to use similar functionality in browsers that don't support CSS variables, everything CSSplus does (and more) is also possible with <a href=http://elementqueries.com>EQCSS</a>, a CSS reprocessor that runs all browsers IE8 and up.</p>
<h2 id=plugins>Plugins</h2>
<p>Included are the following plugins:</p>
<ul>
<li><a href=#aspecty><strong>Aspecty:</strong> an aspect-ratio property</a>
<li><a href=#cursory><strong>Cursory:</strong> mouse/touch cursor variables</a>
<li><a href=#scrollery><strong>Scrollery:</strong> scroll position variables</a>
<li><a href=#selectory><strong>Selectory:</strong> a selector resolver</a>
<li><a href=#varsity><strong>Varsity:</strong> scoped variables</a>
<li><a href=#xpathy><strong>XPathy:</strong> Xpath selectors in CSS</a>
</ul>
<h2 id=how>How to use CSSplus</h2>
<h3 id=Github>Github</h3>
<p>You can download CSSPlus from Github: <a href=https://github.com/tomhodgins/cssplus> CSSplus on Github</a></p>
<h3 id=npm>NPM</h3>
<p>If you are using <a href=http://npmjs.com/package/cssplus>CSSplus on NPM</a> you can include all CSSplus plugins by including the entire package:</p>
<pre><code>const cssplus = require('cssplus')</code></pre>
<p>This will import all CSSplus plugins and make them available to be used in your own code as:</p>
<ul>
<li><code>cssplus.aspecty</code>
<li><code>cssplus.cursory</code>
<li><code>cssplus.scrollery</code>
<li><code>cssplus.selectory</code>
<li><code>cssplus.varsity</code>
<li><code>cssplus.xpathy</code>
</ul>
<p>But if you want to include the plugins individually, you can use the <code>module/submodule</code> syntax:</p>
<pre><code>const selectory = require('cssplus/selectory')</code></pre>
<p>And this means the Selectory plugin is available to be used in your code as:</p>
<pre><code>selectory.load()</code></pre>
<h3 id=global>Global JavaScript</h3>
<p>To include CSSplus plugins globally (outside of a bundler like Webpack or Browserify) you must include a <code><script></code> tag to each plugin you want to use. If you want to include just Selectory for example you would include just the one file like this:</p>
<pre><code><script src=cssplus/selectory.js></script></code></pre>
<p>To include all CSSplus plugins, you'll need to include links to the following files:</p>
<ul>
<li><code><script src=cssplus/aspecty.js></script></code>
<li><code><script src=cssplus/cursory.js></script></code>
<li><code><script src=cssplus/scrollery.js></script></code>
<li><code><script src=cssplus/selectory.js></script></code>
<li><code><script src=cssplus/varsity.js></script></code>
<li><code><script src=cssplus/xpathy.js></script></code>
</ul>
<h3 id=aspecty>Aspecty</h3>
<p>Aspecty is a CSS reprocessor that adds support for an aspect-ratio property using JS. This plugin allows you to define a desired aspect-ratio for an element, based on its rendered width on the page.</p>
<p>By default, Aspecty will reprocess aspect ratios by watching the following events:</p>
<ul>
<li><code>load</code>
<li><code>resize</code>
<li><code>input</code>
<li><code>click</code>
</ul>
<p>For any element with an aspect ratio defined, event listeners will be added to reprocess the styles on the following events:</p>
<ul>
<li><code>mouseenter</code>
<li><code>mouseleave</code>
<li><code>mousedown</code>
<li><code>mouseup</code>
<li><code>focus</code>
<li><code>blur</code>
</ul>
<p>To run Aspecty whenever you want, use the <code>aspecty.load()</code> function in JS.</p>
<p>The aspect ratio property can be used in CSS with the property name <code>--aspect-ratio</code> and a ratio, expressed as width and height as unitless numbers, separated by a slash <code>/</code>:</p>
<pre><code>--aspect-ratio: width/height;</code></pre>
<p>You can use it in CSS like this:</p>
<pre><code>div {
background: lime;
--aspect-ratio: 16/9;
}</code></pre>
<p>Aspecty will look through the document for any element matching the selector (in this case <code>div</code>) and create a new rule with a <code>height</code> value calculated based on each matching element's <code>offsetWidth</code> divided by the aspect ratio defined in CSS. To animate the effect of the <code>--aspect-ratio</code> property, which is actually applying via <code>height</code>, it is necessary to set a <code>transition</code> on the <code>height</code> property like this:</p>
<pre><code>transition: height .2s ease-in-out;</code></pre>
<p>Test available at: <a href=test/aspecty.html>test/aspecty.html</a></p>
<h3 id=cursory>Cursory</h3>
<p>Cursory is a CSS reprocessor that makes the following JS values available as CSS variables:</p>
<ul>
<li><code>cursorX</code>
<li><code>cursorY</code>
<li><code>innerWidth</code>
<li><code>innerHeight</code>
<li><code>clicked</code>
</ul>
<p>These can be used as CSS variables with the following names:</p>
<ul>
<li><code>--cursorX</code>
<li><code>--cursorY</code>
<li><code>--innerWidth</code>
<li><code>--innerHeight</code>
<li><code>--clicked</code>
</ul>
<p>These variables are updated at the following events:</p>
<ul>
<li><code>mousemove</code>
<li><code>touchmove</code>
</ul>
<p>In addition, the <code>--clicked</code> variable is changed from <code>0</code> to <code>1</code> between the <code>mousedown</code> and <code>touchstart</code> events and the corresponding <code>mouseup</code> or <code>touchend</code> events. This allows you to use the <code>var(--clicked)</code> ratio as a <code>1</code> or <code>0</code> in your CSS <code>calc()</code> functions, or as a value for <code>opacity:;</code> fairly easily.</p>
<p>To run Cursory whenever you want, use the <code>cursory()</code> function in JS.</p>
<p>To make an element like div follow the cursor position when using cursory, use CSS with variables like this:</p>
<pre><code>div {
width: 10px;
height: 10px;
position: fixed;
background: black;
top: calc(var(--cursorY) * 1px);
left: calc(var(--cursorX) * 1px);
}</code></pre>
<p>Test available at: <a href=test/cursory.html>test/cursory.html</a></p>
<h3 id=scrollery>Scrollery</h3>
<p>Scrollery is a CSS reprocessor that makes the following JS values available as CSS variables for any element you tell the plugin to watch:</p>
<ul>
<li><code>scrollWidth</code>
<li><code>scrollHeight</code>
<li><code>scrollLeft</code>
<li><code>scrollTop</code>
</ul>
<p>To have scrollery watch an element, you need to give that element a unique identifier, as well as add the <code>data-scrollery</code> attribute. The plugin will use either the value of the <code>data-scrollery</code> attribute, or else the value of the <code>id</code> (if defined) for an element.</p>
<p>By default, Scrollery will watch zero elements. If you add a <code>data-scrollery</code> attribute to either the <code><html></code> or <code><body></code> element it will attach an event listener for the <code>scroll</code> event on the <code>window</code>, otherwise if you add the <code>data-scrollery</code> attribute to other elements it will add a <code>scroll</code> listener to that element.</p>
<p>To run Scrollery whenever you want, use the <code>scrollery()</code> function in JS.</p>
<pre><code><div id=example data-scrollery></div></code></pre>
<p>And the following example are both equivalent, and resolve to a name of <code>example</code>:</p>
<pre><code><div data-scrollery=example></div></code></pre>
<p>Once the plugin is aware of an element to watch, and the unique name of that element, it will make the above values available in the following format: <code>--name-value</code>, for example:</p>
<ul>
<li><code>--example-scrollWidth</code>
<li><code>--example-scrollHeight</code>
<li><code>--example-scrollTop</code>
<li><code>--example-scrollLeft</code>
</ul>
<p>Test available at: <a href=test/scrollery.html>test/scrollery.html</a></p>
<h3 id=selectory>Selectory</h3>
<p>Selectory is a CSS reprocessor that resolves selectors using JS. This plugin will read CSS selectors that end with a <code>[test]</code> attribute and use JavaScript to determine whether or not to apply that style to elements matching the other part of that selector. For example, the JS test <code>1 == 1</code> will always resolve to <code>true</code>, so a selector written for <code>div[test="1 == 1"] {}</code> will always apply to each <code>div</code> element.</p>
<p>By default, Selectory will reprocess selectors by watching the following events:</p>
<ul>
<li><code>load</code>
<li><code>resize</code>
<li><code>input</code>
<li><code>click</code>
</ul>
<p>To run Selectory whenever you want, use the selectory() function in JS.</p>
<p>Other things you can do with Selectory include, appling a rule to a <code>div</code> when it is wider than <code>300px</code>:</p>
<pre><code>div[test="this.offsetWidth > 300"] {
background: orange;
}</code></pre>
<p>Apply a rule to an input when its <code>value=""</code> attribute is greater than <code>30</code>:</p>
<pre><code>input[test="this.value > 30"] {
background: lime;
}</code></pre>
<p>Apply a rule to an input when it has a <code>value=""</code> attribute zero characters long:</p>
<pre><code>input[test="this.value.length == 0"] {
background: purple;
}</code></pre>
<p>Apply a rule to an input when its <code>value=""</code> attribute is more than <code>5</code> characters long:</p>
<pre><code>input[test="5 < this.value.length"] {
background: turquoise;
}</code></pre>
<p>Apply a rule to an <code>h3</code> element when it contains at least one <code>span</code> element:</p>
<pre><code>h3[test="(this.querySelector('span'))"] {
color: red;
}</code></pre>
<p>It is limited what selectors you can use with Selectory, things like <code>:hover</code> and pseudo-classes tend not to work as well. As well the parsing only allows for 1 test per selector, and complex selectors may not work as intended. Using <code>selector[test=""] {}</code> with a simple selector is best.</p>
<p>Test available at: <a href=test/selectory.html>test/selectory.html</a></p>
<h3 id=varsity>Varsity</h3>
<p>Varsity is a CSS reprocessor that makes the following JS values available as CSS variables for any element you tell the plugin to watch:</p>
<ul>
<li><code>offsetWidth</code>
<li><code>offsetHeight</code>
<li><code>offsetLeft</code>
<li><code>offsetTop</code>
<li><code>aspect-ratio</code>
<li><code>characters</code>
<li><code>children</code>
<li><code>value</code>
</ul>
<p>By default, Varsity will reprocess selectors by watching the following events:</p>
<ul>
<li><code>load</code>
<li><code>resize</code>
<li><code>input</code>
<li><code>click</code>
</ul>
<p>To run Varsity whenever you want, use the <code>varsity()</code> function in JS.</p>
<p>To have varsity watch an element, you need to give that element a unique identifier, as well as add the <code>data-varsity</code> attribute. The plugin will use either the value of the <code>data-varsity</code> attribute, or else the value of the <code>id</code> (if defined) for an element.</p>
<pre><code><div id=example data-varsity></div></code></pre>
<p>And the following example are both equivalent, and resolve to a name of <code>example</code>:</p>
<pre><code><div data-varsity=example></div></code></pre>
<p>Once the plugin is aware of an element to watch, and the unique name of that element, it will make the above values available in the following format: <code>--name-value</code>, for example:</p>
<ul>
<li><code>--example-offsetWidth</code>
<li><code>--example-offsetHeight</code>
<li><code>--example-offsetLeft</code>
<li><code>--example-offsetTop</code>
<li><code>--example-aspect-ratio</code>
<li><code>--example-characters</code>
<li><code>--example-children</code>
<li><code>--example-value</code>
</ul>
<p>Test available at: <a href=test/varsity.html>test/varsity.html</a></p>
<h2 id=xpathy>XPathy</h2>
<p>XPathy is a CSS reprocessor that resolves selectors using XPath. This plugin will read CSS selectors that end with a <code>[xpath]</code> attribute and use JavaScript and XPath to determine whether or not to apply that style to elements matching the other part of that selector. For example, the XPath selector <code>//div</code> will always resolve to <code>div</code>, so a selector written for <code>div [xpath="//div"] {}</code> will always apply to each <code>div div {}</code> element.</p>
<p>By default, XPathy will reprocess selectors by watching the following events:</p>
<ul>
<li><code>load</code>
<li><code>resize</code>
<li><code>input</code>
<li><code>click</code>
</ul>
<p>To run XPathy whenever you want, use the <code>xpathy.load()</code> function in JS.</p>
<p>Other things you can do with XPathy include:</p>
<p>Select all <code>span</code> tags with the XPath <code>//span</code>:</p>
<pre><code>[xpath="//span"] {
color: violet;
}</code></pre>
<p>Select all elements with a class name of <code>demo-class</code> with the XPath <code>//*[@class='demo-class']</code>:</p>
<pre><code>[xpath="//*[@class='demo-class']"] {
color: lime;
}</code></pre>
<p>Select an element with a text content of <code>Demo Content</code> with the XPath <code>//*[text()='Demo Content']</code>:</p>
<pre><code>[xpath="//*[text()='Demo Content']"] {
color: violet;
}</code></pre>
<p>Select the parent element of another element with the XPath <code>/..</code>:</p>
<pre><code>[xpath="//*[@class='child']/.."] {
border: 1px solid lime;
}</code></pre>
<p>Compare attribute values as numbers with operators like <code>></code> and <code><</code>:</p>
<pre><code>[xpath="//*[@data-price > 3]"] {
color: violet;
}</code></pre>
<p>Select elements based on the number of children they contain with an XPath like <code>//ul[li[4]]</code>:</p>
<pre><code>[xpath="//ul[li[4]]"] {
color: lime;
}</code></pre>
<p>Test available at: <a href=http://tomhodgins.github.io/cssplus/test/xpathy.html>test/xpathy.html</a></p>
<h2 id=demos>Demos</h2>
<h3 id=cursor-based-box-shadow>Cursor Based Box-Shadow</h3>
<p data-height="300" data-theme-id="26478" data-slug-hash="RVLzZB" data-default-tab="css,result" data-user="tomhodgins" data-embed-version="2" data-pen-title="Cursor Based Box-Shadow with Varsity + Cursory [CSS Variables]" class="codepen">See the Pen <a href="http://codepen.io/tomhodgins/pen/RVLzZB/">Cursor Based Box-Shadow with Varsity + Cursory [CSS Variables]</a> by Tommy Hodgins (<a href="http://codepen.io/tomhodgins">@tomhodgins</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
<h3 id=cursory-demo>Cursory Cursor</h3>
<p data-height="300" data-theme-id="26478" data-slug-hash="xdXdpZ" data-default-tab="js,result" data-user="tomhodgins" data-embed-version="2" data-pen-title="Cursory - CSS Variable Reprocessor for your Cursor" class="codepen">See the Pen <a href="http://codepen.io/tomhodgins/pen/xdXdpZ/">Cursory - CSS Variable Reprocessor for your Cursor</a> by Tommy Hodgins (<a href="http://codepen.io/tomhodgins">@tomhodgins</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
<footer><span>Designed with ♥ by <a href=http://twitter.com/innovati>Tommy Hodgins</a></span><span>Hosted on <a href=https://github.com/tomhodgins/cssplus>Github</a></span></footer>
<script src=cursory.js></script>