Hocus-Pocus v0.3.4

Created and maintained by @_bkzl

Build Status

Hocus-Pocus is a universal and lightweight stylesheet starter kit that focuses on base html elements and typography. You can change the look of every single component, disable some features and define a range of helpers with variables.

Why not Bootstrap?

Libraries like Bootstrap or Foundation are great and have greatly changed how people think about CSS. However, in most cases within my own project work, I just don’t need all these features and UI components like progress bars or breadcrumbs. Instead, I prefer to have something more universal that I can use in any project.

Key Features

The following features are the most characteristic to Hocus-Pocus:

  • Enhanced normalize.css reset
  • Default colors set and color helpers thanks to clrs.cc
  • Widely responsive web design support with customizable breakpoints and approach
  • Flexbox grid with universal, fraction based width helpers
  • Visibility and spacing helpers (auto-generated for the each viewport breakpoint!)
  • Typography with vertical rhythm based on rem units
  • Components like lists, menus, tables, forms, buttons, boxes, media object and sticky footer

Code is open sourced on GitHub. Up to date changelog is available under the releases section.

I appreciate any comments, feedback, and information about potential issues. Have you experienced a bug or noticed a mistake in documentation? Please add a new issue. Thanks!

Quick Start

Hocus-Pocus requires Sass (version 3.3.0 or later) to proper work.

Run:


$ npm install hocus-pocus --save-dev

Then import a main file just after your settings, but before rest of stylesheets. If you want to use color variables in your variables import them first:


// Import colors (optional)
@import "node_modules/hocus-pocus/sass/colors";

// Define settings
$font-family-base: "Open Sans", sans-serif;
$grid-container: 70rem;

// Import Hocus-Pocus
@import "node_modules/hocus-pocus/hocus-pocus";

// Import your stylesheets
@import "compontents/meter";
@import "compontents/price-box";

Hocus-Pocus requires Sass (version 3.3.0 or later) to proper work.

Run:


$ bower install hocus-pocus

Then import a main file just after your settings, but before rest of stylesheets. If you want to use color variables in your variables import them first:


// Import colors (optional)
@import "bower_components/hocus-pocus/sass/colors";

// Define settings
$font-family-base: "Open Sans", sans-serif;
$grid-container: 70rem;

// Import Hocus-Pocus
@import "bower_components/hocus-pocus/hocus-pocus";

// Import your stylesheets
@import "compontents/meter";
@import "compontents/price-box";

Hocus-Pocus applies a following naming convention:


<!-- Element -->
<div class="media"></div>
<a class="btn"></a>

<!-- Element with a related sub-element -->
<div class="media">
  <img class="media-img">
  <div class="media-body"></div>
</div>

<!-- Element with modifier -->
<div class="media media-milli"></div>
<a class="btn btn-primary"></a>

<!-- Element with state -->
<a class="btn is-active"></a>
<a class="btn is-disabled"></a>

<!-- Element that requires a wrapper -->
<!-- i.e. "position: relative" and "position: absolute" pair -->
<div class="box has-close-link">
  <a class="close-link"></a>
</div>

<!-- JavaScript handler -->
<div class="alert js-alert"></div>

Defaults

The most common settings are listed below. Other defaults are listed on corresponding documentation pages or you can find them in the source code under scss/_defaults.scss.


$rwd-type: mobile-first;
$rwd-map: (compact: 320px 414px, regular: 415px);

$font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
$font-family-headings: $font-family-base;
$font-leading: 1.5;
$font-size-base: 1rem;

$grid-container: 1020px;

$color-body: $color-white;
$link-underline: true;
$btn-flat: false;

Colors

Colors available as variables (so you can override them if you wish to):

$color-white
$color-silver
$color-gray
$color-black
$color-red
$color-orange
$color-yellow
$color-lime
$color-green
$color-olive
$color-teal
$color-aqua
$color-blue
$color-navy
$color-fuchsia
$color-purple
$color-maroon

Defaults:


