An experimental Utility CSS framework that pushes the limits of SASS to write CSS classes programatically.
Still in development
Inspired by Tailwind CSS, but made purely with SCSS, without Javascript or any other language.
It is a CSS Framework for rapid prototyping and layout. It is focused on providing you with utility classes that define specific CSS properties, like .bg-blue
or .text-center
.
This approach differs from frameworks Bootstrap that give you opinionated component classes that you then have to customize or apply themes to make them your own.
Utility classes give you more freedom to create and customize your UI any way you like while still helping you follow some structure:
<button class="bg-blue text-white p-y-2 p-x-4 rounded hover:bg-blue-darker">
Click me!
</button>
ExtendCSS also generates placeholder %
classes that you can @extend
to create your own components. So if all your buttons have the same classes you should consider them to a new style:
.btn {
@extend %bg-blue, %text-white, %p-y-2, %p-x-4, %rounded, %hover\:bg-blue-darker;
}
<button class="btn">Click me!</button>
If you prefer this component approach and all you need are the placeholder
%
classes you can disable the regular.
classes by setting the$generateClasses
varialble tofalse
on the mainscss/_application.scss
.
To create classes programaticallty we use the make()
mixin. It takes four parameters:
make($base, $properties, $values, $variants);
-
$base: The base name for the class.
$base: 'border'; // .#{$base}-2 { … } .border-2 { border-width: 2px; }
-
$properties: The css property you're modifying with the class. This can be a string for something straightforward like
background-color
or a key/value list generated multiple modifiers classes:$properties: ( 't': 'border-top-weight', 'b': 'border-bottom-weight', … ); // .border-#{$key}-2 { #{$value}: 2px; } .border-t-2 { border-top-weight: 2px; } .border-b-2 { border-bottom-weight: 2px; }
The property value can also be a list for multiple properties:
$properties: ( 'y': ('border-top-width', 'border-bottom-width'), … ); // .border-#{$propertyKey}-2 { #{$propertyValue}: 2px; } .border-y-2 { border-top-width: 2px; border-bottom-width: 2px; }
If the key is
'default'
it won't be used in the class name:$properties: ( 'default': 'border-width', 't': 'border-top-weight', … ); .border-2 { border-width: 2px; } .border-t-2 { border-top-width: 2px; }
-
$values: A key/value list with the class modifier and the property value.
$value: ( '2': '2px', … ); // .border-#{$key} { border-width: #{$value}; } .border-2 { border-width: 2px; }
-
$variants: Variants are special prefixes to your classes. There are three types of variants:
- Special selector variants:
hover
,active
,first-child
…
$variants: ('hover', 'active', …); // .#{$variant}:bg-blue .bg-blue { background-color: #00F; } .hover\:bg-blue { &:hover { background-color: #00F; } }
<button class="bg-blue hover:bg-red active:bg-green"> I'm red on hover, and green on click </button>
- Screen size variants:
xs
,md
,lg
…
$responsive: ( 'sm': '(min-width: 576px)', 'md': '(min-width: 768px)', … ); $variants: ('hover', $responsive); // .#{$responsiveKey}:bg-blue @media (min-width: 768px) { .xs\:bg-blue { background-color: #00F; } }
<button class="bg-blue md:bg-red lg:bg-green"> I'm blue on phones, red on tablets, green on desktop </button>
- Parent target variants:
group-hover
Sometimes you need to change the style of an element when you hover their parent. This is where group-hover is helpful:
$variants: ('group:hover .group-hover', …); // .#{variant}:bg-blue .group:hover .group-hover\:bg-blue { … }
<div class="group border p-4 hover:bg-blue"> <p class="group-hover:text-white">Some text</p> <button class="bg-blue text-white group-hover:bg-white group-hover:text-blue"> Click me </button> </div>
You can use this pattern in creative ways to create other parent variants too:
$variants: ('.dropdown:focus .dropdown-open', …);
<div class="dropdown outline-none" tabindex="0"> <button class="p-2">Options ▾</button> <div class="p-4 border hidden absolute dropdown-open:block"> Dropdown menu… </div> </div>
- Special selector variants:
The main SASS file (scss/_application.scss
) imports the functions and different config files we're going to need.
Then it defines a list of $classes
we want to loop through and run the make()
mixin.
// ($base, $properties, $values, $variants),
$classes: (
('border', $borderWidthProperties, $borderWidths, $borderWidthVariants),
('border', 'border-color', $borderColors, $borderColorVariants),
('border', 'border-style', $borderStyles, $borderStyleVariants),
('rounded', $borderRadiusProperties, $borderRadius, $borderRadiusVariants),
…
);
Take this line as an example:
('border', 'border-color', $borderColors, $borderColorVariants),
The variables $borderColors
and $borderColorVariants
are defined in the sass/config/borders.scss
file, and you can customize them there if needed.
By default $borderColors
is equal to the main list of $colors
. If you don't need colorful borders in your UI you can change that variable to only the border colors you need, for example changing it to ('faded': 'rgba(0,0,0,0.1)')
will generate a single .border-faded
class.
Likewise $borderVariants
by default will generates lots of variants, if you don't plan on changing border colors on hover, or depending on screen size, then you can edit that variable to remove those variants. If you need no variants at all you can set it equal to an empty list ()
.