Introduction

This site is meant to help us unify our front-end code. These are the documented best-practices for front-end code structure.

#

Buttons

HTML

Main button classes

.button
.button-action
.button-cancel
.icon-button

Add-on classes

.small-button
.toggle-button

HTML Structure

<button class="button">A button</button>
<button class="button-action">An action button</button>
<button class="button-cancel">A cancel button</button>

<a href="#" class="button">A link styled like a button</a>
<a href="#" class="button-action">A link styled like an action button</a>
<a href="#" class="button-cancel">A link styled like a cancel button</a>

<button class="button small-button">A small button</button>

<button class="button toggle-button">A Toggle Button</button>

Live example on Codepen

#

CSS Background

CSS

background, background-color, background-image, background-position, background-repeat, background-size

background is one of the most common properties we set. It can be used shorthand or broken out into more specific properties.

Set a background color

When setting a background color, use background: $light-grey. Even when overriding for something like a hover state, still just use background, rather than background-color.


Set a background image

Using an image as a background can be complicated. The easiest way to do this, without digging in too much, is to set the background-image: url() and use the provided mixin.

Example

// Here's the mixin
@mixin background-image(){
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
}

// Here's how to use it
.element {
  background-image: url('.../image.jpg');
  @include background-image();
}

Using this method, you can also set a fallback image by having multiple values in the background-image. This is helpful when you’re not hosting the source of the image you want to set.

Example

.element {
  background-image: url('http://twitter.com/.../avatar.jpg'), url('.../backup-image.jpg');
  @include background-image();
}

background-size: cover vs. contain

background-size: cover will stretch the image to cover the entire element, no matter the proportions, but it will keep the image’s original aspect ratio.

background-size: contain will constrain the image to fit within the bounds of the element, but will always keep the entire image visible.

#

CSS Box Model

CSS

The Box-model is the basis for the strucure of elements on the web. Elements are defined in space by firstly their display-type, then their width and height, followed by other attributes such as padding, margin, and border.

box-sizing

In the original design of the box-model, padding, margin, and border units would add to the size of the div. (That’s the old way)

In the new way (using box-sizing: border-box;), padding and border push into the set dimensions of the div. This allows for much easier calculations and control of element spacing.

Here’s a live Codepen example: http://codepen.io/shaunrfox/pen/raojBW/


width

EXAMPLE VALUES: 100%, 200px, calc(100% - 50px)

width is very straightforward, but the most important thing to keep in mind is scalability on different screen sizes and when the browser window is resized.

To accomodate the different environments that a site could be viewed in, favor setting percentage-based widths.

Any percentage-based width used is going to be relative to the element’s parent.

calc() is usually used to make something fill a space, minus a pixel value. For instance having a scrollable area, minus the header. Make sure to leave a single space on either side of your operator or it won’t work.


height

EXAMPLE VALUES: 100%, 200px, calc(100% - 50px)

height is considered in much the same way as width, but is not as often set as a percentage (besides 100%).

Any percentage-based height used is going to be relative to the element’s parent.

calc() is usually used to make something fill a space, minus a pixel value. For instance having a scrollable area, minus the header. Make sure to leave a single space on either side of your operator or it won’t work.


padding

EXAMPLE VALUES: 20px

In the new box-model mode (box-sizing: border-box;), padding will push into the element.

padding can be defined on four sides of an element, like many things: top, right, bottom, left. This can be done as a shorthand or as individual values.

.my-class {
  padding: 10px 20px 30px 0;
  /* top: 10px, right: 20px, bottom: 30px, left: 0 */
}

// or

.my-class {
  padding-top: 20px;
  padding-left: 40px;
}

margin

EXAMPLE VALUES: 20px, 0 auto

margin is always outside of the dimensions of your element and set the space around the element, relative to it’s neighbors. This being the case, be especially careful not to cause layout collisions. This happens a lot when combining margin with percentage-based widths.

A common trick for horizontally centering an element inside a larger parent is to set margin: 0 auto;. The 0 defines the top and bottom margin (a shorthand), and the auto defines the right and left. It should be noted that this only works if the element also has a width set.

