README
SCSS Toolkit
A small and configurable SCSS Toolkit to boost your project! 🚀
Table of contents
Installation
Install it with Yarn:
$ yarn add @studiometa/scss-toolkit
Or with NPM:
$ npm install @studiometa/scss-toolkit
Usage
Simple Usage
Import the toolkit in your project to have access to all helpers functions, mixins, variables and classes:
@import '~@studiometa/scss-toolkit';
If your current Sass implementation does not support
@import
s from Node modules, have a look at thenode-sass-magic-importer
custom importer.
Advanced usage
If you need to specify a custom configuration — you probably will, the best way to use the micro framework in your application is to create a separate _config.scss
file which will override the configurations of the framework.
_config.scss
/*==========================================================================*\
Global SCSS configuration
\*==========================================================================*/
// Colors definition
$colors: (
'red': #f00,
'green': #0f0,
'blue': #00f,
);
// Import SCSS Toolkit after the configuration overrides
@import '~@studiometa/scss-toolkit';
You can then import your _config.scss
file wherever you need to access a function, mixin or variable from the toolkit. You can import both your configuration file and the SCSS Toolkit package in your main SCSS file with a variable $has-classes
set to true
to import all the class helpers from the toolkit.
app.scss
/*==========================================================================*\
Main styles
\*==========================================================================*/
// Import dependencies:
// - _config.scss to override the SCSS toolkit's defaults
// - @studiometa/scss-toolkit/components/reset to get some nice defaults
@import './config';
@import '~@studiometa/scss-toolkit/components/reset';
// Import your project files
@import './components/foo';
@import './components/bar';
// ...
// Import the toolkit latst with the `$has-classes` variable set to `true`
// for the functions, mixins and classes helpers. Importing it last will let
// you use the classes without the `--force` modifier to override some
// of your components behaviours.
$has-classes: true;
@import '~@studiometa/scss-toolkit';
$has-classes: false;
⚠️ We reset the
$has-classes
variable tofalse
right after the toolkit import to make sure future import in any SCSS file will only import the mixins, functions and variables declarations without the class helpers.
Documentation
Framework
The micro-framework is composed of 8 different files which defines each a set of variables, mixins, functions and classes. Find below what each file is responsible for.
framework/_breakpoints.scss
Definitions
$breakpoints
: a map of names and values (in pixels) of breakpoints$breakpoints-height
: a map of names and values (in pixels) of height based breakpoints@function media($breakpoint, $type, $unit, $orientation)
: a function to get a breakpoint declaration given a name@function md($breakpoint, $type, $unit, $orientation)
: an alias for themedia(...)
function
Defaults
$breakpoints: (
'xxs': 0,
'xs': 480,
's': 768,
'm': 1024,
'l': 1280,
'xl': 1440,
'xxl': 1920,
) !default;
$breakpoints-height: (
'xxs': 0,
'xs': 360,
's': 576,
'm': 768,
'l': 960,
'xl': 1080,
'xxl': 1440,
) !default;
Usage
.foo {
display: none;
// Media queries
@media #{media('s')} { // @media (min-width: 48em) { ... }
display: block;
}
@media #{md('xs', 'max')} { // @media not all and (min-width: 48em) { ... }
display: flex;
}
@media #{md('s', 'min', 'em', 'height')} { // @media (min-height: 36em) { ... }
min-height: 50vh;
}
// Using Sass ArgList
@media #{md((breakpoint: 's', orientation: 'height')...)} { // @media (min-height: 36em) { ... }
min-height: 50vh;
}
}
framework/_colors.scss
Definitions
$colors-with-force
: wether to create…--force
modifiers with the!important
flag or not$colors-with-breakpoints
: wether to create…--<breakpoint>
modifiers or not$colors
: a map of names and values of colors@function color($color)
: a function to get a color value by its name defined in the previous map@function c($color)
: an alias for thecolor(...)
function@mixin for-each-colors($excludes)
: a mixin to abstract the loop over the$colors
map, with the color name and its value as mixin props- Class helpers:
.<property>-<color>[--force]
: set the given<property>
to the given<color>
's value, with the--force
modifier adding an!important
flag<property>
:background
,color
,fill
,stroke
<color>
: one of the defined colors
Defaults
/** @type {Boolean} Do we need the `--force` modifiers? */
$colors-with-force: false !default;
/** @type {Boolean} Do we need the `--<breakpoint>` modifiers? */
$colors-with-breakpoints: false !default;
/**
* Map of color names and values
*
* @type {Map}
*/
$colors: (
'white': #fff,
'black': #000,
) !default;
Usage
Example usage for the color($color)
function:
.foo {
color: color('white');
}
.bar {
background-color: c('black');
color: c('white');
}
Example usage of the helper classes:
<p class="color-white">
Eveniet neque velit <span class="color-black">asperiores</span>. Dolores…
</p>
<svg version="1.0" xmlns="http://www.w3.org/2000/svg">
<path d="M…" class="fill-white stroke-black" />
</svg>
framework/_displays.scss
Definitions
$displays-with-force
: wether to create…--force
modifiers with the!important
flag or not$displays-with-breakpoints
: wether to create…--<breakpoint>
modifiers or not$displays
: a list of display value from which to create helper classes@mixin hidden-accessible
: a set of properties to hide an element while keeping it accessible- Class helpers:
.display-<type>[--<breakpoint>|--force[-<breakpoint>]]
: classes setting the propertydisplay
to the given<type>
, with the--force
modifier adding the!important
flag to the declaration, and the<breakpoint>
modifier applying the style to the corresponding breakpoint<type>
:none
,block
,flex
,inline
,inline-block
<breakpoint>
: any of the defined breakpoints
.display-hidden-accessible
: a class using thedisplay-hidden-accessible()
mixin
Defaults
/** @type {Boolean} Do we need the `--force` modifiers? */
$displays-with-force: false !default;
/** @type {Boolean} Do we need the `--<breakpoint>` modifiers? */
$displays-with-breakpoints: false !default;
/** @type {List} List of display values to use */
$displays: (none, block, inline, inline-block) !default;
Usage
Example usage for the display-hidden-accessible
mixin:
.foo {
@include display-hidden-accessible; // Hide this element while keeping it accessible
}
Example usage for the helper classes:
<!-- Display an inline element as a block -->
<span class="display-block"></span>
<!-- Force an inline display on an element -->
<div class="display-inline--force"></div>
<!-- Hide an element on small screen, display it as a block on bigger ones -->
<div class="display-none--xxs display-block--m"></div>
framework/_easings.scss
Definitions
Defines a set of defaults easing variables, from $in-quad
to $in-out-back
.
Defaults
$in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53) !default;
$out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94) !default;
$in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955) !default;
$in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19) !default;
$out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1) !default;
$in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1) !default;
$in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22) !default;
$out-quart: cubic-bezier(0.165, 0.84, 0.44, 1) !default;
$in-out-quart: cubic-bezier(0.77, 0, 0.175, 1) !default;
$in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06) !default;
$out-quint: cubic-bezier(0.23, 1, 0.32, 1) !default;
$in-out-quint: cubic-bezier(0.86, 0, 0.07, 1) !default;
$in-sine: cubic-bezier(0.47, 0, 0.745, 0.715) !default;
$out-sine: cubic-bezier(0.39, 0.575, 0.565, 1) !default;
$in-out-sine: cubic-bezier(0.445, 0.05, 0.55, 0.95) !default;
$in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035) !default;
$out-expo: cubic-bezier(0.19, 1, 0.22, 1) !default;
$in-out-expo: cubic-bezier(1, 0, 0, 1) !default;
$in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335) !default;
$out-circ: cubic-bezier(0.075, 0.82, 0.165, 1) !default;
$in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86) !default;
$in-back: cubic-bezier(0.6, -0.28, 0.735, 0.045) !default;
$out-back: cubic-bezier(0.175, 00.885, 0.32, 1.275) !default;
$in-out-back: cubic-bezier(0.68, -0.55, 0.265, 1.55) !default;
Usage
.foo {
transition: transform 0.6s $in-out-expo;
}
framework/index.scss
Definitions
Imports all the framework files with the $has-classes
variable set to false !default
.
Usage
// Import all the framework files at once
@import '@studiometa/scss-toolkit';
framework/_layers.scss
Definitions
$layers-with-force
: wether to create…--force
modifiers with the!important
flag or not$layers-with-breakpoints
: wether to create…--<breakpoint>
modifiers or not$layers
: a map of names and values of layers@function layer($layer, $modifier)
: a function to get a layer value by its name defined in the previous map@function l($layer, $modifier)
: an alias for thelayer(...)
function@function z($layer, $modifier)
: a legacy alias for thelayer(...)
function@mixin for-each-layers($excludes)
: a mixin to abstract the loop over the$colors
map, with the color name and its value as mixin props- Class helpers:
.layer-<layer>[--<breakpoint>|--force[-<breakpoint>]]
: classes setting thez-index
property to the corresponding value, with the--force
modifier adding an!important
flag, and the<breakpoint>
modifier applying the style to the corresponding breakpoint<layer>
: one of the defined layers<breakpoint>
: any of the defined breakpoints
Defaults
/** @type {Boolean} Do we need the `--force` modifiers? */
$layers-with-force: false !default;
/** @type {Boolean} Do we need the `--<breakpoint>` modifiers? */
$layers-with-breakpoints: false !default;
/**
* Map of layer names and values to use
*
* @type {Map}
*/
$layers: (
goku: 9000,
default: 1,
limbo: -999,
) !default;
Usage
Example usage of the functions:
.foo {
z-index: layer('goku');
&[aria-hidden="true"] {
z-index: l('limbo');
}
}
.bar {
z-index: l('default', 2); // z-index: 3;
}
Example usage of the helper classes:
<!-- Apply the `modal` layer value -->
<div class="modal layer-modal"></div>
framework/_spaces.scss
Definitions
$spaces-base
: the base value of your spaces, can be of any unit, butrem
is advised$spaces
: a list of factor of the base value for the different spaces value in your project@function space($space)
: a function returning the computed value for a given$space
defined in the$spaces
list@function s($space)
: alias for the abovespace($space)
function@mixin for-each-spaces($excludes)
: a mixin to abstract the loop over the$spaces
list with the space name and its value passed as props- Class helpers:
.space-<direction>-<size>[--<breakpoint>]
: classes setting the property defined by<direction>
to the given<size>
, with the<breakpoint>
modifier applying the style to the corresponding breakpoint<direction>
: one ofm
,my
,mx
,mt
,mr
,mb
,ml
,p
,py
,px
,pt
,pr
,pb
andpl
<size>
: any of the defined spaces<breakpoint>
: any of the defined breakpoints
Defaults
The default spaces values are based on the power of two, with a base unit starting at 8px (0.5rem).
/** @type {Number} The base value of all spacings */
$spaces-base: 8px / 16px * 1rem !default;
/** @type {List} List of all space factors */
$spaces: (0, 1, 2, 4, 8, 16, auto) !default;
Usage
$spaces-base: 0.5rem;
$spaces: (0, 1, 2, 4, 8, 16, auto);
// SCSS
.foo {
margin: space(4); // 4 * 0.5rem
}
// CSS
.foo {
margin: 2rem;
}
// SCSS
.baz {
margin-right: s(auto);
margin-left: s(auto);
}
<!-- Horizontal padding of 2 times the base unit and 4 times on bigger screens -->
<div class="space-px-2 space-px-4--s"></div>
<!-- Centering an element -->
<div class="space-mx-auto"></div>
framework/_typography.scss
Definitions
@mixin reponsize-type($min-width: 0, $max-width: 2560, $min-size: 12, $max-size: 16)
: a mixin to generate declaration for responsive font-sizes@mixin type-antialiased
: a mixin to generate properties for antialiased font rendering$type-sizes
: a map of font-sizes lists to be used in your project structured as<name>: ( size: <font-size>[, line-height: <line-height>][, weight: <font-weight>])
<name>
: the name of the size<font-size>
: thefont-size
value in pixels<line-height>
: theline-height
value in pixels<font-weight>
: the unitlessfont-weight
value
@mixin font-size($font-size, $unit: 'em')
: a mixin to get CSS properties of the given name defined in the$font-size
map@mixin fz($font-size, $unit: 'em')
: alias for the@include font-size($font-size, $unit)
mixin$type-webfont-dir
: path to the folder of your webfont files (which must be of*.woff
and*.woff2
formats)$type-webfont-display
: thefont-display
property that will be applied to the@font-faces
declarations$type-fonts: (<identifier>: <definition>)
: a map of font identifiers<identifier>
: a unique font name, will be used to generate helper classes<definition>: (stack: <font-family>, [name: <font-name>, webfonts: <webfonts>)
: a map defining the font stack and its webfonts if needed<stack>
: the full stack of fonts and their fallbacks, will be used to declare thefont-family
property<font-name>
: the name of the font, used to set thefont-family
property in the@font-faces
declaration<webfonts>: (filename: <filename>, weight: <font-weight>, style: <font-style>)
: a list of maps containing the filename, weight and style of each wbefont to declare in an@font-faces
statement<filename>
: the name of thewoff
andwoff2
files of your webfont, without extension<font-weight>
: the weight corresponding to the given filename (a number from100
to900
)<font-style>
: the style of the given filename (normal
,italic
, etc.)
@function font-family($type-font)
: a function to get afont-family
stack by a given identifier@function ff($type-font)
: alias for the abovefont-family($type-font)
function- Class helpers:
.type-antialiased
: a class implementing thetype-antialiased
mixin.type[-rem]-<size>[--<breakpoint>]
: set thefont-size
inem
andline-height
properties to the given<size>
defined values, with the-rem
variation setting thefont-size
unit inrem
and the<breakpoint>
modifier applying the styles to the corresponding breakpoint<size>
: a name defined in the$font-sizes
map<breakpoint>
: a breakpoint's name defined in the$breakpoints
map
.type-<font-name>
: set thefont-family
property to the corresponding stack in the$type-fonts
map<font-name>
: the unique identifier given to the font
.type-align-<alignment>[--<breakpoint>]
: set thetext-align
property, with the<breakpoint>
modifier applying the styles to the corresponding breakpoint<alignment>
: one of the value defined in the$type-alignments
map,center
,left
, orright
by defaults<breakpoint>
: a breakpoint's name defined in the$breakpoints
map
.type-<weight>[--<breakpoint>]
: set thefont-weight
property to the given<weight>
, with the<breakpoint>
modifier applying the style to the corresponding breakpoint<weight>
: one of the value defined in the$type-weights
map,300
,400
or700
by defaults<breakpoint>
: a breakpoint's name defined in the$breakpoints
map
.type-spacing-<value>[--<breakpoint>]
: set theletter-spacing
property to the given value, with the<breakpoint>
modifier applying the style to the corresponding breakpoint<value>
: one of the value defined in the$type-spacings
map,25
,50
,100
,200
by defaults<breakpoint>
: a breakpoint's name defined in the$breakpoints
map
.type-transform-<transform>
: set thetext-transform
property to the given<transform>
<transform>
: one of the value defined in the$type-transforms
map,uppercase
,lowercase
orcapitalize
by defaults
.typ-decoration-<decoration>
: set thetext-decoration
property to the given<decoration>
value<decoration>
: one of the value defined in the$type-decorations
map,none
orunderline
by defaults
Defaults
/**
* A map to define all type-sizes and their corresponding line-heights, the
* first value is the font-size, the seconde the line-height.
*
* @type {Map}
*/
$type-sizes: (
display-1: (
size: 32px,
line-height: 48px,
weight: 700,
),
display-2: (
size: 24px,
line-height: 36px,
weight: 700,
),
body: (
size: 16px,
),
small: (
size: 12px,
),
) !default;
/** @type {String} The path to the webfonts directory */
$type-webfont-dir: '/static/fonts/' !default;
/** @type {String} The value for all `font-display` properties */
$type-webfont-display: auto !default;
/**
* A map to define all font-families specifications which we might refer to by a
* named identifier. The map is formatted as follow:
*
* (
* <identifier>: (
* name: <font-family-name>,
* stack: <font-family-stack>,
* webfonts: (
* (
* filename: <webfont-filename>,
* weight: <webfont-weight>,
* style: <webfont-style>,
* ),
* ),
* ),
* )
*
* @type {Map}
*/
$type-fonts: (
serif: (
name: Georgia,
stack: 'Georgia, serif',
webfonts: (
(
filename: 'georgia-regular',
weight: 400,
style: normal,
),
),
),
sans-serif: (
name: Arial,
stack: 'Arial, sans-serif',
webfonts: (
(
filename: 'arial-regular',
weight: 400,
style: normal,
),
),
),
) !default;
/** @type {List} List of alignment values to use */
$type-alignments: (left, center, right) !default;
/** @type {List} List of font weights values to use */
$type-weights: (300, 400, 700) !default;
/** @type {List} List of letter spacings values to use */
$type-spacings: (25, 50, 100, 200) !default;
/** @type {List} List of text transform values to use */
$type-transforms: (uppercase, lowercase, capitalize) !default;
/** @type {List} List of text decoration values to use */
$type-decorations: (none, underline) !default;
Usage
.title {
@include fz('display-1');
@include type-antialiased;
}
<!-- Adjust the size of a title on different breakpoints -->
<h1 class="type-display-1--xxs type-display-2--s">Foo Bar</h1>
<!-- Center a text -->
<p class="type-align-center">Lorem ipsum dolor…</p>
Components
This toolkit come with some useful components : a grid, a reset and a debug helper.
components/debug.scss
Definitions
This component defines colored outlines on every HTML element, useful to debug layout on a page.
Usage
To use it, simply import the component in your project:
// You can import it globally
@import '@studiometa/scss-toolkit/src/components/debug';
// Or locally to enable debug only on a component
.my-component {
@import '@studiometa/scss-toolkit/src/components/debug';
}
components/grid.scss
Definitions
$grid-columns
: the number of columns your grid should have, default is12
$grid-gutters
: a map defining the gutter for each breakpoint of your grid component$grid-breakoints
: a map defining all breakpoints available for your grid, default to the value of$breakpoints
defined in the framework- Component classes:
.grid[--<modifier>]
: the component's BEM block, with modifier being one ofnested
orno-gutter
.grid--nested
: modifier used to nest grid components.grid--no-gutter
: modifier used to have a grid without any gutter
.grid__row[--<modifier>]
: used to set up a row in you grid, with some<modifier>
to take advantage of some flex alignment properties.grid__row--end
: apply the propertyalign-items
with the valueflex-end
to the row, used to align all columns in a row to the bottom.grid__row--center
: apply the propertyalign-items
with the valuecenter
to the row, used to center all columns in a row.grid__row--stretch
: apply the propertyalign-items
withe the valuestretch
to the row, used to stretch all columns in a row to the same height
.grid__col-<columns>--<breakpoint>
: the component's column classes<columns>
: a number from 1 to the total number of columns defined in the$grid-columns
variable<breakpoin>
: name of one of the breakpoint defined in the$grid-breakpoints
variable
grid__pull-<columns>--<breakpoint>
: negative offset classes, used to pull columns to the left by the given<columns>
count<columns>
: a number from 1 to the total number of columns defined in the$grid-columns
variable<breakpoint>
: name of one of the breakpoint defined in the$grid-breakpoints
variable
grid__push-<columns>--<breakpoint>
: offset classes, used to push columns from the left by the given<columns>
count<columns>
: a number from 1 to the total number of columns defined in the$grid-columns
variable<breakpoint>
: name of one of the breakpoint defined in the$grid-breakpoints
variable
.grid__col-<type>--<breakpoint>
<type>
:.grid__col-center--<breakpoint>
: center the column in its row.grid__col-clear--<breakpoint>
: clear the float of the previous column, creates a line-break in your grid.grid__col-no-clear--<breakpoint>
: reverse the effect of the previous class.grid__col-left--<breakpoint>
: float a column to the left from the given breakpoint and up.grid__col-right--<breakpoint>
: float a column to the right from the given breakpoint and up.grid__col-0--<breakpoint>
: hide a column from the given breakpoint and up
<breakpoint>
: name of one of the breakpoint defined in the$grid-breakpoints
variable
Defaults
$grid-columns: 12 !default;
$grid-gutter: space(4) !default;
$grid-breakpoints: $breakpoints !default;
Usage
<!-- One column on mobile, two on tablets and three on desktop -->
<div class="grid">
<div class="grid__row">
<div class="grid__col-12--xxs grid__col-6--s grid__col-4--l">…</div>
<div class="grid__col-12--xxs grid__col-6--s grid__col-4--l">…</div>
</div>
</div>
<!-- A nested grid in a centered main column -->
<div class="grid">
<div class="grid__row">
<div class="
grid__col-12--xxs
grid__col-10--xs
grid__push-1--xs
grid__col-8--m
grid__push-2--m
grid__col-6--l
grid__push-3--l
">
<div class="grid grid--nested">
<div class="grid__row">
<div class="grid__col-6--xxs">…</div>
<div class="grid__col-6--xxs">…</div>
</div>
</div>
</div>
</div>
</div>
components/reset.scss
Definitions
The reset component only import the classic reset.css.
Contributing
This project uses Git Flow as a branching model and a combo of Stylelint and Prettier to lint the SCSS files. You can lint your modifications when contributing with the following commands:
# Lint all files in the src/ folder
$ yarn lint
# or
$ npm run lint
# Try to fix all lint errors/warnings
$ yarn fix
# or
$ npm run fix