CSS preprocessor
Core Features
Auto prefixing
Edit ‘Auto prefixing’ on GithubVendor prefixes for properties, functions, @-rules and declarations are automatically generated – based on trusted sources – so you can maintain cross-browser support while keeping your source code clean and easy to maintain.
.foo {
background: linear-gradient(to right, red, white);
}
.foo {
background: -webkit-linear-gradient(to right, red, white);
background: linear-gradient(to right, red, white);
}
@keyframes bounce {
50% { transform: scale(1.4); }
}
@-webkit-keyframes bounce {
50% {-webkit-transform: scale(1.4);
transform: scale(1.4);}
}
@keyframes bounce {
50% {-webkit-transform: scale(1.4);
transform: scale(1.4);}
}
Nesting
Edit ‘Nesting’ on GithubRules can be nested to avoid repetitive typing when scoping to a common parent selector.
.homepage {
color: #333;
background: white;
.content {
p {
font-size: 110%;
}
}
}
.homepage {
color: #333;
background: white;
}
.homepage .content p {
font-size: 110%;
}
Parent referencing
You can use the parent reference symbol &
for placing the parent selector explicitly.
.homepage {
.no-js & {
p {
font-size: 110%;
}
}
}
.no-js .homepage p {
font-size: 110%;
}
Variables
Edit ‘Variables’ on GithubDeclare variables in your CSS with a @set
directive and use them with the $()
function.
Variables can also be injected at runtime with the vars option.
/* Defining variables */
@set {
dark: #333;
light: #F4F2E2;
smaller-screen: screen and (max-width: 800px);
}
/* Using variables */
@media $(smaller-screen) {
ul, p {
color: $(dark);
/* Using a fallback value with an undefined variable */
background-color: $(accent-color, #ff0);
}
}
/* Interpolation */
.username::before {
content: "$(greeting)";
}
Conditionals
Sections of CSS can be included and excluded on the basis of variable existence with the @ifset
directive:
@set foo #f00;
@set bar true;
@ifset foo {
p {
color: $(foo);
}
}
p {
font-size: 12px;
@ifset not foo {
line-height: 1.5;
}
@ifset bar(true) {
margin-bottom: 5px;
}
}
Direct @import
Edit ‘Direct @import’ on GithubFiles referenced with the @import
directive are inlined directly to save on http requests. Relative URL paths in the CSS are also updated if necessary.
If you specify a media designation following the import URL — as per the CSS standard — the imported file content is wrapped in a @media
block.
/* Standard CSS @import statements */
@import "print.css" print;
@import url( "small-screen.css" ) screen and ( max-width: 500px );
@media print {
/* Contents of print.css */
}
@media screen and ( max-width: 500px ) {
/* Contents of small-screen.css */
}
Rule inheritance
Edit ‘Rule inheritance’ on GithubBy using the @extend
directive and passing it a named ruleset or selector from any other rule you can share styles more effectively across a stylesheet.
Abstract rules can be used if you just need to extend a generic set of declarations.
.negative-text {
overflow: hidden;
text-indent: -9999px;
}
.sidebar-headline {
@extend .negative-text;
background: url( headline.png ) no-repeat;
}
.negative-text,
.sidebar-headline {
overflow: hidden;
text-indent: -9999px;
}
.sidebar-headline {
background: url( headline.png ) no-repeat;
}
Inheritance is recursive:
.one { color: pink; }
.two { @extend .one; }
.three { @extend .two; }
.four { @extend .three; }
.one, .two, .three, .four { color: pink; }
Referencing by name
If you want to reference a rule without being concerned about later changes to the identifying selector use the @name
directive:
.foo123 {
@name foo;
text-decoration: underline;
}
.bar {
@include foo;
}
.baz {
@extend foo;
}
Extending with pseudo classes/elements
@extend
arguments can adopt pseudo classes/elements by appending an exclamation mark:
.link-base {
color: #bada55;
text-decoration: underline;
}
.link-base:hover,
.link-base:focus {
text-decoration: none;
}
.link-footer {
@extend .link-base, .link-base:hover!, .link-base:focus!;
color: blue;
}
.link-base,
.link-footer {
color: #bada55;
text-decoration: underline;
}
.link-base:hover,
.link-base:focus,
.link-footer:hover,
.link-footer:focus {
text-decoration: none;
}
.link-footer {
color: blue;
}
The same outcome can also be achieved with an Abstract rule wrapper to simplify repeated use:
.link-base {
color: #bada55;
text-decoration: underline;
}
.link-base:hover,
.link-base:focus {
text-decoration: none;
}
@abstract link-base {
@extend .link-base, .link-base:hover!, .link-base:focus!;
}
.link-footer {
@extend link-base;
color: blue;
}
Abstract rules
Edit ‘Abstract rules’ on GithubAbstract rules are generic rules that can be extended with the @extend
directive or mixed in (without arguments) like regular mixins with the @include
directive.
@abstract ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@abstract heading {
font: bold 1rem serif;
letter-spacing: .1em;
}
.foo {
@extend ellipsis;
display: block;
}
.bar {
@extend ellipsis;
@include heading;
}
.foo,
.bar {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.foo {
display: block;
}
.bar {
font: bold 1rem serif;
letter-spacing: .1em;
}
Loops
Edit ‘Loops’ on GithubFor...in loops with lists and generator functions.
@for fruit in apple, orange, pear {
.#(fruit) {
background-image: url("images/#(fruit).jpg");
}
}
.apple { background-image: url(images/apple.jpg); }
.orange { background-image: url(images/orange.jpg); }
.pear { background-image: url(images/pear.jpg); }
@for base in range(2, 24) {
@for i in range(1, #(base)) {
.grid-#(i)-of-#(base) {
width: math(#(i) / #(base) * 100, %);
}
}
}
.grid-1-of-2 { width: 50%; }
.grid-2-of-2 { width: 100%; }
/*
Intermediate steps ommited.
*/
.grid-23-of-24 { width: 95.83333%; }
.grid-24-of-24 { width: 100%; }
Functions
math()
Edit ‘math()’ on GithubEvaluate a raw mathematical expression.
math( expression [, unit] )
Examples
font-size: math( 12 / 16, em );
font-size: 0.75em;
h-adjust()
Edit ‘h-adjust()’ on GithubAdjust the hue of a color value.
h-adjust( color, offset )
Parameters
color
Any valid CSS color valueoffset
The percentage to offset the color hue (percent mark optional)
Returns
The modified color value.
Examples
color: h-adjust( deepskyblue -10 );
s-adjust()
Edit ‘s-adjust()’ on GithubAdjust the saturation of a color value.
s-adjust( color, offset )
Parameters
color
Any valid CSS color valueoffset
The percentage to offset the color hue (percent mark optional)
Returns
The modified color value.
Examples
/* Desaturate */
color: s-adjust( deepskyblue -100 );
l-adjust()
Edit ‘l-adjust()’ on GithubAdjust the lightness of a color value.
l-adjust( color, offset )
Parameters
color
Any valid CSS color valueoffset
The percentage to offset the color hue (percent mark optional)
Returns
The modified color value.
Examples
color: l-adjust( deepskyblue 10 );
a-adjust()
Edit ‘a-adjust()’ on GithubManipulate the opacity (alpha channel) of a color value.
a-adjust( color, offset )
Parameters
color
Any valid CSS color valueoffset
The percentage to offset the color opacity
Returns
The modified color value
Examples
/* Reduce color opacity by 10% */
color: a-adjust( rgb(50,50,0) -10 );
hsl-adjust()
Edit ‘hsl-adjust()’ on GithubManipulate the hue, saturation and lightness of a color value
hsl-adjust( color, hue-offset, saturation-offset, lightness-offset )
Parameters
color
Any valid CSS color valuehue-offset
The percentage to offset the color huesaturation-offset
The percentage to offset the color saturationlightness-offset
The percentage to offset the color lightness
Returns
The modified color value
Examples
/* Lighten and increase saturation */
color: hsl-adjust( red 0 5 5 );
hsla-adjust()
Edit ‘hsla-adjust()’ on GithubManipulate the hue, saturation, lightness and opacity of a color value.
hsla-adjust( color, hue-offset, saturation-offset, lightness-offset, alpha-offset )
Parameters
color
Any valid CSS color valuehue-offset
The percentage to offset the color huesaturation-offset
The percentage to offset the color saturationlightness-offset
The percentage to offset the color lightnessalpha-offset
The percentage to offset the color opacity
Returns
The modified color value.
Examples
color: hsla-adjust( #f00 0 5 5 -10 );
data-uri()
Edit ‘data-uri()’ on GithubCreate a data-uri.
data-uri( url )
Parameters
url
URL of an asset
url
cannot be external, and must not be written with an http protocol prefix.
The following file extensions are supported: jpg, jpeg, gif, png, svg, svgz, ttf, woff
Returns
The created data-uri as a string inside a CSS url().
Examples
background: silver data-uri(../images/stripe.png);
background: silver url(data:<img-data>);
this()
Edit ‘this()’ on GithubReference another property value from the same containing block.
Restricted to referencing properties that don't already reference other properties.
this( property-name, fallback )
Parameters
property-name
Property namefallback
A CSS value
Returns
The referenced property value, or the fallback if it has not been set.
Examples
.foo {
width: this( height );
height: 100em;
}
/* The following both fail because they create circular references. */
.bar {
height: this( width );
width: this( height );
}
query()
Edit ‘query()’ on GithubCopy a value from another rule.
query( target [, property-name = default] [, fallback] )
Parameters
target
A rule selector, an abstract rule name or context keyword:previous
,next
(alsoparent
andtop
within nested structures)property-name
The CSS property name to copy, or justdefault
to pass over. Defaults to the calling propertyfallback
A CSS value to use if the target property does not exist
Returns
The referenced property value, or the fallback if it has not been set.
Examples
.foo {
width: 40em;
height: 100em;
}
.bar {
width: query( .foo ); /* 40em */
margin-top: query( .foo, height ); /* 100em */
margin-bottom: query( .foo, default, 3em ); /* 3em */
}
Using context keywords:
.foo {
width: 40em;
.bar {
width: 30em;
.baz: {
width: query( parent ); /* 30em */
.qux {
width: query( top ); /* 40em */
}
}
}
}
Selector grouping
Edit ‘Selector grouping’ on GithubSelector grouping with the :any
pseudo class (modelled after CSS4 :matches) simplifies the creation of complex selector chains.
:any( .sidebar, .block ) a:any( :hover, :focus ) {
color: lemonchiffon;
}
.block a:hover,
.block a:focus,
.sidebar a:hover,
.sidebar a:focus {
color: lemonchiffon;
}
Selector aliases
Edit ‘Selector aliases’ on GithubSelector aliases can be useful for grouping together common selector chains for reuse.
They're defined with the @selector
directive, and can be used anywhere you might use a pseudo class.
@selector heading :any(h1, h2, h3, h4, h5, h6);
@selector radio input[type="radio"];
@selector hocus :any(:hover, :focus);
/* Selector aliases with arguments */
@selector class-prefix :any([class^="#(0)"], [class*=" #(0)"]);
@selector col :class-prefix(-col);
.sidebar :heading {
color: honeydew;
}
:radio {
margin-right: 4px;
}
:col {
float: left;
}
p a:hocus {
text-decoration: none;
}
.sidebar h1, .sidebar h2,
.sidebar h3, .sidebar h4,
.sidebar h5, .sidebar h6 {
color: honeydew;
}
input[type="radio"] {
margin-right: 4px;
}
[class^="col-"],
[class*=" col-"] {
border: 1px solid rgba(0,0,0,.5);
}
p a:hover,
p a:focus {
text-decoration: none;
}
Selector splatting
Selector splats are a special kind of selector alias that expand using passed arguments.
@selector-splat input input[type="#(text)"];
form :input(time, text, url, email, number) {
border: 1px solid;
}
form input[type="time"],
form input[type="text"],
form input[type="url"],
form input[type="email"],
form input[type="number"] {
border: 1px solid;
}
Mixins
Edit ‘Mixins’ on GithubMixins make reusing small snippets of CSS much simpler. You define them with the @mixin
directive.
Positional arguments via the argument function #()
extend the capability of mixins for repurposing in different contexts.
@mixin display-font {
font-family: "Arial Black", sans-serif;
font-size: #(0);
letter-spacing: #(1);
}
/* Another mixin with default arguments */
@mixin blue-theme {
color: #(0 navy);
background-image: url("images/#(1 cross-hatch).png");
}
/* Applying the mixins */
.foo {
@include display-font(100%, .1em), blue-theme;
}
.foo {
font-family: "Arial Black", sans-serif;
font-size: 100%;
letter-spacing: .1em;
color: navy;
background-image: url("images/cross-hatch.png");
}
Skipping arguments
Mixin arguments can be skipped by using the default keyword:
@mixin display-font {
font-size: #(0 100%);
letter-spacing: #(1);
}
/* Applying the mixin skipping the first argument so the
default value is used instead */
#foo {
@include display-font(default, .3em);
}
Sometimes you may need to use the same positional argument more than once. In this case the default value only needs to be specified once:
@mixin square {
width: #(0 10px);
height: #(0);
}
.foo {
@include square;
}
#foo {
width: 10px;
height: 10px;
}
Mixing-in from other sources
Normal rules and abstract rules can also be used as static mixins without arguments:
@abstract negative-text {
text-indent: -9999px;
overflow: hidden;
}
#main-content .theme-border {
border: 1px solid maroon;
}
.foo {
@include negative-text, #main-content .theme-border;
}
Fragments
Edit ‘Fragments’ on GithubFragments – defined and invoked with the @fragment
directive – work in a similar way to mixins, except that they work at block level:
@fragment input-placeholder {
#(1)::-webkit-input-placeholder { color: #(0); }
#(1):-moz-placeholder { color: #(0); }
#(1)::placeholder { color: #(0); }
#(1).placeholder-state { color: #(0); }
}
@fragment input-placeholder(#777, textarea);
textarea::-webkit-input-placeholder { color: #777; }
textarea:-moz-placeholder { color: #777; }
textarea::placeholder { color: #777; }
textarea.placeholder-state { color: #777; }
Plugins
aria
Edit ‘aria’ on GithubPseudo classes for working with ARIA roles, states and properties.
:role(tablist) {...}
:aria-expanded {...}
:aria-expanded(false) {...}
:aria-label {...}
:aria-label(foobarbaz) {...}
[role="tablist"] {...}
[aria-expanded="true"] {...}
[aria-expanded="false"] {...}
[aria-label] {...}
[aria-label="foobarbaz"] {...}
canvas
Edit ‘canvas’ on GithubBitmap image generator.
Requires the GD image library bundled with PHP.
/* Create square semi-opaque png. */
@canvas foo {
width: 50;
height: 50;
fill: rgba(255, 0, 0, .5);
}
body {
background: white canvas(foo);
}
/* White to transparent east facing gradient with 10px
margin and background fill. */
@canvas horz-gradient {
width: #(0);
height: 150;
fill: canvas-linear-gradient(to right, #(1 white), #(2 rgba(255,255,255,0)));
background-fill: powderblue;
margin: 10;
}
/* Rectangle 300x150. */
body {
background: canvas(horz-gradient, 300);
}
/* Flipped gradient, using canvas-data() to generate a data URI. */
.bar {
background: canvas-data(horz-gradient, 100, rgba(255,255,255,0), white);
}
/* Google logo resized to 400px width and given a sepia effect. */
@canvas sepia {
src: url(http://www.google.com/images/logo.png);
width: 400;
canvas-filter: greyscale() colorize(45, 45, 0);
}
.bar {
background: canvas(sepia);
}
ease
Edit ‘ease’ on GithubExpanded easing keywords for transitions.
- ease-in-out-back
- ease-in-out-circ
- ease-in-out-expo
- ease-in-out-sine
- ease-in-out-quint
- ease-in-out-quart
- ease-in-out-cubic
- ease-in-out-quad
- ease-out-back
- ease-out-circ
- ease-out-expo
- ease-out-sine
- ease-out-quint
- ease-out-quart
- ease-out-cubic
- ease-out-quad
- ease-in-back
- ease-in-circ
- ease-in-expo
- ease-in-sine
- ease-in-quint
- ease-in-quart
- ease-in-cubic
- ease-in-quad
See easing demos for live examples.
transition: .2s ease-in-quad;
transition: .2s cubic-bezier(.550,.085,.680,.530);
forms
Edit ‘forms’ on GithubPseudo classes for working with forms.
:input(date, search, email) {...}
:checkbox {...}
:radio {...}
:text {...}
input[type="date"], input[type="search"], input[type="email"] {...}
input[type="checkbox"] {...}
input[type="radio"] {...}
input[type="text"] {...}
hocus-pocus
Edit ‘hocus-pocus’ on GithubComposite :hover/:focus/:active pseudo classes.
a:hocus { color: red; }
a:pocus { color: red; }
a:hover, a:focus { color: red; }
a:hover, a:focus, a:active { color: red; }
property-sorter
Edit ‘property-sorter’ on GithubProperty sorting.
Examples use the predefined property sorting table. To define a custom sorting order pass an array to csscrush_set_property_sort_order()
color: red;
background: #000;
opacity: .5;
display: block;
position: absolute;
position: absolute;
display: block;
opacity: .5;
color: red;
background: #000;
svg
Edit ‘svg’ on GithubDefine and embed simple SVG elements, paths and effects inside CSS
@svg foo {
type: star;
star-points: #(0 5);
radius: 100 50;
margin: 20;
stroke: black;
fill: red;
fill-opacity: .5;
}
/* Embed SVG with svg() function (generates an svg file). */
body {
background: svg(foo);
}
/* As above but a 3 point star creating a data URI instead of a file. */
body {
background: svg-data(foo, 3);
}
/* Using path data and stroke styles to create a plus sign. */
@svg plus {
d: "M0,5 h10 M5,0 v10";
width: 10;
height: 10;
stroke: white;
stroke-linecap: round;
stroke-width: 2;
}
/* Skewed circle with radial gradient fill and drop shadow. */
@svg circle {
type: circle;
transform: skewX(30);
diameter: 60;
margin: 20;
fill: svg-radial-gradient(at top right, gold 50%, red);
drop-shadow: 2 2 0 rgba(0,0,0,1);
}
/* 8-sided polygon with an image fill.
Note: images usually have to be converted to data URIs, see known issues below. */
@svg pattern {
type: polygon;
sides: 8;
diameter: 180;
margin: 20;
fill: pattern(data-uri(kitten.jpg), scale(1) translate(-100 0));
fill-opacity: .8;
}
Known issues
Firefox does not allow linked images (or other svg) when svg is in "svg as image" mode.
API
API functions
Edit ‘API functions’ on Githubcsscrush_file()
Process CSS file and return the compiled file URL.
csscrush_file( string $file [, array $options ] )
csscrush_tag()
Process CSS file and return an html link
tag with populated href.
csscrush_tag( string $file [, array $options [, array $tag_attributes ]] )
csscrush_inline()
Process CSS file and return CSS as text wrapped in html style
tags.
csscrush_inline( string $file [, array $options [, array $tag_attributes ]] )
csscrush_string()
Compile a raw string of CSS string and return it.
csscrush_string( string $string [, array $options ] )
csscrush_get()
Retrieve a config setting or option default.
csscrush_get( string $object_name, string $property )
Parameters
$object_name
Name of object you want to inspect: 'config' or 'options'.$property
csscrush_set()
Set a config setting or option default.
csscrush_set( string $object_name, mixed $settings )
Parameters
$object_name
Name of object you want to modify: 'config' or 'options'.$settings
Associative array of keys and values to set, or callable which argument is the object specified in$object_name
.
csscrush_plugin()
Register a plugin.
csscrush_plugin( string $name, callable $callback )
csscrush_stat()
Get compilation stats from the most recent compiled file.
csscrush_stat()
Options
Edit ‘Options’ on GithubOption | Values (default in bold) | Description |
---|---|---|
minify | true | false | Array | Enable or disable minification. Optionally specify an array of advanced minification parameters. Currently the only advanced option is 'colors', which will compress all color values in any notation. |
formatter | block | single-line | padded | Set the formatting mode. Overrides minify option if both are set. |
newlines | use-platform | windows/win | unix | Set the output style of newlines |
boilerplate | true | false | Path | Prepend a boilerplate to the output file |
versioning | true | false | Append a timestamped querystring to the output filename |
vars | Array | An associative array of CSS variables to be applied at runtime. These will override variables declared globally or in the CSS. |
cache | true | false | Turn caching on or off. |
output_dir | Path | Specify an output directory for compiled files. Defaults to the same directory as the host file. |
output_file | Output filename | Specify an output filename (suffix is added). |
asset_dir | Path | Directory for SVG and image files generated by plugins (defaults to the main file output directory). |
stat_dump | false | true | Path | Save compile stats and variables to a file in json format. |
vendor_target | "all" | "moz", "webkit", ... | Array | Limit aliasing to a specific vendor, or an array of vendors. |
rewrite_import_urls | true | false | "absolute" | Rewrite relative URLs inside inlined imported files. |
import_paths | Array | Additional paths to search when resolving relative import URLs. |
plugins | Array | An array of plugin names to enable. |
source_map | true | false | Output a source map (compliant with the Source Map v3 proposal). |
context | Path | Context for importing resources from relative urls (Only applies to `csscrush_string()` and command line utility). |
doc_root | Path | Specify an alternative server document root for situations where the CSS is being served behind an alias or url rewritten path. |
Getting Started
PHP
Edit ‘PHP’ on GithubIf you're using Composer you can use Crush in your project with the following line in your terminal:
composer require css-crush/css-crush
If you're not using Composer yet just download the library (zip or tar) into a convenient location and require the bootstrap file:
<?php require_once 'path/to/CssCrush.php'; ?>
JavaScript
Edit ‘JavaScript’ on GithubThis preprocessor is written in PHP, so as prerequisite you will need to have PHP installed on your system to use the JS api.
npm install csscrush
All methods can take the standard options (camelCase) as the second argument.
const csscrush = require('csscrush');
// Compile. Returns promise.
csscrush.file('./styles.css', {sourceMap: true});
// Compile string of CSS. Returns promise.
csscrush.string('* {box-sizing: border-box;}');
// Compile and watch file. Returns event emitter (triggers 'data' on compile).
csscrush.watch('./styles.css');