.parent-element {
  width: 100%;
  height: 100%;
}

.child-element {
  width: 400px;
  height: 300px;
  margin: 0 auto;
}

border

EXAMPLE VALUES: 1px solid $light-grey

border is defined similar to padding and can be treated nearly the same. It can be defined on all sides at once or as individual attributes.

We most commonly use the shorthand definitions listed below, but they can also be broken out on their own. The second example is also a common way we use it, defining multiple values as shorthand, but then overriding specific ones for an interaction or emphasis.

.element {
  border: 1px solid $light-grey;
}

.other-element {
  border-bottom: 1px solid $white;

  &:hover {
    border-color: $blue;
  }
}

border-radius

EXAMPLE VALUES: 4px, 50%

border-radius affects the corners of things. It can be used to give subtle rounded-corners to things like buttons, or to make element corners completely round (border-radius: 50%), forming a circle, for things like avatar images.

It can be defined shorthand as top-left, top-right, bottom-right, bottom-left, or as individual values.

#

CSS Box-Shadow

CSS
#

CSS Cursor

CSS
#

CSS Display

CSS
EXAMPLE VALUES: inline, block, inline-block, table, none

“Every element on a web page is a rectangular box. The display property in CSS determines just how that rectangular box behaves.” —CSS Tricks

https://css-tricks.com/almanac/properties/d/display/


display: inline;

These elements are things that behave like text. They’re primarily relative to a baseline and don’t have much ability to affect the layout of other elements on the page.

While many elements’ default state is inline, it’s not something that we set as an override very often, since we’re mostly wanting to deal with boxy things.


display: block;

These elements are things like <div> and <section>. They will behave like rectangles and they’re the building blocks of web layouts.

The default width for block elements is 100%, so they will stretch to the extent of their parent’s width.


display: inline-block;

This is kind of a mix of the two above. You can set some of the same “physical” characteristics of block, but the element is still relative to a baseline (of text, for instance).

The default width for inline-block elements is relative to the element’s contents.

If you want to center an element using inline-block, you must set text-align: center on it’s parent.


display: table

This can be used to make regular block elements behave more like a table. For example, a parent element can be set to display: table; and it will have children set to display: table-row; and display: table-cell;. This can be especially helpful when you need to display tabular data but also need to support a responsive environment.

Try to limit use of display: table unless you’re showing tabluar data.


display: none

The easiest way to hide elements on the page.

#

CSS Layout

CSS

position

EXAMPLE VALUES: relative, absolute, fixed

The position property manipulates the location of an element. Each value of this property will affect the element in a different way.

static

static is the default position value of all elements on the web. If you don’t set the position explicitly, this is the position your element has.

relative

relative positioning will layout relative to it’s normal position. You can affect the position of the element by adding additional positioning properties, like top, right, bottom, left, and z-index. This will remain in the flow of other elements on the page.

absolute

absolute positioning is always relative to it’s closest parent with relative positioning. This will also be pulled out of the normal flow of the page, so it can overlap other elements.

fixed

fixed positioning is always relative to the viewport, meaning it always stays in place, even when the page is scrolled. This is rarely used except sometime for things like headers, footers, or modals.

top, right, bottom, left

EXAMPLE VALUES: 0, 100%, -20px

These properties are used in conjunction with relative, absolute, or fixed positioning.

.parent-element {
  position: relative;
}

.child-element {
	position: absolute;
	top: 20px;
	left: 20px;
	// 20px from the top, left corner of it's parent, regardless of padding or other sibling elements.
}

z-index

EXAMPLE VALUES: 1, -1, 25

The z-index property in CSS controls the vertical stacking order of elements that overlap. As in, which one appears as if it is physically closer to you. z-index only effects elements that have a position value other than static (the default). —CSS-Tricks

Be both conscious and sensible with your z-index values. Avoid tacking on lots of zeros, but also leave yourself room to fill in between values if you need to.


float

EXAMPLE VALUES: left, right, none

float is usually used when you want two or more block elements to be side-by-side. It’s easiest to see in a visual example: http://codepen.io/bxyoung89/pen/WbLRve

clear

If you float things, the parent is not aware of their height. Using a clear fix solution forces the parent to respond to the height of it’s children.

You should use our handy mixin: @include clearfix();


transform

EXAMPLE VALUES: translateY(-50%)

You can do a lot of things with transform, but usually we only use it for vertical centering. You should be careful with this property because it does not necessarily respect round pixel values and can cause things to become blurry.

Our mixin: @include vertical-align(); will vertically center a block element with unknown height inside a parent that’s larger (most of the time). (not to be confused with the vertical-align property)

More info here: https://css-tricks.com/centering-css-complete-guide/


vertical-align

This is primarily used for aligning a collection of elements with display: inline-block;. You’ll usually set this to top so that the elements’ tops all line up.

#

CSS Opacity

CSS
#

CSS Overflow

CSS
#

CSS Primer

CSS
Name
Description
Common Values
.class, block, inline-block, table, none
"Every element on a web page is a rectangular box. The display property in CSS determines just how that rectangular box behaves." —CSS Tricks
inline, block, inline-block, table, none
background, background-color, background-image, background-position, background-repeat, background-size
position, z-index, top, right, bottom, left, float, clear, vertical-align, transform
The Box-model is the basis for the strucure of elements on the web. Things like width, height, padding, margin, and border all play into an element's structure.
width, height, padding, margin, border, box-sizing
Everything about dealing with text.
font-family, font-weight, font-size, font-style, line-height, letter-spacing, text-align, text-transform, text-decoration, color
:before, :after
:hover, :active, :disabled, :first-child, :last-child, :nth-child
pointer, default
auto, scroll, hidden
1, 0.8, 0.2, 0

How to Center Things

Centering things in CSS can be one of the most challenging parts of understanding CSS. CSS Tricks has a good roundup of the usual methods for centering just about anything:

Centering in CSS: A Complete Guide, by CSS Tricks

Here’s also an example of how to center using “table” styling (used for very specific situations): http://codepen.io/shaunrfox/pen/ZYMzpL/

#

CSS Pseudo Elements

CSS

:before & :after

Every element on the web that can contain content (not img, input, br, hr, etc.) can be given additional pseudo elements.

:before will put it’s content before all of the parent’s children. :after will put it’s content after all of the parent’s children.

Carrot Dangler

This is used to make a small arrow that points to another element. We typically use this for special tooltips or dropdowns. You can see this more easily in the Codepen Example.

.parent-element {
  position: relative;
  // Must set position for the carrot to work

  &:before,
  &:after {
    content: ''; // IMPORTANT: pseudo elements will not display at all unless the content attribute is set. If you don't want any text, use the empty string.
    display: block;
    position: absolute;
    left: 50%;
  }

  &:before {
    top: -12px;
    margin-left: -12px;
    border-bottom: 12px solid $light-grey;
    border-right: 12px solid transparent;
    border-left: 12px solid transparent;
  }

  &:after {
    top: -10px;
    margin-left: -10px;
    border-bottom: 10px solid $white;
    border-right: 10px solid transparent;
    border-left: 10px solid transparent;
  }
}
#

CSS Pseudo Selectors

CSS

:hover, :active, :disabled, :first-child, :last-child, :nth-child

#

CSS Selectors

CSS

CSS selectors apply styling to all elements that match the given criteria.

In CSS, specificity and order matters. The most specific match will always apply it’s styles, and if there’s a tie, the last in the source-order will win.

.class

This is the most common way to attach styling to an element. Creating a good system for your class name scheme will help avoid collisions and provide clarity for everyone on the project.


Element

This selector will affect all matching elements. For example, the css selector div will affect all <div> elements.


Attribute selectors

Sometimes it might be necessary to select elements based on their attributes if a class selector is not appropriate. Here are the most common use cases that we run into.

input[type=”text”]

