@neolithic-css/toolkit v1.4.0
Toolkit for generate fully customizable CSS utility classes written in Sass.
Why?
There are tons of CSS frameworks we could choose, while lots of them are just too complex. What I want is just a minimum yet flexible API that could generate all kinds of CSS utilities that match MY requirements easily. Tailwind CSS is cool, but I don't like the name convention of it.
Another thing is that I've never seen a framework that has what I called "Fluid Utility" support. It's really annoying to writing lots of "responsive utility" classes 😣
I wasn't able to find any tools meet my requirements, so I made one.
Installation
You can install it via npm 📦
npm i @neolithic-css/toolkit
Basic Usage
If you use webpack's sass loader, just reference it using the ~
syntax 🤟🏼
Here is a simple example for generating a series of "fluid utilities" for the font-size
.
@use "~@neolithic-css/toolkit" as *;
@include add-fluid-utility(
$property-name: font-size,
$property-value: 14px 16px 18px 20px,
$property-name-alias: fz,
$step: 2px,
);
// Don't forget to call the `build` mixin,
// this mixin outputs all the utilities you added.
@include build;
The above example generates a bunch of "fluid utilities".
For example the class .fz:20~14
indicates font-size
gradually changes from 20px
to 14px
when viewport get resized from 1024px
to 320px
(by default).
Sure you could generate the good old "responsive utilities" as well by utilizing the add-simple-utility
or add-compound-utility
mixin (I'll explain the difference between them later on).
For instance
@include add-simple-utility(
$property-name: font-size,
$property-value: 14px 16px 18px 20px,
$property-name-alias: fz,
);
For example the class .fz:20px@xl
indicates font-size: 20px
applied at viewport size xl
(1256px).
Well the naming convention is totally up to you.
You could config the settings by initializing the global configurations values or specify the settings via the mixin directly.
Global Configurations
Below are the default values of global configurations.
$breakpoints: (
xs: 320px,
sm: 550px,
md: 768px,
lg: 1024px,
xl: 1256px,
xxl: 1600px,
) !default;
// default settings for generating fluid utilities
$fluid: (
start-shrinking-width: default(map.get($breakpoints, lg), 1024px),
stop-shrinking-width: default(map.get($breakpoints, xs), 320px),
strip-unit: true,
step: 10px,
min: 0px,
) !default;
$property-name-delimiter: ':' !default;
$query-delimiter: '@' !default;
$important: true;
For example, if you'd like to giving your own breakpoints, you overwrite the default one by utilizing the with
keyword.
@use "~@neolithic-css/toolkit" as * with
(
$breakpoints: (
sm: 500px,
md: 900px,
lg: 1300px,
xs: 300px,
),
$important: false, // do not append `!important` at the end of css rules.
);
Or you may overwrite it via mixin directly like this.
@include add-simple-utility(
$property-name: font-size,
$property-value: 14px 16px 18px 20px,
$property-name-alias: fz,
// notice that only `$breakpoints` can't be overwrite in mixin,
// here you are saying only output utility classes for size `sm` and `md`.
$breakpoints: (sm, md),
$important: false,
);
Naming Convention
By default, the CSS classname is consists of several parts.
- $property-name-alias
- $property-value-alias
- $property-name-delimiter
- $query-delimiter
- $breakpoint-name
For example, this is the simplest form you can generate a utility.
@include add-simple-utility(
$property-name: display,
$property-value: block,
);
This piece of code gives you :
.display\:block {
display: block !important;
}
/* utilities with media query */
@media (max-width: 320px) {
.display\:block\@xs {
display: block !important;
}
}
in the classname .display:block@xs
, where
display
→$property-name-alias
:
→$property-name-delimiter
block
→$property-value-alias
@
→$query-delimiter
xs
→$breakpoint-name
You can change these parts to whatever you want via global configurations or mixin arguments, or totally ignore them by specifying a $class
argument to the mixin.
I'm not trying to impose my opinion to anyone, but I thought it would be clearer to explicitly separate each part by their functions instead of just joining them all together with the -
.
As I said, you can pass a $class
argument to the mixin if you are not cool with this 🙏🏼
Simple-Utility vs. Compound-Utility
- Simple-Utility : utilities which have only one CSS rule.
- Compound-Utility : utilities which have multiple CSS rules.
For example:
.simple-utility {
margin-top: 10px;
}
.compound-utility {
margin-top: 10px;
font-size: 20px;
}
I grouped utilities into these two types because of the naming convention.
That is, a compound utility can't have a $property-value-alias
and $property-name-alias
.
There are three main mixins you can use to generate utilities:
add-simple-utility
add-fluid-utility
add-compound-utility
As the names of the mixins implied, you use different mixin to generate different type of utilities. The "fluid utility" is simple-utility too.
Tips
There are several helper functions provided within this package.
Before you can use them, make sure you have imported them via the @use
keyword.
@use "~@neolithic-css/toolkit/src/functions" as *;
The range
helper function
Say if you want to generate a series of utilities like this:
.grid-cols\:12 {
grid-template-columns: repeat(12, minmax(0, 1fr)) !important;
}
.grid-cols\:11 {
grid-template-columns: repeat(11, minmax(0, 1fr)) !important;
}
.grid-cols\:10 {
grid-template-columns: repeat(10, minmax(0, 1fr)) !important;
}
.grid-cols\:9 {
grid-template-columns: repeat(9, minmax(0, 1fr)) !important;
}
.grid-cols\:8 {
grid-template-columns: repeat(8, minmax(0, 1fr)) !important;
}
.grid-cols\:7 {
grid-template-columns: repeat(7, minmax(0, 1fr)) !important;
}
.grid-cols\:6 {
grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
}
.grid-cols\:5 {
grid-template-columns: repeat(5, minmax(0, 1fr)) !important;
}
.grid-cols\:4 {
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
}
.grid-cols\:3 {
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
}
.grid-cols\:2 {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
.grid-cols\:1 {
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
}
In such of cases you can utilize the range
helper function like this:
@include add-simple-utility(
$property-name: grid-template-columns,
$property-value: range($from: 1, $to: 12, $step: 1, $template: 'repeat(_$i_, minmax(0, 1fr))'),
$property-name-alias: 'grid-cols',
$property-value-alias: range($from: 1, $to: 12, $step: 1),
);
which is equivalent to:
@include add-simple-utility(
$property-name: grid-template-columns,
$property-value: (
'repeat(12, minmax(0, 1fr))',
'repeat(11, minmax(0, 1fr))',
'repeat(10, minmax(0, 1fr))',
'repeat(9, minmax(0, 1fr))',
'repeat(8, minmax(0, 1fr))',
'repeat(7, minmax(0, 1fr))',
'repeat(6, minmax(0, 1fr))',
'repeat(5, minmax(0, 1fr))',
'repeat(4, minmax(0, 1fr))',
'repeat(3, minmax(0, 1fr))',
'repeat(2, minmax(0, 1fr))',
'repeat(1, minmax(0, 1fr))',
),
$property-name-alias: 'grid-cols',
$property-value-alias: (12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1),
);
add-**-utilities
helper mixin
Each of those add-**-utility
mixins has a corresponded add-**-utilities
helper that can accept a list, so you can register multiple utilities at once.
add-simple-utilities
add-fluid-utilities
add-compound-utilities
For example:
$simple-utilities: (
(
property-name: background-color,
property-value: (#68D391, #F6E05E, #dc3545),
property-name-alias: 'bg',
property-value-alias: (green, yellow, red)
),
(
property-name: display,
property-value: (grid, block, inline-block),
property-name-alias: 'd',
),
(
property-name: grid-template-columns,
property-value: range(1, 12, 1, 'repeat(_$i_, minmax(0, 1fr))'),
property-name-alias: 'grid-cols',
property-value-alias: range(1, 12, 1)
),
(
property-name: gap,
property-value: range(0, 2.5rem, 0.25rem),
property-value-alias: range(0, 10, 1),
property-name-delimiter: '-',
query-delimiter: '|',
),
);
@include add-simple-utilities($simple-utilities...);
Contribution
I really tried to keep this package be simple and lightweight. If you are missing something, feel free to open a pull request 👋