Primitive is a minimalist CSS framework built with Sass that provides helpful, browser-consistent styling for buttons, forms, tables, lists, and typography, and a responsive grid system for templating.

Star Follow @taniarascia


Download and Installation

There are two options for using Primitive.

CSS (easy)

Download the stylesheet, link to it in the <head>, and place all your custom CSS in a separate stylesheet.

Sass (recommended)

Download the source and set up a Sass workflow with Gulp.

HTML Starting Point

Begin with a basic HTML5 template that does the following:

<!doctype html>
<html lang="en">

  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">


  <link rel="stylesheet" href="css/main.min.css">
  <link rel="icon" href="images/favicon.png">


  <script src=""></script>
  <script src="js/script.js"></script>


View all HTML5 with Primitive CSS applied to them.

HTML5 Elements Test


There are three container sizes for content that are centered with left and right padding. Content without a container will span the width of the viewport.

<div class="small-container">Small</div>
<div class="medium-container">Medium</div>
<div class="container">Large</div>
Small Medium Large
800px 1000px 1200px


The grid is based on percents - small-50 or large-50 is 50% of the screen width. The two breakpoints are defined by small or large classes. Resize the screen to see the different breakpoints.

<div class="row">
  <div class="small-50">50%</div>
  <div class="small-50">50%</div>
<div class="row">
  <div class="large-50">50%</div>
  <div class="large-50">50%</div>

No Collapse

If the grid shouldn't collapse to 100% width on small screens, use a column- class.

<div class="row">
  <div class="column-90">90%</div>
  <div class="column-10">10%</div>

Repeating Grid

The grid will wrap and repeat onto the next line if you continue.

<div class="row">
	<div class="small-33">33%</div>
	<div class="small-33">33%</div>
   <!-- etc -->

Flex Grid

Create infinitely repeating cells with a flex grid.

<div class="flex-row">
	<div class="flex-column"></div>
	<div class="flex-column"></div>
<div class="flex-row">
	<div class="flex-column"></div>
	<div class="flex-column"></div>
	<div class="flex-column"></div>

Flex Breakpoints

The same breakpoints are available for the flex grid.

<div class="flex-row">
	<div class="flex-small"></div>
	<div class="flex-small"></div>
<div class="flex-row">
	<div class="flex-large"></div>
	<div class="flex-large"></div>


The font size is set to 1rem on the html element, so all font sizing will cascade from the root.

Headings all have the same line-height and margins, and only the font size is individually defined.

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5


Blockquote is set to have a left border, with the browser default padding removed. A cite will be right aligned and italicized.

	<p>Keep it secret. Keep it safe.</p>
	<cite>Gandalf the Gray</cite>

Keep it secret. Keep it safe.

Gandalf the Gray


Button elements, links with a button class, and input elements should all render exactly the same.

<input type="submit" value="Submit">
<input type="button" value="Input">
<a class="button">Link</a>

Accent Buttons

Adding an accent-button class will display a secondary color.

<button class="accent-button">Button</button>

Muted Buttons

Adding a muted-button class will create ghost/outline buttons.

<button class="muted-button">Button</button>

Round Buttons

Adding a round-button class will create rounded buttons.

<button class="round-button">Button</button>

Square Buttons

Adding a square-button class will create square buttons.

<button class="square-button">Button</button>

Full Width Buttons

Adding a full-button class will create full-width, block level buttons. Button styles can be combined.

<button class="full-button">Button</button>


Default forms will have full-width, block level labels, inputs, selects, and textareas.

  <label for="name">Name</label>
  <input type="text" id="name" placeholder="First Name">
  <label for="choose">Select</label>
  <select id="choose">
    <option disabled selected>Please select</option>
    <option value="option-1">Option 1</option>
    <option value="option-2">Option 2</option>
  <label for="comments">Additional Comments</label>
  <textarea id="comments"></textarea>
    <input type="checkbox">
    Remember me
  <input type="submit" value="Submit">

Split Forms

Add a split-form class to enable left-aligned labels. Combine with rows for versitile layout possibilities.

<form class="split-form">
  <div class="row">
    <div class="small-10">
      <label for="name">Name</label>
    <div class="small-40">
      <input type="text" id="name" placeholder="First Name">
    <div class="small-10">
      <label for="email">Email</label>
    <div class="small-40">
      <input type="email" id="email" placeholder="Email Address">
  <div class="row">
    <div class="small-10">
      <label for="url">URL</label>
    <div class="small-90">
      <input type="url" id="url" placeholder="Website URL">
  <div class="row">
    <div class="push-small-10 small-10">
      <input type="submit" value="Submit">

Form Validation

An input field with a has-error class.

<input type="text" id="name" placeholder="Name" class="has-error">


