#talk-purple3 Design.herokai.com

Introduction

Purple3 is a CSS framework for all of Heroku's digital properties. Purple provides guidelines for the aesthetic, function, and form of user interfaces to provide a consistent experience for our customers. This is a living document and is under constant iteration.

Usage

Purple3 can be included via our CDN. Place the following in the <head> of your application:

<link rel="stylesheet" href="https://www.herokucdn.com/purple3/latest/purple3.min.css">

This site contains overview documentation for the most prominent features of Purple3. For complete documentation, please see the list of modules on Github.

This framework should be used in conjunction with the Purple UI kit (Sketch file).

Upgrading from Purple 2.X

There is no direct upgrade path from previous versions of Purple. Purple3 is a new framework with a new philosophy. In order to help with migration Purple3 can be run alongside Purple 2.X, this is the case with the Heroku Dashboard today.

Developing locally

Please see instructions on Github for developing locally and contributions.

Principles

Purple 3 is built upon a functional CSS system called Tachyons. You may want to keep a link to the Tachyons documentation pages, probably either: Table of Properties or Table of Styles.

The idea of functional CSS is that it exposes a vast amount of atomic classes which do one thing and one thing only. The combination of these classes allows us to build and maintain complex interfaces amid a constantly evolving technological landscape.

This is in stark contrast to CSS frameworks like Bootstrap (on which Purple 2 is based) which impart a lot of presumptions about how interfaces will behave into their classes.

When using functional CSS, instead of writing CSS within stylesheets you simply add classes to elements representing the styling you want. Let’s imagine the following example;

Alasdair Monk
Product designer at Heroku

Previously, we might create an avatar-card.css file for this new element, and write a bunch of CSS to style this element as well as some HTML to render.

However with Purple 3 there is no need to write any CSS whatsoever. We can markup the entire UI in HTML like so;

<div class="bg-white shadow-outer-1 br2 flex flex-column items-center pv3">
  <img class="br-100 w3 h3" src="images/almonk.png" alt="">
  <div class="f3 mt2 mb1">Alasdair Monk</div>
  <div class="f4 gray">Product designer at Heroku</div>
  <div class="flex mt2">
    <a href="" class="link purple f4 ph2 pv1 ba b--light-purple br1 mr2">Email</a>
    <a href="" class="link purple f4 ph2 pv1 ba b--light-purple br1">Twitter</a>
  </div>
</div>

All of the class names used above generally correspond to a single CSS property. For e,g, .flex corresponds to { display: flex}, .b--light-purple would be { border-color: var(--light-purple)}

Helper classes

Of course, there are times when we don’t wish to apply a handful of classes to an HTML element just to create a common and uniform component. For this case, Purple 3 exposes a set of helper classes which wrap their underlying atomic classes for convenience.

For example, you can create a primary button with the .hk-button—primary class, which is merely a wrapper for the classes .tc .link .br1 .f5 .ph3 .fw6 .b--none .nowrap .hk-focus-ring .cursor-hand .bg-gradient-primary .white phew!.

Buttons, tabs, inputs and other basic HMTL elements are perfect contenders for helper classes because they don’t make many assumptions about how they are used in context. The beauty of the system is, if you want to create a button not supported by helper classes like a blue button or a large button you can take the underlying classes and build up the element in anyway you see fit.

Our helper classes are outlined in detail in the Helpers section.

When to write CSS

Of course, using Purple 3 & functional CSS doesn’t mean you’ll never have to write CSS again. Writing CSS should be done when you need very custom styling for an interface.

Colors

Aa.purple
Aa.light-purple
Aa.lightest-purple
Aa.blue
Aa.light-blue
Aa.lightest-blue
Aa.green
Aa.light-green
Aa.lightest-green
Aa.orange
Aa.light-orange
Aa.lightest-orange
Aa.red
Aa.light-red
Aa.lightest-red
Aa.near-black
Aa.dark-gray
Aa.gray
Aa.light-gray
Aa.silver
Aa.light-silver
Aa.lightest-silver
Aa.near-white

Spacing

Spacing is formed using the syntax;

Class

.

Pick one

p Padding
m Margin

Pick one

l Left
r Right
b Bottom
t Top
v Vertical
h Horizontal

Pick one

