glidecss v0.9.14
Glide CSS
A tiny component-first CSS framework for Sass; with a zero footprint by default. Build solid design systems with a set of simple tools, and the power to generate utility classes where appropriate.
Usage
Themes
At the heart of Glide is the ability to define a free-form theme
.
SCSS
@import "glidecss/base";
@include theme((
palette: (
primary: (
1: #fff,
2: #eee,
3: #888
),
accent: (
1: #e70,
2: #f80,
3: #f91
)
),
spacing: (
1: .25rem,
2: .5rem,
3: .75rem
)
));
This is a basic theme which can be accessed by using the theme
function.
SCSS
.button {
padding: theme(spacing, 3);
color: theme(palette, primary, 1);
background: theme(palette, accent, 2);
&:hover {
background: theme(palette, accent, 3);
}
}
CSS
.button {
padding: .75rem;
color: #fff;
background: #f80;
}
.button:hover {
background: #f91;
}
Defaults
A default property can be defined within a set of properties, via the DEFAULT
property key.
SCSS
@include theme((
radius: (
DEFAULT: .25rem,
large: .5rem
)
));
The default is returned when requesting the parent property, so the following are equivilent.
SCSS
border-radius: theme(radius); // <- .25rem
border-radius: theme(radius, DEFAULT); // <- .25rem
Overrides
The theme
mixin performs a non-destrutive merge — in a similar fashion to the !default
operator in Sass — so multiple calls will only add what's new.
SCSS
@include theme((
radius: (
large: .5rem
)
));
@include theme((
radius: (
small: .125rem,
large: 1rem
)
));
This is equivilent to the following, as the original large
property is preserved.
SCSS
@include theme((
radius: (
small: .125rem,
large: .5rem
)
));
As you can see, this means that overrides should be defined before futher theme declarations. More on why this is powerful in the dedicated overrides section.
Components
Global theme properties are powerful when combined with component theme properties.
SCSS
@include theme((
menu: (
background: theme(palette, primary, 2)
padding: theme(spacing, 2),
item: (
display: inline-block
)
)
));
.menu {
background: theme(menu, background);
padding: theme(menu, padding);
}
.menu__item {
display: theme(menu, item, display);
}
CSS
.menu {
background: #eee;
padding: .5rem
}
.menu__item {
display: inline-block;
}
Here our component properties make use of global theme properties, keeping our styling DRY (Don't Repeat Yourself).
Screens
Glide is mobile first by default, so you can specify styles that trigger for, and above, a given screen
size. See configuration section for how to set screen sizes.
Manual
Use screen
to manually define styles for a named screen.
SCSS
.menu {
padding: theme(spacing, 2);
@include screen(lg) {
padding: theme(spacing, 3);
}
}
CSS
.menu {
padding: .5rem;
}
@media (min-width: 1024px) {
.menu {
padding: .75rem;
}
}
Lookup
We can make a component responsive by defining properties that trigger for various screens
.
SCSS
@include theme((
menu: (
background: theme(palette, primary, 2),
padding: (
DEFAULT: theme(spacing, 2),
lg: theme(spacing, 3)
),
item: (
display: (
DEFAULT: block,
md: inline-block
)
)
)
));
.menu {
background: theme(menu, palette, background);
@include screens(menu, padding) using ($padding) {
padding: $padding;
}
}
.menu__item {
@include screens(menu, item, display) using ($display) {
display: $display;
}
}
Responsive properties are named after their screen name. The DEFAULT
will be defined first, as the fallback for all screens.
CSS
.menu {
background: #eee;
padding: .5rem;
}
@media (min-width: 1024px) {
.menu {
padding: .75rem;
}
}
.menu__item {
display: block;
}
@media (min-width: 768px) {
.menu__item {
display: inline-block;
}
}
Lookup (shorthand)
It can be cumbersome to write out the longhand block for a single property, so there is a shorthand that takes a property and a path list:
SCSS
##### SCSS
```scss
@include theme((
menu: (
padding: (
DEFAULT: theme(spacing, 2),
lg: theme(spacing, 3)
)
)
));
.menu {
@include screens(padding, (menu, padding));
}
CSS
.menu {
padding: .5rem;
}
@media (min-width: 1024px) {
.menu {
padding: .75rem;
}
}
Inline
You can supply a map to screens
, although property lookup is recommended.
SCSS
.menu {
@include screens((
DEFAULT: theme(spacing, 2),
lg: theme(spacing, 3)
)) using ($padding) {
padding: $padding;
}
}
CSS
.menu {
padding: .5rem;
}
@media (min-width: 1024px) {
.menu {
padding: .75rem;
}
}
Inline (shorthand)
It can be cumbersome to write out the longhand block for a single property, so there is a shorthand that takes a property and an inline map:
SCSS
##### SCSS
```scss
.menu {
@include screens(padding, (DEFAULT: theme(spacing, 2), lg: theme(spacing, 3)));
}
CSS
.menu {
padding: .5rem;
}
@media (min-width: 1024px) {
.menu {
padding: .75rem;
}
}
Configure
To configure the screen sizes available, just add a screens
property to the theme.
SCSS
@include theme((
screens: (
custom: 800px
)
));
.button {
@include screen(custom) {
padding: theme(spacing, 3);
}
}
CSS
@media (min-width: 800px) {
.button {
padding: .75rem;
}
}
Modes
You can specify styles that should be used for a given mode
, for example dark
mode. By default, a mode is triggered via a parent class named after the mode; usually on the html element.
Manual
Use mode
to manually define styles for the named mode.
SCSS
.menu {
background: theme(palette, primary, 2);
@include mode(dark) {
background: theme(palette, primary, 3)
}
}
CSS
.menu {
background: #eee;
}
.dark .menu {
background: #888;
}
Lookup
To easily set properties across modes, we can make use of modes
to look them up.
SCSS
@include theme((
menu: (
background: (
DEFAULT: theme(palette, primary, 2),
dark: theme(palette, primary, 3)
)
)
));
.menu {
@include modes(menu, background) using ($background) {
background: $background;
}
}
CSS
.menu {
background: #eee;
}
.dark .menu {
background: #888;
}
Lookup (shorthand)
It can be cumbersome to write out the longhand block for a single property, so there is a shorthand that takes a property and a path list:
SCSS
@include theme((
menu: (
background: (
DEFAULT: theme(palette, primary, 2),
dark: theme(palette, primary, 3)
)
)
));
.menu {
@include modes(background, (menu, background));
}
CSS
.menu {
background: #eee;
}
.dark .menu {
background: #888;
}
Inline
You can supply a map to modes
, although property lookup is recommended.
SCSS
.menu {
@include modes((
DEFAULT: theme(palette, primary, 2),
dark: theme(palette, primary, 3)
)) using ($background) {
background: $background;
}
}
CSS
.menu {
background: #eee;
}
.dark .menu {
background: #888;
}
Inline (shorthand)
It can be cumbersome to write out the longhand block for a single property, so there is a shorthand that takes a property and an inline map:
SCSS
.menu {
@include modes(background, (
DEFAULT: theme(palette, primary, 2),
dark: theme(palette, primary, 3)
));
}
CSS
.menu {
background: #eee;
}
.dark .menu {
background: #888;
}
Configure
To configure the modes available, just add a modes
property to the theme in the following format. Each <token>
will be replaced with the relevant value.
SCSS
@include theme((
modes: (
dimmed: '.<mode> <selector>'
),
palette: (
primary: (
1: (
DEFAULT: #fff,
dimmed: #444
)
)
)
));
body {
@include modes(palette, primary, 1) using ($background) {
background: $background;
}
}
CSS
body {
background: #fff;
}
.dimmed body {
background: #444;
}
Utilities
Glide encourages components where possible, however you can generate utilities where it makes sense. We can use variants
and modifiers
to generate utility classes.
Variants
Variants allow us to generate utility classes with a prefix. By default, we can generate variants for screen
, mode
, and any pseudo selector such as hover
.
SCSS
.box {
@include variants(screen, hover) {
padding: theme(spacing, 4);
}
}
CSS
.box {
padding: 1rem;
}
@media (min-width: 640px) {
.sm\:box {
padding: 1rem;
}
}
@media (min-width: 768px) {
.md\:box {
padding: 1rem;
}
}
/* ... */
.hover\:box:hover {
padding: 1rem;
}
Modifiers
Modifiers allow us to generate utility classes with suffixes, based on a theme property or Sass map.
SCSS
.box {
@include modifiers(spacing) using ($spacing) {
padding: $spacing;
}
}
CSS
.box-1 {
padding: .25rem;
}
.box-2 {
padding: .5rem;
}
.box-3 {
padding: .75rem;
}
/* etc. */
You can also specify an inline map, although property lookup is recommended.
SCSS
.box {
@include modifiers((1: .25rem, 2: .5rem)) using ($spacing) {
padding: $spacing;
}
}
CSS
.box-1 {
padding: .25rem;
}
.box-2 {
padding: .5rem;
}
Modifiers (shorthand)
It can be cumbersome to write out the longhand block for a single property, so there is a shorthand that takes a property with a path list or inline map:
SCSS
.box {
@include modifiers(padding, (spacing));
}
CSS
.box-1 {
padding: .25rem;
}
.box-2 {
padding: .5rem;
}
.box-3 {
padding: .75rem;
}
/* etc. */
You can also specify an inline map, although property lookup is recommended.
SCSS
.box {
@include modifiers(padding, (1: .25rem, 2: .5rem));
}
CSS
.box-1 {
padding: .25rem;
}
.box-2 {
padding: .5rem;
}
Combined
We can combine variants
and modifiers
to create responsive, and/or mode specific utility classes.
SCSS
.box {
@include variants(screen, mode) {
@include modifiers(spacing) using ($spacing) {
padding: $spacing;
}
}
}
CSS
.box-1 {
padding: .25rem;
}
.box-2 {
padding: .5rem;
}
/* ... */
@media (min-width: 640px) {
.sm\:box-1 {
padding: .25rem;
}
.md\:box-2 {
padding: .5rem;
}
/* ... */
}
.dark\:box-1 {
padding: .25rem;
}
.dark\:box-2 {
padding: .5rem;
}
/* ... */
Use this power wisely. If you end up with many utility classes — not recommended — then it's advised that you add purgecss to your project.
Configure
To configure the variants available, just add a variants
property to the theme
in the following format. Each <token>
will be replaced with the relevant value.
SCSS
@include theme((
variants: (
first: '<class>:<variant>-child',
last: '<class>:<variant>-child'
)
));
.highlight {
@include variants(first, last) {
background: theme(palette, accent, 2);
}
}
CSS
.highlight {
background: #f80;
}
.first\:highlight:first-child {
background: #f80;
}
.last\:highlight:last-child {
background: #f80;
}
Reset
Glide comes with a simple opt-in reset, just import the reset
stylesheet.
SCSS
@import "glidecss/reset";
Defaults
Glide provides a set of opt-in defaults. You can include them all, or cherry pick the ones you'd like. To include them all, just import the main defaults file.
SCSS
@include "glidecss/defaults";
Screens
The default screens are shown below.
Screen | Min width |
---|---|
sm | 640px |
md | 768px |
lg | 1024px |
xl | 1280px |
xxl | 1536px |
SCSS
@include "glidecss/defaults/screens";
body {
@include screen(md) {
padding: 1rem;
}
}
CSS
@media (min-width: 768px) {
body {
padding: 1rem;
}
}
Modes
The default modes are show below.
Mode | Value |
---|---|
dark | .<mode> <selector> |
SCSS
@include "glidecss/defaults/modes";
body {
@include mode(dark) {
background: black;
}
}
CSS
.dark body {
background: black;
}
Variants
The default variants are show below.
Mode | Value |
---|---|
DEFAULT | <class>:<variant> |
screen | (type: screen) |
mode | (type: mode ) |
SCSS
@include "glidecss/defaults/variants";
.box {
@include variants(screen) {
padding: 1rem
}
}
CSS
.box {
padding: 1rem;
}
@media (min-width: 640px) {
.sm\:box {
padding: 1rem;
}
}
/* ... */
Palette
The default palette is accessed with theme(palette, <name>, <tone>, <mode>)
; color names are semantic, so tweak as necessary to fit your brand.
Primary
Tone | Default mode | Dark mode |
---|---|---|
0 | tint(#22272f, 0%) | shade(#22272f, 90%) |
1 | tint(#22272f, 35%) | shade(#22272f, 70%) |
2 | tint(#22272f, 65%) | shade(#22272f, 40%) |
3 | tint(#22272f, 85%) | shade(#22272f, 20%) |
4 | tint(#22272f, 95%) | shade(#22272f, 10%) |
5 | tint(#22272f, 100%) | tint(#22272f, 0%) |
6 | tint(#22272f, 95%) | tint(#22272f, 10%) |
7 | tint(#22272f, 85%) | tint(#22272f, 20%) |
8 | tint(#22272f, 65%) | tint(#22272f, 40%) |
9 | tint(#22272f, 35%) | tint(#22272f, 70%) |
10 | tint(#22272f, 0%) | tint(#22272f, 90%) |
Note the use of supplied tint
and shade
functions.
SCSS
@include "glidecss/defaults/palette";
body {
@include modes(palette, primary, 10) using ($color) {
color: $color
}
@include modes(palette, primary, 5) using ($background) {
background: $background
}
}
CSS
body {
color: #22272f;
background: #fff;
}
.dark body {
color: #fff;
background: #22272f;
}
Here 10
works well as a foreground color, and 5
as a background color. This allows you to switch modes, with predictable results.
Spacing
The default spacing values are accessed with theme(spacing, <name>)
.
Name | Size | Pixels |
---|---|---|
1 | .25rem | 4px |
2 | .5rem | 8px |
3 | 1rem | 16px |
4 | 1.5rem | 24px |
5 | 2rem | 32px |
6 | 2.5rem | 40px |
7 | 3rem | 48px |
8 | 4rem | 64px |
9 | 5rem | 80px |
10 | 6rem | 96px |
11 | 7rem | 112px |
12 | 8rem | 128px |
SCSS
@include "glidecss/defaults/spacing";
.button {
padding: theme(spacing, 3);
}
CSS
.button {
padding: 1rem;
}
Font family
The default font families are accessed with theme(font, family, <name>)
.
Name | Value |
---|---|
sans | ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol","Noto Color Emoji" |
serif | ui-serif, Georgia, Cambria, "Times New Roman", Times, serif |
mono | ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace |
SCSS
@include "glidecss/defaults/font/family";
.heading {
font-family: theme(font, family, serif);
}
CSS
.heading {
font-family: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
}
Font size
The default font sizes are accessed with theme(font, size, <name>)
.
Name | Size (default) | Pixels (default) | Size (lg) | Pixels (lg) |
---|---|---|---|---|
1 | 0.75rem | 12px | ||
2 | 0.875rem | 14px | ||
3 | 1rem | 16px | ||
4 | 1.125rem | 18px | 1.25rem | 20px |
5 | 1.375rem | 22px | 1.5rem | 24px |
6 | 1.625rem | 26px | 2rem | 32px |
7 | 2rem | 32px | 2.5rem | 40px |
8 | 2.5rem | 40px | 3rem | 48px |
SCSS
@include "glidecss/defaults/font/size";
.heading {
@include screens(font, size, 7) using ($font-size) {
font-size: $font-size;
}
}
CSS
.heading {
font-size: 2rem;
}
@media (min-width: 1024px) {
.heading {
font-size: 2.5rem;
}
}
Font leading
The default font line heights are accessed with theme(font, leading, <name>)
.
Name | Leading |
---|---|
DEFAULT | 1.5 |
tight | 1.25 |
loose | 1.75 |
SCSS
@include "glidecss/defaults/font/leading";
.heading {
line-height: theme(font, leading, tight);
}
CSS
.heading {
line-height: 1.75;
}
Font weight
The default font weights are accessed with theme(font, weight, <name>)
.
Name | Weight |
---|---|
light | 300 |
normal | 400 |
medium | 500 |
bold | 700 |
SCSS
@include "glidecss/defaults/font/weight";
.heading {
font-weight: theme(font, weight, bold);
}
CSS
.heading {
font-weight: 700;
}
Overrides
Note that if you want to override any defaults, the overrides should be declared before including the defaults file. This is due to theme
performing a non-destrutive merge; in a similar fashion to the !default
operator in Sass.
SCSS
@include theme((
spacing: (
0: .125rem,
1: .5rem
)
));
@include "glidecss/defaults";
This will add an additional 0
spacing property, and define a larger than normal 1
property. When the defaults are included, they will leave both of these initial values alone, and only add the remaining properties.
The non-destrutive merge is a super powerful tool when overriding component properties, allowing for a base set of reusable components that can be customised on a project basis.
SCSS
@include theme((
card: (
color: palette(primary, 1),
background: palette(accent)
)
));
@include "card";
Installation
Yarn
yarn add glidecss --dev
NPM
npm install -D glidecss
Import
SCSS
@import "glidecss/base";
@import "glidecss/reset"; // <- optional
@import "glidecss/defaults"; // <- optional
Development
Tests
The test suite will automatically be run by GitHub Actions on a push or pull request.
To manually run the Jest test suite:
yarn test
Releases
Releases are automatically handled by GitHub Actions. Just set the semantic version number in package.json
, tag, push and the rest will happen automatically.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/thelucid/glidecss. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The library is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Glide CSS project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.