CSS Code Convention

 

Precompile your CSS

This convention is written in LessCSS syntax, but now I would recommend SASS instead. Use a precompiler of your choice.

Classes or IDs

Always and only use classes. Never attach style to an ID.

Components

Organize your CSS and markup into components.
Name of components, modifiers and descendants are written in camel case.

Syntax:

<componentName>_descendantName[--modifierName]


Example:

tweetBlock_header--special

Component descendants

Descendants modify the presentation of a child to the component it is attached to. You can’t use more than one descendant in a selector.

<div class="tweetBlock">
 <h3 class="tweetBlock_header"><%= @tweet.header =></h3>
 <p class="tweetBlock_content"><%= @tweet.content %></p>
</div>

.tweetBlock {
  //Style for the tweet container
 }
.tweetBlock_header {
    //Styling the header here
}
.tweetBlock_content {
    //Styling the actual content here
}

/* Compiles into */
.tweetBlock {..}
.tweetBlock_header {..}
.tweetBlock_content {..}

Component modifiers

A modifier class is a class that together with a base class gives a component a special style. If my base class is

.button

and my modifier class is named

.button--special

then the markup using these classes would look like this.

<button class="button button--special">Sign in</button>

Javascript

Hooks

If you need to hook an event to an element. Add a specific .js-hook class. Never attach style to such classes.

Syntax: .js-target
Example .js-login

<button class="btn btn--login js-login">Sign in</button>

<div class="accordion">
    <h2 class="accordion_header js-accordion">Click to expand</h2>
    <div class="accordion_content">Some content...</div>
</div>

States

State classes indicate a certain state of an element and change the presentation of that element. They are usually controlled by javascript. Written in camel case.

These classes can not be styled on their own but always appear in your css as an adjoining class.

Syntax: .is-stateOfComponent
Example: .is-open

.accordion_content {..}
.accordion_content.is-expanded {..}

<dic class="accordion_content is-expanded">...</div>

Variables

Colors, z-indices and fonts all use variables for maintainability and clarity.

Colors

Colors are defined in two steps. First we declare a lot of colors like @color-deepBlush and @color-aquaHaze. Then we define where these colors should be used. This way we can easily both change the actual color it self and change what elements should be styled with that color all in one file, colors.less

To find the name of the color use: http://chir.ag/projects/name-that-color/#6195ED

Syntax: .property-targetElement
Example: .color-menuBorder

/* First we define all colors */
@color-brilliantRose: #ED61BD;
@color-amour: #FCF3F9;

/* Then we define where these should be used */
@color-menuTitle: @color-brilliantRose;

z-index

Z indices are treated the same way as color variables, it’s a two step thing. First we define some general z-index levels. Then we define which elements that should use these z-indices.

Remember if you give a z-index of say 5 to an element that is positioned, all children within that element are in a new z-index context so that you can start over on z-index: 1; again within that element. You don’t need to set the z indices for the entire page in a scale from 0 – 99999. Think of it this way. Your entire page in large has 10 levels of z-indices. And each time you set a z-index of a component that component then has 10 levels within itself and so on.

To reflect this in the CSS we simply indent any sub elements.

Syntax: zIndex-<value>-targetElement
Example: zindex-1-backgroundBlock

/* First we define the general levels */
@zIndex-1: 100;
@zIndex-2: 200;
@zIndex-3: 300;
@zIndex-4: 400;
@zIndex-5: 500;
@zIndex-6: 600;
@zIndex-7: 700;
@zIndex-8: 800;
@zIndex-9: 900;
@zIndex-10: 1000; //Only used for dev and debug purpose

/* Define the indices for each element and sub element */
@zIndex-1-backgroundBlock: @zIndex-1;
@zIndex-1-someElement: @zIndex-1;
    @zIndex-1-someElementBackground: @zIndex-1;
    @zIndex-2-someElementBlock: @zIndex-2;
    @zIndex-3-someElementOverlay: @zIndex-3;

@zIndex-2-myComponent: @zIndex-2;
@zindex-2-loginForm: @zIndex-2;

@zIndex-3-myComponentOverlay: @zIndex-3;


