Skip to content

Instantly share code, notes, and snippets.

@tdrach
Last active August 29, 2015 14:21
Show Gist options
  • Save tdrach/1c35d0cf893c73b62f49 to your computer and use it in GitHub Desktop.
Save tdrach/1c35d0cf893c73b62f49 to your computer and use it in GitHub Desktop.

Motel Front End Coding Styleguide

CSS Coding Style

Formatting

Use one space after selector definitions and property declarations.

.selector {
	background-color: #fff;		
}

If ever grouping selectors, keep them on their own line. Place the closing brace on its' own line, this makes it easier to see where the selector's territory ends. Each declaration should appear on its own line for more accurate error reporting. This also results in more truthful git diffs.

.selector-one,
.selector-two {
	background-color: #fff;
	color: #333;	
}

Omit using units when declaring 0 values on properties, it will prevent problems.

// Good job, yay!
margin: 0;
	
// Bad dog
margin: 0px;

If possible, declare CSS properties in alaphabetical order, then you'll always know where to look when looking through a selector's values.

.selector {
	background-color: #fff;
	color: #333;
	display: block;
}

Don't use elements in selectors, don't use child selectors, don't use key selectors, and don't nest (with some exceptions). In short, selecting with just classes is really fast. CSS reads from right to left and the more selectors, the slower we're going to be. 1 This also maintains our goals of creating descriptive class names.

// Bad things happening: high specificity, messy, slower
div.selector,
.selector > li,
.selector a {
	font-weight: bold;
	span {
		border: 1px solid #333;
	}
}

// Good things happening: faster and cleaner
.selector,
.selector-item,
.selector-link {
	font-weight: bold;
}

Never use IDs

There are a bunch of reasons for this, but at the top of the list are:

  • You can only use them once, preventing reusability
  • Create complicated specificity problems
    There's no reason to use IDs, don't use them.

JS Prefixes

If you need a selector for Javascript, prefix with js-*. Never style these classes, they should not show up in any stylesheet.

State Prefixes

When a style changes based on an action or state, use a state class to denote and style this change. Use a class starting with is-* to describe the state. For example is-active.

Resources

  1. Writing Effecient CSS Selectors

HTML Coding Style

Proper HTML style keeps everything consistent, and increases the performance of our site. These are a couple guidelines when writing markup. This is a great guide for how websites can be better.

Use the HTML5 doctype

<!DOCTYPE html>

Use semantic markup

Know the difference between a <section> and a <div>, if you have a list of stuff and the order matters use an <ol>.

Always use quotes on attributes

<h2 class="subheading">

Don't use trailing slashes on self-closing attributes

<input> not <input/>

Avoid setting inherent attribute values

reference.

<input disabled> not <input disabled="true">

Avoid redundant or unnecessary parent elements

Elements without any attributes and content are rarely useful, get rid of all the cruft you can and be violent.

	<ul class="nav">
		<li class="nav-item is-active">
			<a href="/about" class="nav-itemLink">About</a>
		</li>			
		<li class="nav-item">
			<a href="/faq" class="nav-itemLink">FAQ</a>
		</li>
	</ul>

not

	<div>
		<ul class="nav-list">
			<li class="nav-item">
				<div>
					<a href="/about" class="nav-itemLink">About</a>
	// etc...

Use only lowercase

<a href="#"> not <A HREF="#">

Provide multimedia fallbacks

<img src="/img/logo.png" alt="Motel Logo"> not <img src="/img/logo.png">

Leave out the type attribute in link and script tags

The type="XX" attribute in <link> and <script> tags. Unless it's not Javascript or CSS, reference.

Always use double quotation marks in HTML

<section class="block">

Motel SCSS Architecture

The idea of this document is to give us a starting, and reference point for architecting HTML and SCSS in projects. Often, this will be a new project, but not always. The ideas here can be applied to existing projects. At Motel, we're constantly changing and improving. It goes without saying that this guide will change and become better over time and after experience. Much smarter people including Harry, Jacob, Nicolas, Nicole Sullivan have said smarter things and have smarter ideas about this smart stuff. I've stolen a lot of this from them.