$color-body: $color-white;        // body background color
$color-ui: $color-silver;         // ui elements color like rules, borders, form inputs
$color-btn: $color-black;         // button color without any modifiers
$color-text: $color-black;        // base font color
$color-link: $color-blue;         // links color
$color-muted: $color-gray;        // blockquote and `.text-muted` color
$color-small: $color-text;        // small color
$color-disabled: $color-ui;       // disabled form input and buttons color
$color-brand: $color-blue;        // brand color
$color-positive: $color-green;    // positive color
$color-cautionary: $color-yellow; // cautionary color
$color-negative: $color-red;      // negative color
$color-informative: $color-blue;  // informative color
$color-map: (
  'white': $color-white,
  'silver': $color-silver,
  'gray': $color-gray,
  'black': $color-black,
  'red': $color-red,
  'orange': $color-orange,
  'yellow': $color-yellow,
  'lime': $color-lime,
  'green': $color-green,
  'olive': $color-olive,
  'teal': $color-teal,
  'aqua': $color-aqua,
  'blue': $color-blue,
  'navy': $color-navy,
  'fuchsia': $color-fuchsia,
  'purple': $color-purple,
  'maroon': $color-maroon,
  'brand': $color-brand,
  'positive': $color-positive,
  'cautionary': $color-cautionary,
  'negative': $color-negative,
  'informative': $color-informative,
  'muted': $color-muted
);                                // color helpers are generated based on this map

Color Helpers

Specify text and background color of an element.

Color helpers use !important and are generated for each color in $color-map.

Usage:


.text[-color];
.bg[-color];

/*
 * Where [-color] is one of these values:
 *   -aqua, -blue, -navy, -teal, -green, -olive, -lime, -yellow, -orange,
 *   -red, -fuchsia, -purple, -maroon, -white, -silver, -grey, -black,
 *   -informative, -positive, -negative, -brand, -muted
 */

Paragraph with a muted text

Paragraph with a brand text

Paragraph with a negative background

Paragraph with a black background and white text


<p class="text-muted">Paragraph with a muted text</p>
<p class="text-brand">Paragraph with a brand text</p>
<p class="bg-negative">Paragraph with a negative background</p>
<p class="bg-black text-white">Paragraph with a black background and white text</p>

Responsive Design

Choose approach of writing responsive design that you prefer: mobile-first or desktop-first.

Define custom breakpoints. Each of them gets a mixin and own set of helpers.

Defaults:


$rwd-type: mobile-first;  // choose between `mobile-first` and `desktop-first`
$rwd-map: (
  'compact': 320px 414px,
  'regular': 415px
);                        // helpers are based on this map

Additional helper for hidpi displays:


@include hidpi($density); // in dpi, defaults to 192 (retina displays)

Usage:


@include rwd('compact') {
  h1 {
    color: $color-red;
  }
}