It’s worth pointing out that someElementOverlay is still positioned below say loginForm since the overlays parent only has a z-index of 100;

Fonts

We want an easy way to change our commonly used typography as well as a way to let us still customize everything if we like. This is accomplished by using a combination of mixins and variables.

Syntax: .font-intendedUse
Example: .font-smallHeadline

/* First we define font sizes and families */
@fontSize-smallest:		12px;
@fontSize-smaller:		14px;
@fontSize-small:		15px;
@fontSize-medium:		16px;
@fontSize-large:                17px;
@fontSize-larger:		18px;
@fontSize-largest:		20px;

@lineHeight-tightest: 1em;
@lineHeight-tighter:
@lineHeight-tight:
@lineHeight-base:
@lineHeight-loose:
@lineHeight-looser:

@letterSpacing-tightest:
@letterSpacing-tighter:
@letterSpacing-tight:
@letterSpacing-normal:
@letterSpacing-loose:
@letterSpacing-looser:

@fontFamily-headline: 	"Some hipster font", Arial, sans-serif;
@fontFamily-paragraph: 	"Some cool web font", Verdana, sans-serif;
@fontFamily-iAmAMoron:	"Comic Sans", "Times New Roman", serif;

/* Then we define the classes */
.font-smallHeadline {
    font-family: @fontFamily-headline;
    font-size: @fontSize-larger;
    font-weight: 300;
    letter-spacing: @letterSpacing-loose;
    line-height: @lineHeight-looser;
}
.font-paragraph {
	font-family: @fontFamily-paragraph;
	font-size: @fontSize-medium;
	font-weight: 400;
        letter-spacing: @letterSpacing-normal;
        line-height: @lineHeight-base;
}

/* We use it like this in other classes */
.myComponent_content {
	border: 1px solid @color-myComponentBorder;
	.font-paragraph;
}

Vendor prefixes

Always use a mixin when you need browser specific prefixing.

Syntax: m-propertyName
Example: m-borderRadius

.m-borderRadius(@radius) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
} 

//--- And use like this
.myComponent {
  .m-borderRadius(3px);
}

Media Queries

Always nest media queries inside classes. This is an exception to the no-nesting rule. By nesting them we keep things clean and in one place. You could define the breakpoints as variables but my personal favorite is to just start out with the mobile width and then keep increasing width of you browser window until a certain element break (looks ugly) and insert a breakpoint at that specific width to fix that particular element. That way our site becomes truly responsive.

.myComponent {
    //This affects all sizes up until the next defined size
    display: block;
    width: 100%;

    //When we reach 600px change display mode and width
    @media(min-width: 600px) {
        display: inline-block;
        width: 10%;
    }

    //When we reach 1024px adjust the width
    @media(min-width: 1024px) {
        width: 20%;
    }
}

Formatting

Formatting is more religion than science. Do what you like but do it consistently throughout the entire project.

Brackets and spacing

CSS classes are to be followed by a space and a curly bracket and then a new line. Properties are indented a tab that is 4 spaces wide.

.myComponent {
    ....
}
.anotherComponent {
    ....
}

Comments

Use the Less style of comments. They are removed upon compilation.

//------- My Comment ---------
.myComponent {
    ....
}

Sorting of properties

Always sort properties alphabetically with mixing last also sorted alphabetically.

// Correct
.myComponent {
    background-image: url("icon-home.png");
    color: @primaryTextColor;
    font-family: "Times New Roman", sans-serif;
    margin: 0 auto;
    z-index: @zIndex-1-myComponent;
}

//Incorrect
.anotherComponent {
    font-family: "Times New Roman", sans-serif;
    margin: 0 auto;
    color: @primaryTextColor;
    z-index: @zIndex-1-myComponent;
    background-image: url("icon-home.png");
}

Quotes

Always quote when you can. It makes things visually clearer.

// Correct
.myComponent {
    background-image: url("icon-home.png");
    font-family: "Times New Roman", sans-serif;
}

//Incorrect
.anotherComponent {
    background-image: url(icon-home.png);
    font-family: Times New Roman, sans-serif;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Powered by kittens and brainpower.