Ideas

Structure

/ scss
	
	• app.scss
	• config.scss
	
	/ bits
		• forms.scss
		• buttons.scss
		• footer.scss
	
	/ global
		• base.scss
		• layout.scss
		
	/ lib
		• bourbon
		• neat
		• reset
				
	/ mixins
		• rem
		• vp

_

app.scss

Include every file here. We use the @include "XX" syntax to grab files we need. This is also where we define source order. Do not @include in any other files.

//  Init Configuration
@import "config"

// Include Libraries
@import "lib/bourbon/bourbon";
@import "lib/neat/neat";
@import "lib/reset";

// Global Styles	
@import "global/base.scss"
@import "global/layout.scss"

// etc...

config.scss

This is where all of our $variables live, and project-specific colors, fonts, etc. are defined. When a value needs repeating, it may need to be in a variable, and this variable should be in the config.scss file.

At its' simplist, this may be something like:

// config.scss

// Font Size
$fontSize-biggest: 6rem;
$fontSize-normal: 2rem;
$fontSize-smallest: 1.3rem;

// Colors
$color-dark: #022040;
$color-primary: #EA4644;

//

Declaring Variables

When declaring variables for CSS, start with a camelCased name that matches the property (if possible).

So declaring a variable for a CSS border-left would look like $borderLeft-* to start. Follow that with a meaningful, but ambiguous name like $borderLeft-pullQuote. Notice we're not saying "chunky" or "highlight", because the actual style may change later on.

$borderLeft-pullQuote: 6px solid $color-active;

Being a little ambiguous here helps, if we use something like $color-red in a variable name, maybe what we're really talking about is the "primary" brand color, maybe $color-primary would be better. We could even go a step further by adding a modifier describing a variable:

Colors are a good example of this:

$color-subtle--borders: #fafafa;
$color-active: #66cccc;

There may be weird properties, where you can describe as best you can.

Example: I declared variables to help me with crazy clip-paths on motel.is.

$clipPath-topLeft: polygon(100% 8%, 100% 38%, 90% 100%, 0 94%, 0 0);

Z-Index

One of the more annoying things of relative/absolute/fixed positioning is setting z-index values for these elements. Anyone who's done this has quickly realized the mess of keeping track of all these values and how they relate to each other @fat created a scale for this to help keep it in order, and to see the relation between elements.

I think this is really helpful, so if you're doing anything with z-index, use the scale, and declare the variables all in one place.

// config.scss

$zIndex-1: 100; 
$zIndex-2: 200; 
$zIndex-3: 300; 
$zIndex-4: 400; 
$zIndex-5: 500; 

$zIndex-tabView: $zIndex-1;
$zIndex-editModal: $zIndex-2;

Global Directory

Anything that applies to the entire project will go into the global directory. For us, we will start with a base.scss and a layout.scss. Further in the project, there may be something like a typography.scss for Global type styles.

base.scss

This is where all the base styles go. These include element styles to big elements like body and html, maybe some a tags.

// base.scss

body {
	font-family: $fontFamily-brandSans;
	color: $color-dark--text;
}

a {
	text-decoration: none;
	color: $color-dark--text;
}

layout.scss

The idea with a layout file is to separate the location/layout styles from the presentation styles. If this file gets too large, it can (and should) be broken up into a different directory.

// layout.scss

.tabView {
	@include span-columns(8);
	@include shift(2);
}

If the layout.scss file got too large, breaking it into a separate directory could look like this. We will decide on a project to project basis.

/ layouts
	• dashboard.scss
	• global.scss
	• tabView.scss

Lib Directory

The lib directory holds all of our third-party libraries. For us, this means stuff like Bourbon, Bourbon Neat, and maybe Eric Meyer's Reset.

Bits! (directory)