@include hidpi {
  .logo {
    background-image: url([email protected]');
  }
}

<div class="compact-hidden">...</div>
<div class="hidden compact-visible">...</div>

<div class="grid">
  <div class="grid-item 1/4 compact-hidden">
    ...
  </div>

  <div class="grid-item 3/4 compact-1/1">
    <h1 class="compact-no-margin-top">
      ...
    </h1>
  </div>
</div>

Width Helpers

Width helpers work with various elements like grid items, boxes, form inputs, table cells etc.

Fractions of these numbers are available: n/1, n/2, n/3, n/4, n/5, n/6, n/8, n/9, n/10 and n/12.

Width helpers are generated for each breakpoint in $rwd-map.

Usage:

.1/1
.1/4, .2/8, .3/12
.3/4, .6/8, .9/12
.2/5, .4/10
.3/5, .6/10
.1/6, .2/12
.5/6, .10/12
.1/2, .2/4, .3/6, .4/8, .5/10, .6/12
.1/8
.3/8
.1/5.compact-1/2
.4/5.compact-1/2

Visibility Helpers

Specify visibility of an element.

Visibility helpers use !important and are generated for each breakpoint in $rwd-map.

Following classes are available: .hidden, .visible, .block, .inline-block and .inline

Usage:

Inline paragraph hidden on mobile


<p class="inline compact-hidden">Inline paragraph hidden on mobile</p>
<small class="hidden compact-block">Block small text visible on mobile</small>

Spacing Helpers

Specify spacing (margin/padding) of an element.

Spacing helpers use !important and are generated for each size in $spacing-map and each breakpoint in $rwd-map.

Defaults:


// spacing helpers and media gutter modifiers are generated based on this map
$spacing-map: (
  '1/4': $spacing-unit / 4,
  '1/3': $spacing-unit / 3,
  '1/2': $spacing-unit / 2,
  '2/1': $spacing-unit * 2,
  '3/1': $spacing-unit * 3,
  '4/1': $spacing-unit * 4
);

Usage:


.margin[-size][-type];
.padding[-size][-type];
.no-margin[-type];
.no-padding[-type];

/*
 * Where [-type] is blank (all values) or one of these values:
 *   -top, -right, -bottom, -left, -horizontal, -vertical
 *
 * Where [-size] is blank ($spacing-unit) or one of these values:
 *   -1/4, -1/3, -1/2, -2/1, -3/1, -4/1
 */
.padding-vertical
.margin.no-padding
.margin-2/1-bottom
.padding-1/2-left.padding-1/2-top.compact-no-padding-left
.compact-margin-horizontal
.compact-padding-1/2

<div class="padding-vertical">...</div>
<div class="margin no-padding">...</div>
<div class="margin-2/1-bottom">...</div>
<div class="padding-1/2-left padding-1/2-top compact-no-padding-left">...</div>
<div class="compact-margin-horizontal">...</div>
<div class="compact-padding-1/2">...</div>

Grid

Create a centered wrapper for grid elements. Usually used as a root element for a whole layout.

Defaults:


$grid-container: 1020px; // container's width

Usage:

.container

<div class="container">
  ...
</div>

Build a grid using a combination of grid items and width helpers. Grid elements can be nested. It's based on flexbox.

Defaults:


$grid-gutter: $spacing-unit; // width of grid gutter

Usage:

.grid-item.1/3
.grid-item.2/3

<div class="grid">
  <div class="grid-item 1/3">
    ...
  </div>

  <div class="grid-item 2/3">
    ...
  </div>
</div>

Grid Types

Set horizontal and/or vertical alignment:

.grid-item.1/3

<div class="grid grid-left">
  <div class="grid-item 1/3">
    ...
  </div>
</div>
.grid-item.1/3

<div class="grid grid-center">
  <div class="grid-item 1/3">
    ...
  </div>
</div>
.grid-item.1/3

<div class="grid grid-right">
  <div class="grid-item 1/3">
    ...
  </div>
</div>
.grid-item.1/2
.grid-item.1/2

<div class="grid grid-top">
  <div class="grid-item 1/2">
    ...
  </div>
  <div class="grid-item 1/2">
    ...
  </div>
</div>
.grid-item.1/2
.grid-item.1/2

<div class="grid grid-middle">
  <div class="grid-item 1/2">
    ...
  </div>
  <div class="grid-item 1/2">
    ...
  </div>
</div>
.grid-item.1/2
.grid-item.1/2

<div class="grid grid-bottom">
  <div class="grid-item 1/2">
    ...
  </div>
  <div class="grid-item 1/2">
    ...
  </div>
</div>

Create a flat grid without gutter:

.grid-item.1/2
.grid-item.1/2

<div class="grid grid-flat">
  <div class="grid-item 1/2">
    ...
  </div>
  <div class="grid-item 1/2">
    ...
  </div>
</div>

Create a grid where content of a first item is aligned to left and content of a second item is aligned to right:

.grid-item.1/2
.grid-item.1/2

<div class="grid grid-pair">
  <div class="grid-item 1/2">
    ...
  </div>
  <div class="grid-item 1/2">
    ...
  </div>
</div>

Reverse grid items order (available for each breakpoint in $rwd-map):

.grid-item.1/3
.grid-item.2/3

<div class="grid grid-reverse">
  <div class="grid-item 1/3">
    ...
  </div>
  <div class="grid-item 2/3">
    ...
  </div>
</div>
.grid-item.2/5
.grid-item.3/5

<div class="grid compact-grid-reverse">
  <div class="grid-item 2/5">
    ...
  </div>
  <div class="grid-item 3/5">
    ...
  </div>
</div>

Stack grid items (available for each breakpoint in $rwd-map):

.grid-item.1/3
.grid-item.2/3

<div class="grid grid-stack">
  <div class="grid-item 1/3">
    ...
  </div>
  <div class="grid-item 2/3">
    ...
  </div>
</div>
.grid-item.2/5.compact-1/1
.grid-item.3/5.compact-1/1

<div class="grid compact-grid-stack">
  <div class="grid-item 2/5 compact-1/1">
    ...
  </div>
  <div class="grid-item 3/5 compact-1/1">
    ...
  </div>
</div>

Combination of stack and reverse:

.grid-item.5/6
.grid-item.1/6

<div class="grid grid-reverse grid-stack">
  <div class="grid-item 5/6">
    ...
  </div>
  <div class="grid-item 1/6">
    ...
  </div>
</div>
.grid-item.1/3
.grid-item.2/3

<div class="grid compact-grid-reverse compact-grid-stack">
  <div class="grid-item 1/3">
    ...
  </div>
  <div class="grid-item 2/3">
    ...
  </div>
</div>

Float Helpers

Clearfix and float helpers.

.float-left
.float-right

<div class="clearfix">
  <div class="float-left">...</div>
  <div class="float-right">...</div>
</div>

Typography

Typography elements keep vertical rhythm and have custom reset.

Defaults:


$font-leading: 1.5;                       // base font leading
$font-size-micro: .8rem;                  // font size of `.text-micro`
$font-size-small: .9rem;                  // font size of `small` and `.text-small`
$font-size-base: 1rem;                    // base font size
$font-size-lead: 1.2rem;                  // font size of `.text-lead` element
$font-size-btn: $font-size-base;          // font size of buttons

$font-size-h1: 3rem;                      // font size of headings
$font-size-h2: 2rem;
$font-size-h3: 1.5rem;
$font-size-h4: 1.4rem;
$font-size-h5: 1.3rem;
$font-size-h6: 1.2rem;

$font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
$font-family-headings: $font-family-base;
$font-family-monospace: Consolas, 'Liberation Mono', Menlo, Courier, monospace;

$font-weight-light: 100;                  // light font weight
$font-weight-normal: 400;                 // normal/base font weight
$font-weight-bold: 700;                   // bold font weight
$font-weight-headings: $font-weight-bold; // default font weight of headings

$link-underline: true;                    // should links have underline
$link-active: false;                      // should active links look like clicked

Headings

Heading Level 1


<h1>Heading Level 1</h1>
<span class="h1">Heading Level 1</span>

Heading Level 2


<h2>Heading Level 2</h2>
<span class="h2">Heading Level 2</span>

Heading Level 3


<h3>Heading Level 3</h3>
<span class="h3">Heading Level 3</span>

Heading Level 4


<h4>Heading Level 4</h4>
<span class="h4">Heading Level 4</span>
Heading Level 5

<h5>Heading Level 5</h5>
<span class="h5">Heading Level 5</span>
Heading Level 6

<h6>Heading Level 6</h6>
<span class="h6">Heading Level 6</span>

Paragraphs

Default styles for <p>, <strong>, <em>, <sup>, <sub>, <small>, <a>, <mark>, <del>, <ins>, <s> and <u>.

Paragraph with a strong element.

Paragraph with an emphasis element.

Paragraph with a sup element.

Paragraph with a sub element.

Paragraph with a small element.

Paragraph with a link.

Paragraph with a mark element.

Paragraph with a deleted text and an inserted text elements.

Paragraph with a strikethrough element.

Paragraph with an underline element.


<p>Paragraph with a <strong>strong</strong> element.</p>
<p>Paragraph with an <em>emphasis</em> element.</p>
<p>Paragraph with a <sup>sup</sup> element.</p>
<p>Paragraph with a <sub>sub</sub> element.</p>
<p>Paragraph with a <small>small</small> element.</p>
<p>Paragraph with a <a href="#-">link</a>.</p>
<p>Paragraph with a <mark>mark</mark> element.</p>
<p>Paragraph with a <del>deleted text</del> and an <ins>inserted text</ins> elements.</p>
<p>Paragraph with a <s>strikethrough</s> element.</p>
<p>Paragraph with an <u>underline</u> element.</p>

Blockquote

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida.


<blockquote>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna.
    Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida.
  </p>
</blockquote>

Code

.hocus-pocus { display: block; }

<code>
  .hocus-pocus {
    display: block;
  }
</code>

Rule



<hr>

Text Helpers

Micro text

Small text

Normal text

Lead text


<p class="text-micro">Micro text</p>
<p class="text-small">Small text</p>
<p>Normal text</p>
<p class="text-lead">Lead text</p>

Mono text


<p class="text-mono">Mono text</p>

Light weight text

Normal weight text

Bold weight text


<p class="text-light">Light weight text</p>
<p class="text-normal">Normal weight text</p>
<p class="text-bold">Bold weight text</p>

Lowercased text

Uppercased text

Capitalized text


<p class="text-lowercase">Lowercased text</p>
<p class="text-uppercase">Uppercased text</p>
<p class="text-capitalize">Capitalized text</p>

Left aligned text

Center aligned text

Right aligned text


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

Lists

Defaults:


$list-menu-color: $color-white;      // list menu color
$list-menu-background: $color-link;  // list menu background color

Usage:

  1. List item 1
  2. List item 2

<ol>
  <li>List item 1</li>
  <li>List item 2</li>
</ol>
  • List item 1
  • List item 2
    • List item A
    • List item B

<ul>
  <li>List item 1</li>
  <li>
    List item 2
    <ul>
      <li>List item A</li>
      <li>List item B</li>
    </ul>
  </li>
</ul>
  • List item 1
  • List item 2
  • List item 3

<ul class="list-reset">
  ...
</ul>
  • List item 1
  • List item 2
  • List item 3

<ul class="list-inline">
  ...
</ul>
  • List item 1
  • List item 2
  • List item 3

<ul class="list-divided">
  ...
</ul>

<ul class="list-menu">
  ...
</ul>
Definition list title
Definition list description

<dl>
  <dt>Definition list title</dt>
  <dd>Definition list description</dd>
</dl>

Images

Images are vertically aligned to the middle of container and have box-sizing set to content-box.

Replace any element that contains text with an image:


@include img-replace($path, $width, $height);

Usage:


.logo {
  @include img-replace('path/to/img.svg', 100px, 40px);
}

Image Helpers

example

<img src="img.png" alt="placeholder" class="img-rwd">
example

<img src="img.png" alt="placeholder" class="img-rounded">
example

<img src="img.png" alt="placeholder" class="img-circle">

Tables

Defaults:


$table-zebra-background: rgba($color-ui, .5);     // zebra table highlight color
$table-hover-background: $table-zebra-background; // hover table highlight color

Usage:

Header 1 Header 2 Header 3
Cell A Cell B Cell C
Cell D Cell E Cell F
Cell G Cell H Cell I

<table>
  <colgroup>
    <col class="1/4">
    <col class="1/2">
    <col class="1/4">
  </colgroup>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell A</td>
      <td>Cell B</td>
      <td>Cell C</td>
    </tr>
    <tr>
      <td>Cell D</td>
      <td>Cell E</td>
      <td>Cell F</td>
    </tr>
    <tr>
      <td>Cell G</td>
      <td>Cell H</td>
      <td>Cell I</td>
    </tr>
  </tbody>
</table>
Header 1 Header 2 Header 3
Cell A Cell B Cell C
Cell D Cell E Cell F
Cell G Cell H Cell I

<table class="table-bordered">
  ...
</table>
Header 1 Header 2 Header 3
Cell A Cell B Cell C
Cell D Cell E Cell F
Cell G Cell H Cell I

<table class="table-bordered table-zebra">
  ...
</table>
Header 1 Header 2 Header 3
Cell A Cell B Cell C
Cell D Cell E Cell F
Cell G Cell H Cell I

<table class="table-bordered table-hover">
  ...
</table>

Forms

Usage:


<form class="form-inline">
  <input type="email" placeholder="E-mail">
  <input type="password" placeholder="Password">

  <button type="submit">Submit</button>
</form>

<form class="form-stacked">
  <label for="name">Name</label>
  <input id="name">

  <label for="email">E-mail</label>
  <input type="email" id="email">

  <label for="password">Password</label>
  <input type="password" id="password">

  <label for="search">Search</label>
  <input type="search" id="search">

  <label for="disabled">Disabled</label>
  <input type="text" id="disabled" disabled>

  <label for="readonly">Read-only</label>
  <input type="text" id="readonly" readonly>

  <label>
    <input type="checkbox">Remember me
  </label>

  <label for="gender">Gender</label>
  <select id="gender">
    <option selected></option>
    <option value="female">Female</option>
    <option value="male">Male</option>
  </select>

  <label for="comment">Comment</label>
  <textarea id="comment"></textarea>

  <button type="submit">Submit</button>
</form>

<form class="form-horizontal">
  <div class="form-item">
    <label for="email">E-mail</label>
    <input type="email" id="email">
  </div>

  <div class="form-item">
    <label for="password">Password</label>
    <input type="password" id="password">
  </div>

  <div class="form-group">
    <label>
      <input type="checkbox">Remember me
    </label>

    <button type="submit">Submit</button>
  </div>
</form>

Buttons

Defaults:


$btn-flat: false; // disable drop shadow

Define own button types:


@include btn($name, $color, $color-text: $color-white)

Usage:


@include btn('primary', #00F)

Button Types

Link as a button

<button type="submit">Form button</button>

<a href="#" class="btn">Link as a button</a>
Disabled link as a button

<button disabled>Disabled button</button>

<a href="#" class="btn btn-disabled">Disabled link as a button</a>

<a href="#" class="btn btn-outline">Outline button</a>

<a href="#" class="btn btn-brand btn-outline">Outline brand button</a>

<a href="#" class="btn btn-flat">Flat button</a>

<a href="#" class="btn btn-shadow">Shadowed button</a>

<a href="#" class="btn btn-block">Block button</a>

<a href="#" class="btn btn-brand">Brand button</a>

<a href="#" class="btn btn-positive">Positive button</a>

<a href="#" class="btn btn-negative">Negative button</a>

Boxes

Create an element that is out of a rest of content. Useful for flashes, islands, sidebar boxes etc. The last element inside it will have removed a bottom margin.

Define own box types:


@include box($name, $color, $contrast: 25%)

Usage:


@include box('alert', $color-red)

Box Types

Element inside a box


<div class="box">
  ...
</div>

Element inside a box


<div class="box bg-silver">
  ...
</div>

Informative box


<div class="box box-informative">
  <p>Informative box</p>
</div>

Positive box


<div class="box box-positive">
  <p>Positive box</p>
</div>

Cautionary box


<div class="box box-cautionary">
  <p>Cautionary box</p>
</div>

Negative box


<div class="box box-negative">
  <p>Negative box</p>
</div>

Media

Media object works with any html element.

Gutter size modifiers are generated for each size in $spacing-map.

Usage:

Example Text


<div class="media">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-middle">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-bottom">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-1/2">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-2/1">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-flat">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-reverse">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Example Text


<div class="media media-middle media-3/1 media-reverse">
  <img src="...">
  <div class="media-body">
    ...
  </div>
</div>

Pin footer to the bottom of a viewport regardless of the content.

Usage:


<body class="sticky-footer">
  <div> <!-- Content wrapper -->
    ...
  </div>
  <footer>...</footer>
</body>