CSSplus

A family of CSS Reprocessor Plugins

About CSSplus

CSSplus is a family of CSS reprocessing plugins that give you more power when writing CSS. It's called “CSSplus” because it's CSS plus 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.

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.

If you're looking for a little more 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 EQCSS, a CSS reprocessor that runs all browsers IE8 and up.

Plugins

Included are the following plugins:

How to use CSSplus

Github

You can download CSSPlus from Github: CSSplus on Github

NPM

If you are using CSSplus on NPM you can include all CSSplus plugins by including the entire package:

const cssplus = require('cssplus')

This will import all CSSplus plugins and make them available to be used in your own code as:

But if you want to include the plugins individually, you can use the module/submodule syntax:

const selectory = require('cssplus/selectory')

And this means the Selectory plugin is available to be used in your code as:

selectory.load()

Global JavaScript

To include CSSplus plugins globally (outside of a bundler like Webpack or Browserify) you must include a <script> 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:

<script src=cssplus/selectory.js></script>

To include all CSSplus plugins, you'll need to include links to the following files:

Aspecty

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.

By default, Aspecty will reprocess aspect ratios by watching the following events:

For any element with an aspect ratio defined, event listeners will be added to reprocess the styles on the following events:

To run Aspecty whenever you want, use the aspecty.load() function in JS.

The aspect ratio property can be used in CSS with the property name --aspect-ratio and a ratio, expressed as width and height as unitless numbers, separated by a slash /:

--aspect-ratio: width/height;

You can use it in CSS like this:

div {
  background: lime;
  --aspect-ratio: 16/9;
}

Aspecty will look through the document for any element matching the selector (in this case div) and create a new rule with a height value calculated based on each matching element's offsetWidth divided by the aspect ratio defined in CSS. To animate the effect of the --aspect-ratio property, which is actually applying via height, it is necessary to set a transition on the height property like this:

transition: height .2s ease-in-out;

Test available at: test/aspecty.html

Cursory

Cursory is a CSS reprocessor that makes the following JS values available as CSS variables:

These can be used as CSS variables with the following names:

These variables are updated at the following events:

In addition, the --clicked variable is changed from 0 to 1 between the mousedown and touchstart events and the corresponding mouseup or touchend events. This allows you to use the var(--clicked) ratio as a 1 or 0 in your CSS calc() functions, or as a value for opacity:; fairly easily.

To run Cursory whenever you want, use the cursory() function in JS.

To make an element like div follow the cursor position when using cursory, use CSS with variables like this:

div {
  width: 10px;
  height: 10px;
  position: fixed;
  background: black;
  top: calc(var(--cursorY) * 1px);
  left: calc(var(--cursorX) * 1px);
}

Test available at: test/cursory.html

Scrollery

Scrollery is a CSS reprocessor that makes the following JS values available as CSS variables for any element you tell the plugin to watch:

To have scrollery watch an element, you need to give that element a unique identifier, as well as add the data-scrollery attribute. The plugin will use either the value of the data-scrollery attribute, or else the value of the id (if defined) for an element.

By default, Scrollery will watch zero elements. If you add a data-scrollery attribute to either the <html> or <body> element it will attach an event listener for the scroll event on the window, otherwise if you add the data-scrollery attribute to other elements it will add a scroll listener to that element.

To run Scrollery whenever you want, use the scrollery() function in JS.

<div id=example data-scrollery></div>

And the following example are both equivalent, and resolve to a name of example:

<div data-scrollery=example></div>

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: --name-value, for example:

Test available at: test/scrollery.html

Selectory

Selectory is a CSS reprocessor that resolves selectors using JS. This plugin will read CSS selectors that end with a [test] 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 1 == 1 will always resolve to true, so a selector written for div[test="1 == 1"] {} will always apply to each div element.

By default, Selectory will reprocess selectors by watching the following events:

To run Selectory whenever you want, use the selectory() function in JS.

Other things you can do with Selectory include, appling a rule to a div when it is wider than 300px:

div[test="this.offsetWidth > 300"] {
  background: orange;
}

Apply a rule to an input when its value="" attribute is greater than 30:

input[test="this.value > 30"] {
  background: lime;
}

Apply a rule to an input when it has a value="" attribute zero characters long:

input[test="this.value.length == 0"] {
  background: purple;
}

Apply a rule to an input when its value="" attribute is more than 5 characters long:

input[test="5 < this.value.length"] {
  background: turquoise;
}

Apply a rule to an h3 element when it contains at least one span element:

h3[test="(this.querySelector('span'))"] {
  color: red;
}

It is limited what selectors you can use with Selectory, things like :hover 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 selector[test=""] {} with a simple selector is best.

Test available at: test/selectory.html

Varsity

Varsity is a CSS reprocessor that makes the following JS values available as CSS variables for any element you tell the plugin to watch:

By default, Varsity will reprocess selectors by watching the following events:

To run Varsity whenever you want, use the varsity() function in JS.

To have varsity watch an element, you need to give that element a unique identifier, as well as add the data-varsity attribute. The plugin will use either the value of the data-varsity attribute, or else the value of the id (if defined) for an element.

<div id=example data-varsity></div>

And the following example are both equivalent, and resolve to a name of example:

<div data-varsity=example></div>

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: --name-value, for example:

Test available at: test/varsity.html

XPathy

XPathy is a CSS reprocessor that resolves selectors using XPath. This plugin will read CSS selectors that end with a [xpath] 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 //div will always resolve to div, so a selector written for div [xpath="//div"] {} will always apply to each div div {} element.

By default, XPathy will reprocess selectors by watching the following events:

To run XPathy whenever you want, use the xpathy.load() function in JS.

Other things you can do with XPathy include:

Select all span tags with the XPath //span:

[xpath="//span"] {
  color: violet;
}

Select all elements with a class name of demo-class with the XPath //*[@class='demo-class']:

[xpath="//*[@class='demo-class']"] {
  color: lime;
}

Select an element with a text content of Demo Content with the XPath //*[text()='Demo Content']:

[xpath="//*[text()='Demo Content']"] {
  color: violet;
}

Select the parent element of another element with the XPath /..:

[xpath="//*[@class='child']/.."] {
  border: 1px solid lime;
}

Compare attribute values as numbers with operators like > and <:

[xpath="//*[@data-price > 3]"] {
  color: violet;
}

Select elements based on the number of children they contain with an XPath like //ul[li[4]]:

[xpath="//ul[li[4]]"] {
  color: lime;
}

Test available at: test/xpathy.html

Demos

Cursor Based Box-Shadow

See the Pen Cursor Based Box-Shadow with Varsity + Cursory [CSS Variables] by Tommy Hodgins (@tomhodgins) on CodePen.

Cursory Cursor

See the Pen Cursory - CSS Variable Reprocessor for your Cursor by Tommy Hodgins (@tomhodgins) on CodePen.