This is where you'll be living (for most of the time). A bit is a semantically named, reusable piece of code.

There's a lot of talk about "components" and "modules". Maybe it's just my pilgrim brain, but I always have to sit, think, and read Aristotle to determine the difference. I could always insert a thesaurus-heavy definition here of what it is, but in the interest of simplicity, any reusable piece of code will be a bit.

.tabView {
	background-color: $color-subtle;
	color: $color-dark--text;
}

Reusable pieces of code, and constructing bits

A bit is a reusable piece of code you can use throughout the project. A bit file is the only place to use a placeholder. Placeholders are cool because you can use them like a selector, but if you don't, they won't compile into your CSS. You use it by doing something like this:

%button {
	background: transparent;
	padding: 1em 2em;
}

.button {
	@extend %button;
}

.button--error {
	@extend %button;
	color: $color-warn;
}

The reasons here are numerous (1) for not using @extends everywhere (much to my chagrin). We want to use placeholders and @extend with related elements, and use them to reduct code complexity and repetition.

Mixin Directory

Mixins are little functions you write in CSS for reusing blocks of code, as well as doing some crazy math business to save your typing fingers.

One of my favorite Mixins adds the vendor-prefixing values for you, like magic!

@mixin vp($name, $argument) {
	-webkit-#{$name}: #{$argument};
	-ms-#{$name}: #{$argument};
	 -moz-#{$name}: #{$argument};
	-o-#{$name}: #{$argument};
	#{$name}: #{$argument};
}

You would use it like this

.tabView {
	@include vp(transform, translateY(50%);
}

At Motel, we will use mixins to prevent us from rewriting a bunch of code. If you're repeating code, you should probably write a mixin, and @include the mixin where you need it.

Mixins will have their own file, unless they are grouped and name-prefixed. Like so:

// mixins/font.scss

@mixin font-smallCaps()	 {
	text-transform: uppercase;
	letter-spacing: 0.1em;
}

// other font mixins

What's the difference between a mixin and a placeholder?

A lot of things. Mixins will technically "repeat" code. If you use a placeholder, the compiler will grab all the selectors using that placeholder, and put them together (this can end badly). Mixins also let you pass values, so if it needs to do math fun, a Mixin is the only way to go.

Why SCSS Syntax?

At Motel, and when in the position to influence the architecture of an application, we'll chose to use SCSS. SCSS (Sassy CSS) is a SASS syntax that builds on the existing CSS syntax. We use SCSS because it is aesthetically and semantically close to the compiled CSS that will result. This means we can still write CSS, and use it in a SCSS file. If having to write Vanilla CSS for a project, all of our knowledge isn't thrown out the window. All of the functionality of SASS is contained We also remain close to the final compiled code, and can be flexible will establishing our own opinionated guidelines.

Semantic Selectors

We will primary be using classes to select our elements and style. These classes will be semantic and meaningful. We already talked about using classes (and how we're going to use them a lot). The problem with using non-semantic class names is they don't tell you a lot about what's going on, and you have to use a bunch of classes in order to get the thing to do what you want:

<section class="col-md-6 block block--big u-pullLeft tabView">

With this implementation, we'd have to add and remove classes, while writing different CSS (and possibly changing the class code) in order to modify it.

Our goal is to be writing bits that are descriptive and repeatable.

<section class="tabView">
	<header class="tabView-header">
		<h1>Dashboard</h1>
	</header>
</section>

Here we know that to restyle this element, we just need one class.

We're going to reduce the amount of code we write, while being mindful of the implications. This does mean that we'll have to be careful about how we write our CSS. Making careful use of %placeholders and @mixins, we can write clean, performant, and maintainable CSS.

The SCSS for this may look like:

// global/layout.scss
.tabView {
	@include span-columns(8);
	@include shift(4);
}

// bits/tabView.scss
.tabView {
	background-color: $color-subtle;
	color: $color-dark--text;
}

References

  1. When to use @extend; when to use a mixin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment