Why Grease?
Grease combines a trio of ultra-fast tools (11ty, Lightning CSS, and Esbuild) with a modern, declarative CSS architecture that frees you from browser micro-management. It’s light enough for small sites, but has everything you need to tackle large projects without getting bogged down in slow builds, dependency hell, and bloated front-ends. Key benefits:
- Fast in-browser design. Fast tools and a custom-property-powered composable CSS architecture makes designing in browser a joy, and scaffolding new pages fast.
- Zero-config entrypoints. Import everything into monolithic CSS and JS bundles? Break out page bundles? Inline critical CSS? YES.
- No fillers, no additives. Grease takes a platform-first approach and keeps dependencies to minimum so you can focus on building, not bundling.
- Expressive color. Grease includes a comprehensive color system that lets you easily support light & dark mode, custom themes, composable themes, and all of the above.
- Fluid, variable type. A straightforward fluid type system makes it easy to keep your type game on point across a wide range of devices and screen sizes.
- Batteries included. Production-ready odds & ends come in the box. Sitemaps, canonical URL support, no-index support, metadata, etc.
Getting started
- Clone the Grease repository on Github.
- Install with
npm install
. - To start the local dev server, run
npm start
. - Grease is pre-configured for Netlify deployment. You can use the
publish:prod
script and_public
output directory to deploy elsewhere.
Working with CSS
Grease uses a practical, declarative approach to writing modern CSS, using three breakpoints (small, medium, large), and three cascade layers:
base
is where you define the default presentation characteristics for your project. Tailoring the custom media queries, custom properties, typeface, and base elements alone should get you halfway there. A kitchen sink demo is included to make it easy to see the impact of your changes across a wide variety of elements.components
is where you define commonly repeated objects that live across your project. Components care little about their position on any given page.utilities
is for CSS that manipulates elements and components. Grease aims to cover the small subset of attributes that are highly variable (page position, type characteristics, spacing) as opposed to making every property available. This approaches delivers the key benefits of utility css (breaking the linear ratio between page count and lines of CSS, less repetition) without the tooling complexity of build-dependent approaches.
Syntax, draft specs
Components in Grease use a modified BEM syntax, which uses a terse block --modifier1 --modifier2
syntax instead of block--modifier1 block--modifier2
.
Lightning is configured to transpile draft custom media syntax, but nothing else. Adjust as need be for the project at hand.
Breaking up CSS
Grease gives you three options for including CSS:
- In the main bundle. Global stuff goes here.
- As route-specific bundles. Add a CSS file to
source/css/pages
(or any folder not prefixed by an underscore) to create a new entrypoint. Assign the path tostylesheet
in template frontmatter to use it. - As
style
tags. For critical CSS or page-specific one-offs, Grease includes an 11ty bundle that processes CSS with Lightning and adds it to a style tag in the page head.
Working with JS
Like with CSS, Grease supports config-free javascript bundles. A main bundle is included by default, and you can add JS files to source/js
(or any sub-folder not prefixed by an underscore) to create a new bundles. Assign paths to javascript
in template frontmatter to use them.
Grease is designed to use the web platform directly, and assumes ESM. Several custom elements are included; a scroll detector, an element that collapses and expands details
elements at different viewport sizes, and an element that triggers animations on viewport entry.
Layout
Layout with Grease is handled primarily by grid
and flex
utilties. Both are opt-in, which makes it easy to mix in more specific layout needs (or wholesale replace with a different approach). Use margin
and padding
utilities to finnesse interplay between elements.
Grid
Rapidly compose responsive layouts with an infinitely nestable 12 column+2 “bleed” column grid that collapses to 1 column +2 bleed columns @small. Add the .grid
class to a parent container to opt in.
<section class="grid">
<div class="start-1 span-6"></div>
<div class="start-auto bleed-end"></div>
</section>
<section class="grid">
<div class="span-1/3"></div>
<div class="span-1/3"></div>
<div class="span-1/3"></div>
</section>
Grid children
.start-{1-12/auto}
sets the column start positon @md+.span-{1-12}
sets how many columns the element spans at @medium+.bleed
,.bleed-{start/end}
makes elements stick to page edges @sm+.place-{start/center/end}
set placement of content within a grid
Flex
Add the .flex
or .inline-flex
class to a parent container to opt in.
.gap-{sm/md/lg}
sets row and column gap.column-gap-{sm/md/lg}
sets column gap.align-items-{start/center/end}
sets alignment.justify-{start/center/between/end}
sets justification.no-wrap
prevents items from wrapping.column
switches to a vertical orientation- Append
@sm
or@md
to properties to apply at specific breakpoints
Margin
.mt-{0/xs-xxl/flex}
sets block start margin.mb-{0/xs-xxl/flex}
sets block end margin.ml-{0/xs-xxl/flex}
sets inline start margin.mr-{0/xs-xxl/flex}
sets inline end margin- Prepend
-
to set negative margin - Append
@md
to apply at medium+
Padding
.pt-{0/xs-xxl/flex}
sets block start padding.pb-{0/xs-xxl/flex}
sets block end padding.pl-{0/xs-xxl/flex}
sets inline start padding.pr-{0/xs-xxl/flex}
sets inline end padding- Append
@md
to apply at medium+
Typography
Grease uses a semi-fluid type system that attempts to do most of the heavy-lifting for you. Set --size-base
, --size-scale-sm
, and --size-scale-md
in @root.css
and Grease takes it from there. Line height defaults to --leading-fluid
, which decreases as type size increases. A secondary step-based system steps in when you need fine-grained control.
Typographic utilities
.size-{xxxs-xxxxl}
adjusts font size.weight-{200-800}
adjusts font weight.measure-{xs-xl}
limits width to a maximum number of character{.left/.center/.right}
changes text alignment.leading-{flush/xxs-lg}
adjusts line height.tracking-{sm-xl}
adjusts letter spacing.balance
attempts to balance multiple lines of text.italic
,.uppercase
,.unlisted
,.undecorated
do what they suggest
Color & opacity
Grease includes a fully featured color system built around modern features like relative color, light-dark(), and color-mix() that lets you implement page themes, component themes, and light/dark mode without having to micro-manage color. Here’s how it works:
- Set your key colors, like
--primary
,--secondary
, and--neutral
in@root.css
. These colors, along with--50
to--900
tint & shade presets form your base color system. - Create color “presets” like
--color-text
,--color-bg
, etc with baked in light and dark support, and use them liberally to reduce micro-management and make theme-friendly components. To define presets, use relative color syntax along with light-dark(), like so:
--color-text: light-dark(
oklch(from var(--primary) var(--700)),
oklch(from var(--primary) var(--300) / 50%)
)
- Make component-level exceptions by using the same strategy above. Remember that you can always use
calc()
expressions instead of tint & shade presents, like so:
border-color: light-dark(
oklch(from var(--secondary) calc(l * 1.5) c h),
oklch(from var(--secondary) calc(l / 1.5) c h)
)
- Use color and opacity utilities to make context-specific adjustments and one-offs.
- Create additional themes by creating a class in
css/_base/themes.css
that redefines your base colors and your color presets. Add the class to the HTML element using thetheme
front matter key for a page-level theme, or to elements for component-level theming. You can also use.light
or.dark
to force light or dark mode at the page or component level.
Color & opacity utilities
.color
does nothing on it’s own; use with modifiers below.--{text/bg/border/accent}
sets a remap target.--use-{text/bg/border/accent}
remaps to a different part’s color.--{primary/secondary/neutral}-{50-900}
remaps to a specific color.set-{text/bg}
sets color.text-{10-90}
adjusts text opacity.bg-{10-90}
adjusts background opacity.border-{10-90}
adjusts border opacity
Animation
Grease includes a simple, tiny, composable animation system:
- Define a CSS animation and a utility class that invokes it.
- Use the class name as the value for the
data-aos
attribute on the element you want to animate. - Grease will animate in the element when it enters the viewport. If multiple elements appear at once, Grease builds in a brief stagger (taking into consideration any existing delays).
By adding animation to elements and sub-elements, you can quickly scaffold out surprisingly complex animations from a handful of simple primitives. For instances where it’s inconvenient to add an attribute directly to an element, use data-aos-children
to apply the animation class to all direct children of the element.