Tables are set to a width of 100%, with a bottom border and bold headings.

      <th>Head 1</th>
      <th>Head 2</th>
      <th>Head 3</th>
      <th>Footer 1</th>
      <th>Footer 2</th>
      <th>Footer 3</th>
      <td>Description 1</td>
      <td>Description 2</td>
      <td>Description 3</td>
      <td>Description 1</td>
      <td>Description 2</td>
      <td>Description 3</td>
      <td>Description 1</td>
      <td>Description 2</td>
      <td>Description 3</td>
Head 1 Head 2 Head 3
Footer 1 Footer 2 Footer 3
Description 1 Description 2 Description 3
Description 1 Description 2 Description 3
Description 1 Description 2 Description 3

Striped Tables

Add a striped class for alternating row background colors.

<table class="striped-table">
  <!-- etc -->
Head 1 Head 2 Head 3
Description 1 Description 2 Description 3
Description 1 Description 2 Description 3
Description 1 Description 2 Description 3

Contained Tables

Wrap the table in a contain-table class to prevent tables with a lot of content from stretching on small screens.

<div class="contain-table">
  <!-- etc -->
Head 1 Head 2 Head 3 Description 2 Description 3
Description 1 Description 2 Description 3
Footer 1 Footer 2 Footer 3


Regular ordered and unordered lists have no special styling applied to them.

	<li>List item one
			<li>Nested list item</li>
	<li>List item two</li>
	<li>List item three</li>
  • List item one
    • Nested list item
  • List item two
  • List item three
  1. List item one
    1. Nested list item
  2. List item two
  3. List item three

Definition Lists

Definition titles are bold, and margins have been placed after each description.

	<dt>Definition Title One</dt>
	<dd>First definition description</dd>
	<dt>Definition Title Two</dt>
	<dd>First definition description</dd>
Definition Title One
First definition description
Definition Title Two
First definition description


Style has been added for inline <code> tags, and <kbd> is a keyboard input.

Place blocks of preformatted code in a <pre><code>.

class Voila {
  // Voila
  static const string VOILA = "Voila";


Helper classes are helpful for templating.

Vertical Center

Vertically center an element with the vertical-center class. (Uses Flexbox.)

<div class="vertical-center">
	<div>Vertically centered</div>
Vertically centered

Text Alignment

Use text-left, text-right, and text-center to align content.

<p class="text-left">Left</p>
<p class="text-center">Center</p>
<p class="text-right">Right</p>




Screen Reader Text

Accessibility is important - if you have a label that should be hidden but accessible, or use an icon as a link, or want to skip navigation, use the screen-reader-text class to hide content visually.

<a class="screen-reader-text" href="#content">Skip Navigation</a>

Responsive Images

Add a responsive-image class for responsive images.

<img src="#" class="responsive-image" alt="Responsive Image">
Example of responsive-image CSS class

More Helper Classes

Class What it does
.float-left float: left
.float-right float: right
.block display: block
.inline-block display: inline-block
.inline display: inline
.show display: block !important
.hide display: none !important
.padding-top padding-top: 2rem
.no-padding-top padding-top: 0
.padding-bottom padding-bottom: 2rem
.no-padding-bottom padding-bottom: 0
.margin-top margin-top: 2rem
.no-margin-top margin-top: 0
.margin-bottom margin-bottom: 2rem
.no-margin-bottom margin-bottom: 0
.content-section padding: 60px 0 (30px on mobile)


This project is built with Sass (SCSS) and Gulp. If you're not familiar with these technologies, please read the tutorials below.

Sass is used to extend your CSS, allowing you to use useful concepts like variables and nesting, as well as compartmentalizing and organizing the code. Gulp is used to watch for changes and process those Sass files into regular CSS files, as well as minifying and adding prefixes for cross-browser compatibilty.

If you already have Node installed, you can just clone the project...

git clone

install the dev dependencies in the root of the project...

npm install

and run.


The default gulp command will run a watch to compile, minify and prefix your files. If that doesn't make sense, read the aformentioned article and you'll be up to speed in no time.

Directory Structure

The project contains the source and destination folders, as well as a few necessary project files.