This is used to target all inputs with their type attributes set to “text”.

data-

HTML allows custom attributes beginning with data-. One example of where you could use this would be for a custom tooltip where you set data-tooltip to be the content. Beware that this technique is not the best for accessibility or internationalization.

[class=”ico-*”]

This is a special selector that will allow you to target classes that are prefixed or suffixed with a set naming scheme. The Fox Icons are a good example of this.


Combining Selectors

Now that you know about the two basic selectors, there are various ways we can combine selectors to be more specific, or be more efficient.

selector, selector

To keep your code DRY, you can list selectors that will share the same attributes. You do this by putting all selectors in a comma separated list.

.class-1.class-2

For an element that has multiple classes, the selector can be written: .class-1.class-2. It’s important to note that this selector is more specific then either classes on their own. If you use a property that has been defined on either of the individual classes, this new selector will override it. If there are properties that are unique to any of the selectors, that property will not be overridden. The determination of how these rules are applied is called “cascading”.

selector selector

Adding a space between selectors targets the first selector’s children, who match the second selector.

Example:
<div class="class-1" id="div-1">
  <div class="class-2" id="div-2"></div>
  <div class="class-2" id="div-3"></div>
</div>
<div class="class-2" id="div-4"></div>
.class-1 {
  background: red;
}

.class-2 {
  background: blue;
}

.class-1 .class-2{
  background: green;
}

In this example, div-1 will be red. div-2 and div-3 will be green. div-4 will be blue.

selector > selector

This rule is similar to selector selector, except it only selects the direct descendents, but will not go any further down the hierarchy.


SCSS

This section will cover selectors in SCSS. To read more about SCSS in gerneral, see the SCSS Primer.

nesting

In SCSS, you can nest selectors to logically scope rules, but this should be used cautiosly to avoid making too many overly-specific selectors when they’re compiled.

Nesting Example:
.box {
  background: red;

  .header {
    background: blue;
  }
}
Compiled:
.box {
  background: red;
}

.box .header {
  background: blue;
}

&

As you can see from the previous example, nesting introduces a space between the two rules. Often, though, you’ll want to have no space between selectors. To achieve this, add an & before the nested selector.

Ampersand Example:
.box {
  background: red;

  &.blue {
    background: blue;
  }
}
Compiled:
.box {
  background: red;
}

.box.blue {
  background: blue;
}

browser prefixes

Due to the rapidly evolving state of the web, some browsers implement features faster than others. Usually when a feature is implememnted before it makes it into the official CSS specification, browsers will allow a prefixed version of the property. The most common prefixes are: -webkit, -ms, -moz, -o. This can be a hge hastle to maintain. We highly recommend using an auto-prefixer to solve this issue. Google it.


@media Queries

In the new era of Responsive Web Design, things on the web should be built to work on a variety of screen sizes. The first tactic to accomplish this is to use percentage-based dimensions. Where the layout needs to adjust or elements need to change size, you should use @media Queries to introduce new styling.

Example:
.box {
  // in a grid, two across
  display: inline-block;
  width: 50%;

  @media (max-width: 600px) {
    // at 600px or less, it becomes a list
    display: block;
    width: 100%;
  }
}

Do not do this

Selecting IDs

IDs, when used properly, are unique and only used once. Targetting IDs, therefore, is inefficient and does not promote DRY code.

Lots of nesting in SCSS

Too much nesting in SCSS creates overly specific selectors, leading to poor performance and not reusable code.

!important

When CSS gets overly specific, it may be tempting to use !important to get overrides to work, but DON’T DO IT. Use better selectors.

Selecting *

* will select EVERYTHING. We only use it once, to define the box-model. In general, there are not many other reasons to select all and it can become very computationally intensive.

#

CSS Text Handling

CSS

font-family

EXAMPLE VALUES: Depends on your project.

To set what font gets used, use the font-family property. In most of our projects this is done for you in our base css.

However, if you want to change what font is used, you should have numerous fallbacks like.

.my-class {
  font-family: "Source Sans Pro", Verdana, Helvetica, Arial, sans-serif;
}

