/v-helper

A shorter SCSS access to CSS custom properties.

Primary LanguageSCSSDo What The F*ck You Want To Public LicenseWTFPL

v.scss

v.scss brings a single SCSS function for shorter access (4 characters saved!) to CSS custom properties : v(propName) instead of var(--propName). It also improves fallbacks chaining.

Note

This helper has cool features, but I have decided to not use it outside of personal projects. Compared to IDE auto-completion, its benefits might not be worth the cognitive load linked to an additional abstraction.

Table of contents

Installation

  1. npm install v.scss pulls the package into your project.
  2. @import '~v.scss'; in a SCSS files makes v() available.

Usage

Declare your CSS custom properties as you usually do:

:root {
  --primary: #000;
  --bg: #fff;
}

Then, access them with v().

html {
  background: v(bg);
  color: v(primary);
}

That’s it! Here’s the generated CSS:

html {
  background: var(--bg);
  color: var(--primary);
}

Fallback value as optional second parameter

The CSS var() function can take a fallback value as second parameter: if the wanted custom property isn’t defined or valid for the browser, the fallback will be used.

:root {
  --primary: cyan;
  --bg: #433221;
}

html {
  background: v(bg, brown); // `background: var(--bg, brown);`
  color: v(primaryyyy, yellow); // `color: var(--primaryyyy, yellow);`
}

The background will be #433221 (--bg value) but the color will be yellow because --primaryyyy doesn’t exist.

Note

If you need the last parameter to be a string, wrap its quotes in more quotes:

.shrug::after {
  content: v(shrug-emoji, "\_(ツ)_/¯'"); /* double quotes around single ones */

  // generates
  content: var(--shrug-emoji, '¯\_(ツ)_/¯'); /* single quotes */
}

You can swap double and single quotes. CSS will be fine.

Multiple fallbacks

You can have multiple fallbacks by chaining multiple custom properties names. The last parameter is always a fallback value.

html {
  color: v(primary, accent, bg, #f0f0f0);

  // generates
  color: var(--primary, var(--accent, var(--bg, #f0f0f0)));
}

If you need the last parameter to not be a fallback value, replace it by null:

html {
  color: v(primary, accent, null);

  // generates
  color: var(--primary, var(--accent));
}

Note

If you need a list of values to not be considered as fallback, wrap them in quotes: as described in a comment, the list will be considered as one value, and the quotes will be stripped.

.my-class {
  transition-property: v(transition-properties, 'opacity, visibility');

  // generates
  transition-property: var(--transition-properties, opacity, visibility);
}

Edge cases

SCSS interpolation

In order to assign a value to a custom property using a SCSS variable or a SCSS function, interpolation is required:

$primary: #000;

.my-class {
  --primary: $primary; // error 🚫, custom property assignment needs interpolation
  --primary: #{$primary}; // correct ✅, value interpolated with `#{}`
  --primary: #000; // correct ✅, regular syntax

  --accent: v(secondary); // error 🚫, custom property assignment needs interpolation
  --accent: #{v(secondary)}; // correct ✅, function interpolated
  --accent: var(--secondary); // correct ✅, regular syntax

  color: v(accent); // correct ✅, `color` is not a custom property
}

Interpolation means “Have a look at #{what is inside the curly braced} and replace the $value-string by its computed value ($000)”.

In situations where interpolation is needed, using v() is less readable (#{v(propName)}) than the standard syntax (var(--propName)).

-- is a valid custom property name

It turns out that -- is a valid name for a CSS custom property.

Declaring and using it is all about edge cases:

.my-class {
  --: .5; // error 🚫
  --#{''}: .5; // correct ✅
  #{'--'}: .5; // correct ✅

  opacity: var(--); // error 🚫
  opacity: var(#{'--'}); // correct ✅
  opacity: v(); // correct ✅, thanks to v() ✌️
}

Another example, with three dashes:

.my-class-with-more-dashes {
  --#{'-'}: .5; // correct ✅
  #{'---'}: .5; // correct ✅

  opacity: var(#{'---'}); // correct ✅, interpolated
  opacity: v('-'); // correct ✅, thanks to v() ✌️
}

Changelog

See releases.

See also