0 0px
1 4px
2 10px
3 14px
4 20px
5 30px
6 40px
7 80px

The syntax above is combined to create a system for padding and margins. For example; .pt2 would add padding to the top of the element to the value of 10px and .mh0 would make the horizontal margin zero.

Sizes

.h1 = 16px .w1 = 16px
.h2 = 24px .w2 = 24px
.h3 = 32px .w3 = 32px
.h4 = 60px .w4 = 60px
.h5 = 100px .w5 = 100px

Shadows

.shadow-outer-1
.shadow-outer-2
.shadow-outer-3
.shadow-inner-1
.shadow-inner-2

Gradients

.bg-gradient-primary
.bg-gradient-secondary
.bg-gradient-red
.bg-gradient-orange
.bg-gradient-green
.bg-gradient-blue
.bg-gradient-silver

Opacity

.o-100
.o-90
.o-80
.o-70
.o-60
.o-50
.o-40
.o-30
.o-20
.o-10
.o-0

Border radius

.br1
.br2
.br3
.br4

.br-pill
.br--bottom
.br--top

.br--left
.br--right

Border positioning

.ba = border on all sides
.bt = border top
.br = border right
.bb = border bottom
.bl = border left
.bn = border none

Alerts & warnings

Errors

Standard

Error message
Some addiitonal text to explain what went wrong.
Error message
Some addiitonal text to explain what went wrong.

Banner

Error message straight to the point
Error message
Some addiitonal text to explain what went wrong.

Warnings

Standard

Warning message
Some additional text to explain what went wrong.

Banner

Warning message straight to the point

Info

Standard

Informational message
Some additional text to explain what's up.

Banner

Info message straight to the point

Generic

Standard

Generic message
Some additional text to explain what's up.

Wells

Wells are typically used to display empty states or to otherwise indicate that some content is missing or incomplete.

Standard

Your content will appear here

Once you’ve performed the action whatever is meant to be shown here will be shown here

On tinted background

Your content will appear here

Once you’ve performed the action whatever is meant to be shown here will be shown here

Cards

Cards are used to logically group functionality and information.

dashboard-staging

Lists

Standard

Matthew Ginnard
admin
Kathy Simpson
admin
Roberta Carraro
admin

Read only list

Domain name
DNS target
heroku.com
test.herokuapp.com
test.heroku.com
test.herokuapp.com
lorem.heroku.com
test.herokuapp.com

Editable list

Key
Value
test_key
test_value
test_key
test_value

Fills

Use fill helpers to quickly style SVG images. Fill helpers can also be used in conjunction with the malibu icon system.

All colors can be used to fill an SVG.

.fill-red
.fill-orange
.fill-gold
.fill-green
.fill-blue
.fill-purple

Buttons

Buttons drive the interactive experience of any UI. In Purple 3 they should always be represented as button elements.

Standard

Primary button

To call attention to primary actions

button.hk-button--primary
Secondary button

For secondary or less used actions

button.hk-button--secondary
Tertiary button

For infrequently used actions

button.hk-button--tertiary
Danger button

For destructive actions

button.hk-button--danger
Warning button

For potentially problematic situations

button.hk-button--warning
Info button

For informational situations

button.hk-button--info

Small

Small Primary button

To call attention to primary actions

button.hk-button-sm--primary
Small Secondary button

For secondary or less used actions

button.hk-button-sm--secondary
Small Tertiary button

For infrequently used actions

button.hk-button-sm--tertiary
Small Danger button

For destructive actions

button.hk-button-sm--danger
Small Warning button

For potentially problematic situations

button.hk-button-sm--warning
Small Info button

For informational situations

button.hk-button-sm--info

Anchor

Using an anchor

Combine the helper class with additional markup

a.hk-button--primary.flex.items-center
Create app
<a href="#" class="hk-button--primary flex items-center">
  <span>Create app</span>
</a>

Group

Standard

For actions which are closely related

<div class="hk-button-group">
  <button type="button" class="hk-button--secondary">Left</button>
  <button type="button" class="hk-button--secondary">Middle</button>
  <button type="button" class="hk-button--secondary">Right</button>
</div>
Small size

For actions which are closely related

<div class="hk-button-group">
  <button type="button" class="hk-button-sm--secondary">Left</button>
  <button type="button" class="hk-button-sm--secondary">Middle</button>
  <button type="button" class="hk-button-sm--secondary">Right</button>