  • dist - the distribution folder that contains the final CSS, JavaScript, and HTML output.
  • src - the source folder that contains all the scss files and folders.
  • .gitignore - ignore node_modules and .sass-cache files.
  • gulpfile.js - the Gulp project that will compile, minify and prefix the scss files.
  • package.json - npm package folder to initialize node_modules
├── css/
│   ├── main.min.css
│   └──
├── js/
│   └── script.js
├── images/
│   └── favicon.png
├── index.html
└── scss/
    ├── base/
    │   ├── _mixins.scss
    │   ├── _normalize.scss
    │   ├── _reset.scss
    │   └── _variables.scss
    └── components/
        ├── _scaffolding.scss
        ├── _grid.scss
        ├── _helpers.scss
        ├── _buttons.scss
        ├── _forms.scss
        ├── _tables.scss
        ├── _navigation.scss
        └── _layout.scss

Main Sass File

In the main Sass file, main.scss, we'll pull in the configuration (variables and mixins) first, followed by resets, then all the components.

// Configuration
@import "base/variables";
@import "base/mixins";

// Reset
@import "base/normalize";
@import "base/reset";

// Components
@import "components/scaffolding";
@import "components/grid";
@import "components/helpers"; 
@import "components/buttons";
@import "components/forms";
@import "components/tables";
@import "components/navigation";
@import "components/layout";

Most of the components should be self-explanatory. Scaffolding is the main styling of typography, links, headings, etc. Navigation and layout are empty files, but I kept them in because they're generally necessary. Add more files as necessary (3rd party, fonts, etc).


Much of the design can be configured just by changing some settings in _variables.scss. This file will define your colors, typography, sizes, breakpoints, buttons, borders, and more. Define all your variables here to keep your project organized.

/* Variables
 * ===============
 * All variables and most of the configuration is defined on this page. */

/* Containers */

$x-small: 600px;
$small: 800px;
$medium: 1000px;
$large: 1200px;

/* Breakpoints */

$mobile: $x-small;
$desktop: $medium;

/* Colors */

$background: white;
$primary-color: #1E6BD6;
$secondary-color: #21B983; 
$accent-color: #cdcdcd;
$alternate-background: #fafafa;
$alternate-color: #404040;
$link-color: $primary-color;
$link-hover-color: darken($link-color, 15%);
$highlight: #ffeea8;
$error: #D33C40;
$bq-border: 16px solid #f0f0f0;

/* Typography */

// Body font
$font-size: 1rem;
$body-font-size: 1rem;
$font-style: normal;
$font-variant: normal;
$font-weight: normal;
$font-color: #404040;
$font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Arial, sans-serif;
$line-height: 1.6;

// Headings
$heading-font-color: #404040;
$heading-font-weight: 600;
$heading-font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Arial, sans-serif;
$heading-line-height: 1.2;

// Mobile heading font size
$h1-mobile: 1.75rem;
$h2-mobile: 1.5rem;
$h3-mobile: 1.25rem;
$h4-mobile: 1.1rem;
$h5-mobile: 1rem;

// Heading font size
$h1: 2.25rem;
$h2: 2rem;
$h3: 1.75rem;
$h4: 1.5rem;
$h5: 1.25rem;

/* Padding */

$padding: 1rem;
$margins: 1.5rem;
$content-padding: 60px 0;
$content-padding-mobile: 30px 0;

/* Borders */

$border-width: 1px;
$border-style: solid;
$border-color: #dedede;
$border-radius: 4px;
$borders: $border-width $border-style $border-color;

/* Buttons */

$button-background: $primary-color;
$button-background-hover: darken($button-background, 10%);
$button-color: #ffffff;
$button-font-weight: 600;
$button-font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Arial, sans-serif;
$button-font-size: 1rem;
$button-border-width: 1px;
$button-border-style: solid;
$button-border-color: $button-background;
$button-border-radius: $border-radius;
$button-text-transform: none;

// Accent buttons
$accent-button-background: $secondary-color;
$accent-button-color: #ffffff;
$accent-button-color-hover: #ffffff;

// Muted Buttons
$muted-border: 1px solid $accent-color;
$muted-border-hover: 1px solid darken($accent-color, 30%);
$muted-background: transparent;
$muted-background-hover: transparent;
$muted-color: darken($accent-color, 50%);
$muted-color-hover: darken($accent-color, 50%);

// Round Buttons
$round-buttons: 40px;

/* Forms */

$forms: ('[type=color], [type=date], [type=datetime], [type=datetime-local], [type=email], [type=month], [type=number], [type=password], [type=search], [type=tel], [type=text], [type=url], [type=week], [type=time], select, textarea');
$buttons: ('.button, a.button, button, [type=submit], [type=reset], [type=button]');
$input-background: transparent;
$placeholder: darken($accent-color, 20%);
$form-border: 1px solid #cdcdcd;
$form-border-hover: 1px solid darken(#cdcdcd, 10%);
$form-border-focus: 1px solid $link-color;

/* Tables */

$stripes: #f8f8f8;
$caption: #ababab;

/* Code */

$code-color: $font-color;
$code-size: 14px;
$code-family: Menlo, monospace;
$code-background: transparent;
$code-borders: $borders;

Changing these default configurations will go a long way in setting the tone of the rest of your site. View the example below to toggle the style of common HTML5 elements between Primitive, Bootstrap, Foundation, Material, and Skeleton frameworks.

HTML5 Elements Test

From here, the design is up to you. Happy coding!