🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more →

postcss-css-variables

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcss-css-variables - npm Package Compare versions

Comparing version

to
0.6.0

# v0.6.0 - 2016-9-23
- Update/refactor readme
- Thank you to [@isiahmeadows](github.com/isiahmeadows) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/36)
- Use string value for `undefined` variables to play nice with other plugins downstream
- Thank you to [@vincentorback](github.com/vincentorback) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/44)
# v0.5.2 - 2016-8-24
- Fix [#42](https://github.com/MadLittleMods/postcss-css-variables/issues/42) where `opts.preserve` was not working inside at-rules
- Thanks you to [@muftiev](github.com/muftiev) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/43)
- Thank you to [@muftiev](github.com/muftiev) for the [contribution](https://github.com/MadLittleMods/postcss-css-variables/pull/43)

@@ -8,0 +15,0 @@

@@ -147,2 +147,10 @@ var resolveValue = require('./resolve-value');

// Set 'undefined' value as a string to avoid making other plugins down the line unhappy
// See #22
if (valueResults.value === undefined) {
valueResults.value = 'undefined';
}
// Set the new value after we are done dealing with at-rule stuff

@@ -149,0 +157,0 @@ decl.value = valueResults.value;

{
"name": "postcss-css-variables",
"version": "0.5.2",
"version": "0.6.0",
"description": "PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation",

@@ -5,0 +5,0 @@ "keywords": [

@@ -1,26 +0,43 @@

[![npm version](https://badge.fury.io/js/postcss-css-variables.svg)](http://badge.fury.io/js/postcss-css-variables) [![Build Status](https://travis-ci.org/MadLittleMods/postcss-css-variables.svg)](https://travis-ci.org/MadLittleMods/postcss-css-variables)
# PostCSS CSS Variables
[PostCSS](https://github.com/postcss/postcss) plugin to transform [`CSS Custom Properties(CSS variables)`](http://dev.w3.org/csswg/css-variables/) syntax into a static representation. This plugin provides a future-proof way of using **most** of CSS variables features.
[![npm version](https://badge.fury.io/js/postcss-css-variables.svg)](http://badge.fury.io/js/postcss-css-variables) [![Build Status](https://travis-ci.org/MadLittleMods/postcss-css-variables.svg)](https://travis-ci.org/MadLittleMods/postcss-css-variables) [![Gitter](https://badges.gitter.im/MadLittleMods/postcss-css-variables.svg)](https://gitter.im/MadLittleMods/postcss-css-variables?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
CSS variables or CSS Custom Properties limited subset polyfill/shim.
[PostCSS](https://github.com/postcss/postcss) plugin to transform [`CSS Custom Properties (CSS variables)`](http://dev.w3.org/csswg/css-variables/) syntax into a static representation. This plugin provides a future-proof way of using **most** of CSS variables features, including selector cascading with some caveats, because this can only see the CSS, not the potentially dynamic HTML and DOM the CSS is applied to.
We strive for the most complete transformation but we/no plugin can achieve true complete parity according to the [specification](http://dev.w3.org/csswg/css-variables/) because of the DOM cascade unknowns.
### Install
### [Changelog](https://github.com/MadLittleMods/postcss-css-variables/blob/master/CHANGELOG.md)
```
npm install postcss-css-variables --save-dev
```
### Install
### Table of Contents
`npm install postcss-css-variables --save-dev`
- [Code Playground](#code-playground)
- [Usage](#usage)
- [Syntax](#syntax)
- [Defining Custom Properties with `--*`](#defining-custom-properties-with---)
- [Using Variables/Custom Properties with `var()`](#using-variables-custom-properties-with-var)
- [Features](#features)
- [At-rules like `@media`, `@support`, etc.](#at-rules-like-media-support-etc)
- [Pseudo-classes and Elements](#pseudo-classes-and-elements)
- [Nested Rules](#nested-rules)
- [`calc()`](#calc)
- [Why?](#why)
- [Interoperability](#interoperability)
- [Differences from `postcss-custom-properties`](#differences-from-postcss-custom-properties)
- [Caveats](#caveats)
- [Options](#options)
- [Quick Reference/Notes](#quick-referencenotes)
- [Testing](#testing)
- [Changelog](https://github.com/MadLittleMods/postcss-css-variables/blob/master/CHANGELOG.md)
# [Code Playground](https://madlittlemods.github.io/postcss-css-variables/playground/)
[Try it](https://madlittlemods.github.io/postcss-css-variables/playground/) before you install it!
[Try it in the playground](https://madlittlemods.github.io/postcss-css-variables/playground/) and see what you think! Just add some CSS and see to see the final transformed/compiled CSS. You can try anything here in the playground, too.
Add some PostCSS and it will show you the transformed/compiled CSS.
# Usage
You can try any of these examples on the [code playground](https://madlittlemods.github.io/postcss-css-variables/playground/).
[*For more general PostCSS usage, look here.*](https://github.com/postcss/postcss#usage)

@@ -45,13 +62,71 @@ ```js

[*For more general PostCSS usage, see this section*](https://github.com/postcss/postcss#usage)
# Syntax
## At-rule support `@media`, `@support`, etc
### Defining Custom Properties with `--*`
You can add rules that declare CSS variables nested inside at-rules. You can even nest the at-rules however deep you want.
A custom property is any property whose name starts with two dashes `--`. A property must be in a rule.
The following CSS:
*Note: `:root` is nothing more than the selector for the root DOM node. Any other selector like `.class`, `#id`, or even `#foo ~ .bar > span.baz` works.*
```css
:root {
--foo-width: 100px;
--foo-bg-color: rgba(255, 0, 0, 0.85);
}
.foo {
--foo-width: 100px;
--foo-bg-color: rgba(255, 0, 0, 0.85);
}
```
Custom properties can be declared multiple times, but like variable scope in other languages, only the most specific one takes precedence.
```css
:root: {
--some-color: red;
}
.foo {
/* red */
color: var(--some-color);
}
.bar {
--some-color: blue;
/* blue */
color: var(--some-color);
}
.bar:hover {
--some-color: green;
/* Automically gets a `color: green;` declaration because we `--some-color` used within scope elsewhere */
}
```
*[W3C Draft: CSS Custom Properties for Cascading Variables, section 2](http://dev.w3.org/csswg/css-variables/#defining-variables)*
### Using Variables/Custom Properties with `var()`
```css
.foo {
width: var(--foo-width);
/* You can even provide a fallback */
background: var(--foo-bg-color, #ff0000);
}
```
*[W3C Draft: CSS Custom Properties for Cascading Variables, section 3](http://dev.w3.org/csswg/css-variables/#using-variables)*
# Features
### At-rules like `@media`, `@support`, etc.
It's perfectly okay to declare CSS variables inside media queries and the like. It'll work just as you would expect.
```css
:root {
--width: 100px;

@@ -71,3 +146,3 @@ }

will be processed to:
Will be transformed to:

@@ -86,7 +161,9 @@ ```css

## Pseudo class and elements
### Pseudo-classes and Elements
Psuedo-classes are also dealt with correctly, because it's easy to statically determine.
```css
.foo {
--foo-color: #ff0000;
--foo-color: red;
color: var(--foo-color);

@@ -96,31 +173,27 @@ }

.foo:hover {
--foo-color: #00ff00;
--foo-color: green;
}
```
will be processed to:
Will be transformed to:
```css
.foo {
color: #ff0000;
color: red;
}
.foo:hover {
color: #00ff00;
color: green;
}
```
### Nested Rules
This pairs very well with [`postcss-nested`](https://github.com/postcss/postcss-nested) or [`postcss-nesting`](https://github.com/jonathantneal/postcss-nesting), adding support for nested rules. For either, you must put the plugin before `postcss-css-variables` in the plugin stack so that the `&` references are expanded first (`postcss-css-variables` doesn't understand them). For example, with `postcss-nested`, your PostCSS setup would look like this:
## Nested rules
When using this feature, `postcss-css-variables` will output invalid CSS by itself(but you did input invalid CSS anyway). This feature is best paired with [`postcss-nested`](https://github.com/postcss/postcss-nested) in order to properly expand the rules.
Run `postcss-nested` before `postcss-css-variables` so that `postcss-nested` can properly expand the `&` references before we start resolving variable values.
```js
var postcss = require('postcss');
var cssvariables = require('postcss-css-variables');
var nestedcss = require('postcss-nested');
var nested = require('postcss-nested');

@@ -131,6 +204,5 @@ var fs = require('fs');

// Process your CSS with postcss-css-variables
var output = postcss([
// Flatten/unnest rules
nestedcss,
nested,
// Then process any CSS variables

@@ -145,6 +217,4 @@ cssvariables(/*options*/)

### Simple example
For a simple example with nesting:
The following CSS:
```css

@@ -161,3 +231,3 @@ .box-foo {

will be processed to:
With also `postcss-nesting`, this will be transformed to:

@@ -167,13 +237,11 @@ ```css

width: 150px;
}
.box-bar {
width: 150px;
}
.box-foo .box-bar {
width: 150px;
}
```
### Complex example
For a more complex example with a media query:
The following CSS:
```css

@@ -199,3 +267,3 @@ :root {

will be processed to:
Will be transformed to:

@@ -205,12 +273,6 @@ ```css

width: 150px;
}
.box-bar {
width: 150px;
}
@media (max-width: 800px) {
.box-bar {
width: 300px;
}
}
.box-foo .box-bar {
width: 150px;
}

@@ -222,2 +284,6 @@

}
.box-foo .box-bar {
width: 300px;
}
}

@@ -228,71 +294,80 @@ ```

## Interoperability
# Why?
`postcss-css-variables` plays really nice with [`postcss-nested`](https://github.com/postcss/postcss-nested) in order to get a larger subset of CSS variables features. *See [Nested rules, Usage section](#nested-rules)*
This plugin was spawned out of a [discussion on the `cssnext` repo](https://github.com/cssnext/cssnext/issues/99) and a personal need.
If you are using [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties) previously, we have a compatible feature set and more so you can switch over without having to refactor any of your code. You can just start writing the new awesome stuff.
There is another similar plugin available, [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties), although it restricts itself much more than this plugin, preferring partial spec conformance. This plugin has the same capabilities but also adds imperfect feature support which stem from not being to know what the DOM will look like when you compile your CSS. We instead look at the explicit structure of your CSS selectors.
### Interoperability
# Why?
Putting `postcss-css-variables` in place of `postcss-custom-properties` should work out of the box.
This plugin was spawned out of a [discussion on the `cssnext` repo](https://github.com/cssnext/cssnext/issues/99) and a personal need.
In `postcss-custom-properties`, CSS variable declarations are specifically restricted to the `:root` selector. In `postcss-css-variables`, this is not the case and they may be declared inside any rule with whatever selector. The variables are substituted based on statically known CSS selector inheritance.
There is another similar plugin available, [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties), which at the moment, covers less of the [CSS-variable/custom-property draft/spec](http://dev.w3.org/csswg/css-variables/) compared to this plugin. It also happened to not cover the feature I was after and after dealing with it, making an incomplete prototype piggybacking off of it; I decided to write my own starting from scratch. I do use some of the same/similar unit tests because that just makes sense to get proper code coverage.
### Differences from `postcss-custom-properties`
The main features that we`postcss-css-variables` add/provide are:
In [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties), CSS variable declarations are specifically restricted to the `:root` selector. In `postcss-css-variables`, this is not the case and they may be declared inside any rule with whatever selector.
- No limitation on what scope CSS variables can be declared or used (`:root` or wherever)
- Proper value substitution based on explicit DOM/structure traversal
- At-rule support `@media`, `@support`, etc
- Nested rules which can be fully deduced with [`postcss-nested`](https://github.com/postcss/postcss-nested).
- Pseudo class/element support `:hover`, etc
Here's a quick overview of the differences:
- CSS variables may be declared in any selector like `.foo` or `.foo .bar:hover`, and is not limited to just `:root`
- CSS variables may be declared in `@media`, `@support`, and other at-rules.
- CSS variables may be declared in `:hover` and other psuedo-classes, which get expanded properly.
- Variables in nested rules can be deduced with the help of [`postcss-nested`](https://github.com/postcss/postcss-nested) or [`postcss-nesting`](https://github.com/jonathantneal/postcss-nesting).
Continue to the next section to see where some of these might be unsafe to do. There are reasons behind the ethos of why the other plugin, [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties), is very limited in what it supports, due to differing opinions on what is okay to support.
# Syntax
# Caveats
### [Defining Custom Properties: the --* family of properties](http://dev.w3.org/csswg/css-variables/#defining-variables)
When you declare a CSS variable inside one selector, but consume it in another, this does make an unsafe assumption about it which can be non-conforming in certain edge cases. Here is an example where these limitations result in non-conforming behavior.
A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS). A property must be in a `rule`.
Using the following CSS:
*Note: `:root` is nothing more than the selector for the root DOM node. You could use any other selector (class, id, etc)*
```
:root {
--foo-width: 100px;
--foo-bg-color: rgba(255, 0, 0, 0.85);
```css
.component {
--text-color: blue;
}
.component .header {
color: var(--text-color);
}
.component .text {
--text-color: green;
color: var(--text-color);
}
```
A custom property can be declared multiple times.
Note the nested markup below. We only know about the DOM's inheritance from your CSS selectors. If you want nest multiple times, you need to be explicit about it in your CSS which isn't necessary with browser that natively support CSS variables. See the innermost `<h1 class="title">`
*See: [W3C Draft: CSS Custom Properties for Cascading Variables, section 2](http://dev.w3.org/csswg/css-variables/#defining-variables) for more information.*
```html
<div class="component">
Black
<h1 class="title">
Blue
### [Using Cascading Variables: the var() notation](http://dev.w3.org/csswg/css-variables/#using-variables)
<p class="decoration">
Green
<h1 class="title">Blue with this plugin, but green per spec</h1>
</p>
</h1>
</div>
```
.foo {
width: var(--foo-width);
/* You can even provide a fallback */
background: var(--foo-bg-color, #ff0000);
}
```
[`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties) avoids this problem entirely by restricting itself to just the `:root` selector. This is because the developers there would prefer to not support a feature instead of something almost-spec-compliant like what `postcss-css-variables` does.
*See: [W3C Draft: CSS Custom Properties for Cascading Variables, section 3](http://dev.w3.org/csswg/css-variables/#using-variables) for more information.*
# Options
### `preserve` (default: `false`)
Allows you to preserve custom properties & var() usage in output.
# Options:
Possible values:
### `preserve` (default: `false`)
Allows you to preserve custom properties & var() usage in output.
Allowed values:
- `false`: Removes `--var` declarations and replaces `var()` with their resolved/computed values.
- `true`: Keeps `var()` declarations in the output and has the computed value as a fallback declaration. Also keeps computed `--var` declarations
- `true`: Keeps `var()` declarations in the output and has the computed value as a fallback declaration. Also keeps computed `--var` declarations.
- `'computed'`: Keeps computed `--var` declarations in the output. Handy to make them available to your JavaScript.

@@ -304,3 +379,3 @@

Can be a simple key-value pair or an object with a `value` property and an optional `isImportant` bool property
Can be a simple key-value pair or an object with a `value` property and an optional `isImportant` bool property.

@@ -310,3 +385,3 @@ The object keys are automatically prefixed with `--` (according to CSS custom property syntax) if you do not provide it.

```
```js
var postcss = require('postcss');

@@ -313,0 +388,0 @@ var cssvariables = require('postcss-css-variables');