</div>
With dropdown

For actions which are closely related

<div class="hk-button-group">
  <button type="button" class="hk-button--secondary">Left</button>
  <button type="button" class="hk-button--secondary">
    Right
    <svg class="fill-purple h1 w1 ml1 v-mid nudge-up--1">
      <use xlink:href="#caret-16" />
    </svg>
  </button>
</div>

Other states

Disabled button

For actions that are temporarily unavailable

button.hk-button--disabled-primary
Async button

For performing asynchronous actions (such as saving a form)

button.hk-button--async Requires malibu

Inputs

Standard input.hk-input
Read-only input.hk-input--read-only
Disabled input.hk-input--disabled
Invalid input.hk-input .b--red .hk-focus-ring--red
Valid input.hk-input .b--green .hk-focus-ring--green
Search input.hk-search-input
Textarea textarea.hk-input

Selects

Standard select.hk-select
Disabled select.hk-select--disabled

Badges

Standard .hk-badge
$7.00/mo
Info .hk-badge .bg-blue
New!
Warning .hk-badge .bg-orange
Beta

Spinners Requires malibu

Standard size

<div class="bg-light-silver br2 mr2 flex-auto w-50 flex justify-center">
  <svg class="fill-gray h2 w2 v-mid mv4">
    <use xlink:href="#loading-28" />
  </svg>
</div>
<div class="bg-purple br2 ml2 flex-auto w-50 flex justify-center">
  <svg class="fill-white h2 w2 v-mid mv4">
    <use xlink:href="#loading-28" />
  </svg>
</div>

Small size

<div class="bg-light-silver br2 mr2 flex-auto w-50 flex justify-center">
  <svg class="fill-gray h1 w1 v-mid mv4">
    <use xlink:href="#loading-16" />
  </svg>
</div>
<div class="bg-purple br2 ml2 flex-auto w-50 flex justify-center">
  <svg class="fill-white h1 w1 v-mid mv4">
    <use xlink:href="#loading-16" />
  </svg>
</div>

Last row (Hide bottom border on last child)

Use the class .hk-hide-bb-last-row on the parent element of a collection of DOM elements to hide the bottom border on the last child.

Example

Item 1
Item 2
Item 3
Item 4

Tabs

Examples

Examples of how to combine Purple classes to create complex interfaces.

Input variations

Append to input

@heroku.com

Prepend to input

http://

Append & prepend

http://
.com

Join button

Inline edit

Default state

username

Editing state

Pipeline card

ultraboost-hype-prod Auto deploys master
Rolled back 17 days ago
Releasing v133
Removed app-header

Headers

Standard

Lorem ipsum

Breadcrumb

De
devex
acme-pipeline
acme-prod

Inline metadata

Lorem ipsum
Github heroku/greatness master

Metadata

Lorem ipsum
Space devex-frankfurt
Github heroku/greatness master

Dropdown menu

<div class="mv3">
  <button type="button" class="hk-button-sm--secondary">
    <svg class="fill-purple h1 w1 ml1 v-mid nudge-up--1">
      <use xlink:href="#caret-16" />
    </svg>
  </button>
</div>

<div class="w-100 mw5 pl0 tl normal bra b--light-gray br1 bg-white hk-shadow-box shadow-outer-2">
  <ul class="pa0 ma0 pv1 f5">
    <li class="list f5">
      <a href="#" class="link db dark-gray hover-bg-lightest-silver lh-copy pv1 ph3">View logs</a>
    </li>
    <li class="list">
      <a href="#" class="link db dark-gray hover-bg-lightest-silver lh-copy pv1 ph3">Run console</a>
    </li>
    <li class="list">
      <a href="#" class="link db dark-gray hover-bg-lightest-silver lh-copy pv1 ph3">Production check</a>
    </li>
    <li class="list">
      <a href="#" class="link db dark-gray hover-bg-lightest-silver lh-copy pv1 ph3">Restart all dynos</a>
    </li>
    <div class="db mv1 bb b--light-silver"></div>
    <li class="list">
      <a href="#" class="link db dark-gray hover-bg-lightest-silver lh-copy pv1 ph3">Add to pipeline...</a>
    </li>
  </ul>
</div>