In this example Verdana will be used if the broswer does not have access to “Source Sans Pro”, then Helvetica, etc…

If you want to have them download a font, you’ll want to use @font-face. Here’s a helpful resource TODO PROVIDE RESOURCE


font-size

EXAMPLE VALUES: 12px, 1.2rem, 1.4rem, 1.6rem

font-size controls how big the words will appear.

There are several units you can use, but we recommend pixels (px) and root ems (rem). Root ems are a percentage of the font size set on the html element.

As part of our code, we have a mixin that you should use in most cases. It will take care of both rems and a pixel fallback.

usage

.my-class {
  @include font-size(1.6);
}

outputs

.my-class {
  font-size: 16px;
  font-size: 1.6rem;
}

color

EXAMPLE VALUES: $off-black, #ffffff, tint($mid-grey, 0.7), $red, rgba(255, 255, 255, 0.5)

color changes the color of the text.

In our code, we have variables corresponding to color values. SCSS Color Variables


line-height

EXAMPLE VALUES: 12px, 30px

line-height sets the vertical spacing between lines of text. We mostly use it to vertically center a single line of text. If there is a chance your text might wrap, use a different method as detailed by Centering in CSS: A Complete Guide, by CSS Tricks

For buttons, we commonly set the line-height to the height of the button to center the text vertically within the button.

.button {
  height: 30px;
  line-height: 30px;
}

text-align

EXAMPLE VALUES: center, left

text-align is fairly straightforward. It aligns text. text-align: center; should mostly only be used for text that does not wrap. Center-aligned text that wraps is more difficult to read.


font-weight

EXAMPLE VALUES: normal/400, semibold/600, bold/700

font-weight tells the browser which cut of the given font you want to deliver to the browser. The numbers shown above generally correspond directly to the named weights beside them, though some font makers use different systems. These three are the most common values we use with Source Sans Pro.


font-style

EXAMPLE VALUES: normal, italic

This attribute is basically used to set the text to italic. You only really need to set it to normal if you’re overriding the italic.


text-transform

EXAMPLE VALUES: normal, uppercase

text-transform will take the formatting of the given text and transform it to your defined value, most commonly to make something uppercase.

Uppercase text can be difficult to read, though, so we often pair this with font-weight and letter-spacing to help with that, as seen below.

<div class="name">Shaun Fox</div>
.name {
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 1px;
}

letter-spacing

EXAMPLE VALUES: 1px, 1em

This is typically paired with text-transform as demonstrated above. It should only ever be used on uppercase text. If used with lowercase text, readability is sacrificed.


text-decoration

EXAMPLE VALUES: none, underline

text-decoration is most often used to override the default browser styling of anchor tags. Frequently we’ll set the anchor to text-decoration: none, which removes the underline, but we’ll give it other attributes that help define it as a link. For example:

.link {
  text-decoration: none;
  color: $blue;

  &:hover {
  	border-bottom: 1px solid $blue;
  }
}

white-space

EXAMPLE VALUES: nowrap

We primarily use white-space: nowrap to force text to be one line, without wrapping. Most often used in conjunction with CSS truncation.

#

Checkboxes

HTML
<div class="checkbox-wrapper">
  <input class="checkbox-input" type="checkbox" id="show_on_login" />
  <label for="show_on_login">Show on login</label>
</div>
#

Dropdowns

HTML

We use the Bootstrap markup and JS for our dropdowns.

<div class="dropdown">
  <button class="button dropdown-toggle" type="button" id="cool-dropdown" data-toggle="dropdown">
    Dropdown
    <svg viewBox="0 0 30 30" class="ico-arrow-down">
      <use xlink:href="#ico-arrow-down"></use>
    </svg>
  </button>
  <ul class="dropdown-menu" role="menu" aria-labelledby="cool-dropdown">
    <li><a href="#">Action</a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
    <li class="divider"></li>
    <li><a href="#">Separated link</a></li>
  </ul>
</div>
#

SCSS Color Variables

