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); // <- .25remOverrides
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 --devNPM
npm install -D glidecssImport
SCSS
@import "glidecss/base";
@import "glidecss/reset"; // <- optional
@import "glidecss/defaults"; // <- optionalDevelopment
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 testReleases
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.