How to write your CSS
Structure
- The core CSS file included within your HTML should be named Default.css
- Minified CSS files should be named appropriately e.g. min.css
- Where platforms allow, CSS & Sass should sit within the standard UI folder structure with a respective folder for each.
- Partial Sass files should be created for each block of code and separated into the following folder structure;
- Base
Global styles & elements without the use of classes e.g. paragraphs, lists, headings, tables. - Components
Site specific components or modules e.g. call to actions, panels. Variations upon components should be included in the same file. - Regions
Styles associated to specific regions of content, not intended for multiple use e.g. global header, footer, navigation. - Shared
Styles, or Sass settings which set up the core structure of the project e.g. colour palette, grid, mix-ins, reset, variables. - Vendor
Files and styles specific to plugins. These will generally be the standard CSS supplied with the plugin, modified as required for the specific project.
- Base
- Partial files should be imported into your single Default.scss
- These partial files should be imported in a logical order and resemble the levels of specificity within the project e.g. base styles, then components, then regions.
.
├── CSS
| ├── Default.css
| └── Default.min.css
├── Sass
| ├── Base
| | ├── _Headings.scss
| | ├── _Links.scss
| | ├── _Lists.scss
| | ├── _Main.scss
| | └── _Paragraphs.scss
| ├── Components
| | ├── _Banner.scss
| | ├── _Content.scss
| | └── _Social.scss
| ├── Regions
| | ├── _Footer.scss
| | ├── _Header.scss
| | ├── _Main.scss
| | └── _Navigation.scss
| ├── Shared
| | ├── _Clearfix.scss
| | ├── _ColourPalette.scss
| | ├── _Grid.scss
| | ├── _MIPalette.scss
| | ├── _Reset.scss
| | └── _Settings.scss
| └── Vendor
| | └── _SyntaxHighlighting.scss
Documentation
- For key sections of your CSS file, commenting should be practised in order to increase readability.
- Base styles and components should be appropriately commented to allow for automated stylesheet generation using Hologram.
/*doc
---
title: Alert
name: alert
category: basics
---
```html_example
<div class='alert'>Hello</div>
```
*/
Reset
- Every project should begin with the use of Creative Jar’s reset stylesheet.
- Rules should only be reset to ensure consistency and with relevant styles being set e.g. bullet point lists should still have their left indent and bullets.
- To ensure easier responsive authoring and maintainability, the use of the
border-boxbox model is encouraged.
Syntax
- CSS declarations should follow the ‘semi-expanded’ format. Therefore, each selector and property within your CSS should be written on its own line.
- When grouping selectors, keep individual selectors to a single line.
- Include one space before the opening brace of declaration blocks for legibility.
- Properties should be alphabetised within their CSS declaration. This reduces the chance of redefining properties in multi-author projects.
- When declaring CSS3 properties, vendor prefixes should appear before the standardised properties, whilst remaining alphabetised.
#selector {
background: rgb(0, 0, 0) url('../Images/Bg.gif') no-repeat;
-moz-box-shadow: 0 0 10px rgba(0,0,0,.2);
-wekbit-box-shadow: 0 0 10px rgba(0,0,0,.2);
box-shadow: 0 0 10px rgba(0,0,0,.2);
color: rgb(255, 255, 255);
font: 14px Arial, sans-serif;
}
Nesting & Specificity
- The use of class names is strongly encouraged over IDs. Reserving IDs for unique instances of a module.
- CSS should not be nested according to region container locations, adding too much specificity. If you value modularity you will strive to avoid contextual styles.
- Use of descendant selectors (nesting) should only be utilised for directly related elements of a module. e.g heading within panel, list within unordered list etc.
- As a rule of thumb, it is advised not to have more than 4 levels of descendants in your selectors. This ensures that CSS remains modularised and prevents future issues with specificity. Otherwise known as the ‘The Inception Rule’.
- Use of
!importantis unnecessary, and strongly discouraged.
/* Bad CSS */
nav#primary {
ul {
li {
a {
}
ul {
li {
a {
...
}
}
}
}
}
}
/* Good CSS */
nav {
ul.primary-level {
> li {
> a {
...
}
}
}
ul.drop-down {
> li {
> a {
...
}
}
}
}
Naming Conventions
- Class names and identifiers should be lowercased and hyphenated
- Class names and identifiers should follow the SMACSS approach;
- Components are straightforward and simply be named the module/component itself
- Layout based rules should be prefixed with
l- - State based rules should be prefixed with
is-
.panel {
...
}
nav[role=navigation] ul li.is-active a {
...
}
.tabbed-content.is-active {
...
}
.l-container {
...
}
.l-col {
...
}
Variables
- Like class names, variables should be descriptive of their use and application rather than their visual style
- Variables should be lowercased and hyphenated for increased readability
- Use of variables is encouraged for recurring instances e.g. colours, fonts, grid units, image paths
- Variables should be grouped through the use of prefixing, allowing for improved code hinting e.g.
color-,font-
// Base Typography
$font-size-base: 15px;
$line-height-base: 25px;
$font-size-small: 12px;
$font-size-tiny: 10px;
// Font Stacks
$font-family-base: 'Arial', sans-serif;
// Default Spacing
$spacing-unit-base: 25px;
$spacing-unit-large: $spacing-unit-base*2;
$spacing-unit-small: $spacing-unit-base/2;
Colours
- Colours should be defined using the rgb format. This allows for easy updates to rgba colour values in the future.
- A project's colour palette should be defined via the use of Sass maps, grouping colours and tints together appropriately.
- Colours can then be referenced within your Sass using the functions outlined in this blog post.
$color-neutral-grey: rgb(53, 53, 53);
$color-brand-accent: rgb(255, 70, 0);
$palettes: (
neutral: (
base: rgb(255, 255, 255),
dark: rgb(0, 0, 0)
),
neutral-grey: (
base: $color-neutral-grey,
dark: rgb(36, 36, 36),
light: lighten($color-neutral-grey, 70%)
),
brand-accent: (
base: $color-brand-accent,
),
blue: (
base: rgb(0, 123, 145)
)
);
Units
- In majority of cases,
px(pixels) should be used as the unit of measurement e.g. module dimensions, margins, paddings and font sizes - Where required and applicable,
%(percentages) should be used for responsive requirements.
Grids
- Use of a grid system for all layout is encouraged, but only implemented through CSS without the requirement of adding class names to HTML elements.
- Susy is our preferred grid system of choice.
@import "susy";
$susy: (
columns: 12,
math: fluid,
output: float
);
.l-container {
@include container(1280px);
padding: 0 gutter(12);
}
.l-col {
padding: 0 gutter(12);
width: span(6 of 12);
}
Media queries
- Major breakpoints should be set as variables and referenced through Breakpoint.
- Initially, major breakpoints should be set for ‘small’, ‘medium’ and ‘large’ viewports (do not use terms such as mobile, tablet, desktop as there is too much fragmentation and overlap).
- Minor breakpoints should be targeted around each element where there is a break in the flow and layout. For example where the navigation breaks before the next major breakpoint. This is to ensure our code is more concise and we are only introducing breakpoints where and when they are necessary.
- Place media queries as close to their relevant rule sets whenever possible. Don't bundle them all in a separate stylesheet or at the end of the document. Doing so only makes it easier for folks to miss them in the future.
@import "breakpoint";
$breakpoint-large: 1000px;
$breakpoint-medium: 600px;
$breakpoint-small: 400px;
nav[role=navigation] ul li {
@include breakpoint($breakpoint-small) {
...
}
}
Icons
- Most interfaces require icons to be implemented. To ensure crisp edges on retina screens, flexibility and re-use, icons should be implemented via an icon font.
- If custom icons, SVG's should be created and stored within the UI/Images folder, icoMoon app should then be used to create an icon font.