CSS
SCSS

Our color variables, defined in _colors.scss, are designed to help us reuse colors without having to remember hex values.

/* This is a default set of utility colors that we use from time to time. */
$red: #ed1c24;
$orange: #ff6600;
$yellow: #ffcc00;
$forest-green: #666600;
$green: #51b848;
$teal: #006666;
$blue: #0090cb;
$cyan: #00ccff;
$dark-cyan: darken($cyan, 10%);
$indigo: #2a1e5c;
$purple: #66439a;
$yellow-green: #efe80c;
$red-orange: #ff3600;
$tan: #F2F1E6;
$dark-tan: #C6C7C0;

/* These are all of our blacks, greys, and whites. */
$black: #000;
$off-black: #111;
$dark-grey: #666;
$mid-grey: #aaa;
$light-grey: #ccc;
$off-white: #eee;
$white: #fff;

/* Sometimes we'll define colors for very specific uses. They should get very specific names to help assure that they're only used in the appropriate place. */
$filter-background: #f9f4de;
$filter-active-button-color: #eee27e;

/* Our brand colors */
$snap-blue: #00a9ed;
$orange: #fe5019;
$midnight: #002B38;

/* If we find that we're recreating a particular color often, we should store it as a new variable, like this: */
$light-blue: tint($blue, 30%);

There are also a few functions we can use to transform colors to other colors.

Our custom color functions:

// Slightly lighten a color
@function tint($color, $percentage) {
  @return mix($color, white, $percentage);
}

// Usage
.box {
  background: tint($blue, 30); // mixes $blue at 30% and white at 70%
}

// Slightly darken a color
@function shade($color, $percentage) {
  @return mix($color, black, $percentage);
}

// Usage
.button {
  background: $blue;
  border: 1px solid shade($blue, 80); // mixes $blue at 80% and black at 20%
}

These are our preferred way to transform colors because it outputs a slightly more predictable result than the standard lighten() and darken() built into SCSS.

Built-in SCSS color functions:

  • Lighten: background: lighten($blue, 20);
  • Darken: background: darken($orange, 60);
  • RGBA:
    • color: rgba($off-black, 60); - useful for letting text mix onto background colors
    • background: rgba($white, 95); - useful for making the background of an element transparent without affecting the transparency of it’s contents.

There are many more color functions, but these are the main ones we use.

#

SCSS Mixins

CSS
SCSS

Mixins are chunks of commonly used code that can be included again and again throughout your SCSS. Mixins can also take a variable when they’re called.

This snippet is used on parent elements with floating child elements to force them to wrap around their children.

@mixin clearfix {
  &::after {
    content: '';
    display: table;
    clear: both;
  }
}

This snippet is used to generate REM-based font sizes with a PX backup. Note that it takes a variable ($size) and does some math with the value it’s given.

@mixin font-size($size){
  font-size: ($size * 10) + px;
  font-size: $size + rem;
}

More snippets that are used extensively:

// Uppercase, 600, letter-spaced
@mixin uppercase {
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 1px;
}

// Truncate text
@mixin truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

// Vertical align anything
@mixin vertical-align {
  display: block;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  transform-style: perserve-3d;
}

Usage

.box {
  @include vertical-align();
  @include uppercase();
  @include font-size(1.8);
}

Outputs to:

.box {
  display: block;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  transform-style: perserve-3d;

  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 1px;

  font-size: 18px;
  font-size: 1.8rem;
}
#

SCSS Primer

CSS
SCSS
#

Variables in SCSS

CSS
SCSS

SCSS (or Sass) variables can be used for any kind of simple stored value. We most commonly use them for colors, but they can be used for lots of things.

$snap-blue: #00a9ed;
$orange: #fe5019;

$filter-buttons-height: 40px;

$global-padding: 2%;

Usage

.button {
  background: $snap-blue;
  height: $filter-buttons-height;
  padding: 0 $global-padding;
}

This compiles to:

.button {
  background: #00a9ed;
  height: 40px;
  padding: 0 2%;
}