Skip to content

garrettw/vitals

Repository files navigation

Vitals

npm version npm package size npm total downloads npm weekly downloads npm monthly downloads

Overview

Vitals makes a great addition to your Sass toolkit. It exists solely to fill gaps that other projects do not.

It consists of a few simple Sass tools for building modern, flexible websites: an improved normalize (including a pure CSS version), shorthand systems for flexbox and grid, and a fluid sizing function.

Browser support:

  • Edge 88+
  • Firefox 78+
  • Chrome 88+
  • Safari/iOS 14+
  • Opera 74+
  • Chrome for Android
  • Firefox for Android

The goal is to be compatible with the most common browsers and versions currently in use.

I highly recommend combining Vitals with the excellent MQ media query library to create responsive grids and font sizes. But Breakpoint is ok too.

Installation / Usage

Install from npm:

npm install vitals-scss

Or with Yarn:

yarn add vitals-scss

If you install Vitals from npm or Yarn, use the package directly from node_modules with Sass module syntax:

@use "vitals-scss";

This works in modern JS build workflows such as Vite, Webpack/Sass loader, Next.js, Astro, Eleventy, and any Dart Sass-based pipeline that resolves node_modules.

If you want only the core Sass utilities without the normalize layer:

@use "vitals-scss/scss/flex-grid";
@use "vitals-scss/scss/fluid";

If you instead copy the scss directory into your project and use it locally, import it from the local path:

@use "vitals";

Or you can load just the core Sass components without the normalize layer:

@use "flex-grid";
@use "fluid";

Vitals Flex+Grid

Flex+Grid is little more than some rewritten vocabulary that makes more sense to me. It's just a little syntactic sugar for those who already use flexbox and grid capably.

API Overview

Flex container mixins:

// This is the most basic one that the others inherit from.
// Its only advantage over "display: flex;" is that it adds "align-items: stretch"
// for browser normalization.
@include flex;

// Each of these also work stand-alone.
@include flex-row;
@include flex-row-reverse;
@include flex-col;
@include flex-col-reverse;

Flex item mixin:

// This is just a shortcut for flex: 0 1 auto; for browser normalization purposes.
@include flex-item;

Flex alignment modifiers:

// On a flex row, this aligns horizontally.
// Accepts all valid CSS values for justify-content, as well as
// "start", "end", and "justify" if you like those better.
@include flex-align($val);

// On a flex row, this aligns vertically. I call them "xalign" because "x" indicates
// alignment on the cross axis, thus making these suitably named for columns as well.
// Accepts all valid CSS values for align-items, as well as "start" and "end".
@include flex-xalign($val);

// On a flex row child, this changes vertical alignment per item.
// Accepts all valid CSS values for align-self, as well as "start" and "end".
@include item-xalign($val);

Flex item sizing function:

// Returns a measurement that accounts for gutter width.
// $fraction is literally a fraction size, like 1/4, that the item should occupy
// in the desired dimension.
// Default $gutter value is $item-gutter, which defaults to 0.625rem (10px).
item-size($fraction, $gutter)

Grid mixins:

@mixin grid-rows($val) { grid-template-rows: $val;    }
@mixin grid-cols($val) { grid-template-columns: $val; }

@mixin grid-align($val)  { justify-self: $val; }
@mixin grid-xalign($val) { align-self: $val;   }

Flex row Example

To start off, set up a container:

.row {
  @include flex-row;
}

Now that you have a row container, let's make some flex items that are 25% wide with the default 10px gutter.

.this-item-here {
  @include flex-item;
  width: item-size(1/4);
  margin: 0 0 $item-gutter $item-gutter;
}

What happened here? The item-size() function spits out a measurement that accounts for gutter width. For a standard push-left grid a la Bourbon Neat 2.0, you'll at least want to set margin-left to the gutter size. I also set margin-bottom so that vertical spacing is the same. $item-gutter is an included variable that is used by item-size() as the default gutter size if one isn't specified. It is set to 0.625rem, which is usually 10px.

If you don't want a gutter, that's fine too.

.this-other-item {
  @include flex-item;
  width: item-size(1/3, 0); // equivalent to "width: percentage(1/3);"
}

How to make cells responsive

To use Vitals Grid in a responsive manner, just redefine your item-size()s in different media queries. This works because any item that exceeds 100% of a container's main axis will be wrapped automatically.

Here's a primitive example using a sidebar class and the MQ+ media query library I recommended above.

.sidebar {
  @include flex-item;
  width: item-size(1); // full width by default, for mobile-first design
  margin-left: $item-gutter;

  @include mq(48em) {
    width: item-size(1/4); // 25% wide at desktop resolution
  }
}

It's that simple!

Vitals Fluid

Fluid is a function that will output a flexible dimension, which scales along with the viewport width, for use with any property.

If you use this OUTSIDE of a media query, the scaling will not stop at a minimum or maximum.

This function takes a min and max size, and a min and max viewport.

fluid($sm, $lg, $narrow, $wide)

$sm is the size to be used when the viewport is at $narrow width, and $lg is the size at $wide width.

This function outputs a calc() string that scales the size linearly from $sm to $lg for the viewport range of $narrow to $wide.

Here's an example using Modular Scale and MQ+.

body {
  // the smallest font size, for mobile first
  font-size: ms(0);

  @include mq(45em, 60em) {
    // the intermediate size, which scales smoothly
    font-size: fluid($sm: ms(0), $lg: ms(1), $narrow: 45em, $wide: 60em);
  }

  @include mq(60em) {
    // the largest size
    font-size: ms(1);
  }
}

Is that it?

Yes, for now. I think there are some existing projects that adequately address their goals, such as:

I'll add to this list as I find other useful Sass projects.

Tips

Modular Scale

If you use the Modular Scale library, I've found that the following configuration gives some nice round increments at multiples of 3.

$modularscale: (
  base: 1rem,
  ratio: 1.25992
);

Using this, ms(0) = 1rem, ms(3) = 2rem, ms(6) = 4rem, ms(9) = 8rem, and so on.

I've included this in _defaults.scss which you must import explicitly if you want to use it, as it is optional.

Development notes

To build the local source:

npm install
npm run build

For development watching source changes:

npm run watch

This project currently uses the Sass CLI to compile source files and PostCSS + Autoprefixer to apply browser-specific prefixes.

  • npm run watch now runs both Sass watch and Autoprefixer watch together.
  • npm run compile compiles scss/_vitals.scss into css/vitals.css and then applies Autoprefixer.
  • npm run minify compiles scss/_vitals.scss into css/vitals.min.css and then applies Autoprefixer.
  • browserslist in package.json determines the final vendor prefixes added to built CSS.

The build produces css/vitals.css and css/vitals.min.css from scss/_vitals.scss.

About

A minimalistic bundle of a few SCSS/Sass tools for building modern, flexible websites: a better normalize, shorthand stuff for flexbox and grid, and a fluid sizing function.

Topics

Resources

License

Stars

10 stars

Watchers

4 watching

Forks

Packages

 
 
 

Contributors