• Stars
    star
    278
  • Rank 148,454 (Top 3 %)
  • Language
    JavaScript
  • License
    BSD 3-Clause "New...
  • Created about 8 years ago
  • Updated about 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Believe in Better CSS

Sky CSS Style Guide

Believe in Better CSS

An Evolving CSS / Sass Style Guide for Sky

Contents

Writing CSS / Sass

Linter


Writing CSS / Sass

Template

Before diving into the details of CSS coding style, you can find a Sky-conformant .scss template over at git.io/template.

Instantly get started with:

curl -L git.io/template -o _<your-file-name>.scss

Back to contents

Architecture

Project stylesheets should be structured following closely to the principles of ITCSS, imported in the following order for greater control over re-usability and specificity:

  1. Settings - Global configuration and variables.
  2. Tools - Mixins and functions.
  3. Generic - High-level styles such as resets and normalize.css.
  4. Elements - Base HTML styling.
  5. Objects - Common non-cosmetic structural design patterns.
  6. Components - Specific cosmetic elements of UI.
  7. Trumps Utilities - Helpers and overrides.

Back to contents

Formatting

  • Use soft tabs (2 spaces) for indentation.
  • Use lower-case hyphenated naming over camelCase.
  • Put a space before an opening bracket { and a new line after.
  • Put a new line before and after a closing bracket }.
  • Put a space after, but not before, a colon :.
  • Put a new line after a semi-colon ;, with no space before.
  • Don't leave more than 1 line empty.
  • Use // comment commenting for non-outputted SCSS (e.g. settings, functions).
  • Use /* comment */ commenting for all other SCSS
    • Outputted comments are useful for debugging, and can always be removed later in production using various build tools.
  • Leave an empty line at the end of a file.
  • Use leading zeros for decimal values (e.g. 0.5 instead of .5) for better readability.
  • Don't specify units for zero values (e.g. 0 instead of 0px).

Back to contents

Selectors and Naming

It's important we keep code transparent and self-documented when it comes to naming our selectors.

Don't

  • Don't use html tags in selectors.
  • Don't use IDs (#) in selectors.
  • Don't unnecessarily nest selectors.
    • Try to keep selectors flat, at the same level of specificity.
    • Avoid going more than 2 levels deep.

Do

  • Do use classes.

Back to contents

BEM

Block, Element, Modifier

BEM is naming convention that aims to improve readability and re-usability.

All CSS class names should follow the BEM pattern.

Block

A block represents an independent component and should specifically describe its purpose.

<div class="block"></div>

For more detail on BEM blocks, visit bem.info.

Element

Elements represent parts of a block and cannot be used separately, they have no standalone meaning.

An element should be named to describe its purpose, prefixed with a double underscore __ to separate from the block.

<div class="block">
  <div class="block__element">
  </div>
</div>

In your stylesheet this would look like:

.block {
  /* block styles here */
}

.block__element {
  /* element styles here */
}

Avoid using the SCSS ampersand shortcut (&__) when defining elements, it'll make searching your codebase a lot less productive.

⚠️ Don't create elements inside elements (e.g. .block__element__element). Consider creating a new block for the parent element instead.

For more detail on BEM elements, visit bem.info.

Modifier

Modifiers define a change in cosmetics, used alongside a block or element.

Changes in a state shouldn't be dictated by modifiers, and are handled slightly differently.

A modifier should be named to describe its purpose, prefixed with a double hyphen -- to separate from the block or element.

<div class="block block--modifier">
  <div class="block__element">
  </div>
</div>

and / or

<div class="block">
  <div class="block__element block__element--modifier">
  </div>
</div>

In your stylesheet this would look like:

.block {
  /* block styles here */
}

.block--modifier {
  /* modifier styles here */
}

Avoid using the SCSS ampersand shortcut (&--) when defining elements, it'll make searching your codebase a lot less productive.

For more detail on BEM modifiers, visit bem.info.

States

  • is-
  • has-

State prefixes signify that the piece of UI in question is currently styled a certain way because of a state or condition. It tells us that the DOM currently has a temporary, optional, or short-lived style applied to it due to a certain state being invoked.

<div class="c-example is-active"></div>

or

<div class="c-example">
  <div class="c-example__element is-active">
  </div>
</div>

Namespacing

Following a prefix convention provides better insight into a class' purpose for other developers to work with.

  • o- signifies that this class is an Object, and that it may be used in any number of unrelated contexts to the one you can currently see it in. ⚠️ Making modifications to these types of class could potentially have knock-on effects in a lot of other unrelated places.
  • c- signifies that this class is a Component. This is a concrete, implementation-specific piece of UI. All of the changes you make to its styles should be detectable in the context you're currently looking at. Modifying on top of these styles should be safe and have no side effects.
  • u- signifies that this class is a Utility class. It has a very specific role (often providing only one declaration) and should not be bound onto or changed. It can be reused and is not tied to any specific piece of UI. You will probably recognise this namespace from libraries and methodologies like SUIT.
  • t- signifies that a class is responsible for adding a Theme to a view. It lets us know that UI Components' current cosmetic appearance may be due to the presence of a theme.
  • js- signifies that this piece of the DOM has some behaviour acting upon it, and that JavaScript binds onto it to provide that behaviour. If you're not a developer working with JavaScript, leave these well alone.
  • qa- signifies that a QA or Test Engineering team is running an automated UI test which needs to find or bind onto these parts of the DOM. Like the JavaScript namespace, this reserves hooks in the DOM for non-CSS purposes.

Back to contents

Properties

Properties should be ordered in the following manner (a style similar to Dropbox) to promote readability:

  1. @include - use your previously-defined mixins right at the start for ease of modification and readability.
  2. Structure - display, position, margin, padding, width, height, box-sizing, overflow etc.
  3. Typography - font-*, line-height, text-*, letter-spacing etc.
  4. Cosmetic - color, background-*, border-*, animation, transition etc.
  5. Native interaction - appearance, cursor, user-select, pointer-events etc.
  6. Pseudo-elements - ::before, ::after etc.
  7. Nested elements
  8. Pseudo-classes - :hover, :focus, :active etc.
  9. @media - media queries should be defined last for ease of modification and readability.

Defining separately:

  1. State classes
  2. Modifier classes
Example
.c-example {
  @include example-mixin();
  padding: 20px;
  position: relative;
  font-size: 1.25em;
  color: black;
  border: solid 1px grey;
  transition: border 1s ease;

  &:focus,
  &:hover {
    text-decoration: underline;
    border: solid 1px black;
  }

  @media(min-width: 721px) {
    font-size: 1em;
  }
}

.c-example__heading {
  text-transform: uppercase;
}

/* States
  =========================================== */

.c-example.is-active {
  border: solid 1px blue;
}

/* Modifiers
  =========================================== */

.c-example--large {
  font-size: 2.5em;
}

Back to contents

Extending and Modifying

⚠️ Never use @extend.

Extending styles isn't flexible and leads to bloated stylesheets. When re-building common styles, @mixins are always a more powerful and stable approach.

⚠️ Never directly overwrite a previously defined class.

Avoid the confusion of selectors being defined in multiple places by using a new BEM --modifier class.

/* .c-example is a component defined earlier in the project */

/* Don't overwrite the class */
.c-example {
  color: red;
}

/* Do create a new `--modifier` class */
.c-example--error {
  color: red;
}

Back to contents

Specificity

By following the steps above (specifically by using classes and limited nesting) conflicts with specificity shouldn't be a problem.

⚠️ Never use !important

If you're struggling to override styles, battling specificity, the safest option is to chain the selector to itself. In SCSS we can achieve this by:

/**
 * Doubling up a selector's specificity in SCSS.
 *
 * 1. Outputs as `.c-example.c-example`
 *
 */

.c-example {
  color: #4a4a4a;

  &#{&} { /* [1] */
    text-decoration: none;
  }
}

Back to contents

Resources

Reference

Guides

Organisation Style Guides

Back to contents


Linter

Installation

Our CSS linter runs on Stylelint, you can install the configuration by running:

$ npm install stylelint-config-sky-uk --save

After installing, create/amend your .stylelintrc to extend the config:

{
  "extends": "stylelint-config-sky-uk"
}

Usage

Run the following command to lint all .scss files in your project directory.:

$ stylelint '**/*.scss' --syntax scss

To ignore dependency folders such as node_modules, you'll need to create a .stylelintignore file or use --ignore-path in the CLI.

Versioning

The CSS Style Guide follows Semantic Versioning to help manage the impact of releasing new library versions.

Maintainers

The CSS Style Guide is maintained by the Toolkit Champions.

More Repositories

1

gradle-maven-plugin

Gradle 5.x Maven Publish Plugin to deploy artifacts
131
star
2

anticipy

A Python library for time series forecasting
Python
82
star
3

ReactiveAPI

Write clean, concise and declarative network code relying on URLSession, with the power of RxSwift. Inspired by Retrofit.
Swift
79
star
4

feed

Nginx based Kubernetes ingress controller for AWS
Go
58
star
5

osprey

Kubernetes OIDC CLI login
Go
51
star
6

cqlmigrate

Cassandra schema migration library
Java
46
star
7

api-explorer

API Explorer is a live documentation client for Swagger/OpenAPI Specification
JavaScript
44
star
8

kafka-configurator

Kafka Topic Configurator
Scala
32
star
9

kafka-message-scheduler

Scheduler for low-frequency and long-term scheduling of delayed messages to Kafka topics.
Scala
32
star
10

mite

Mite - A Python Performance Testing Framework
Python
25
star
11

bslint

A linter for the BrightScript language.
Python
24
star
12

terraform-provider-nsx

A Terraform provider for VMware NSX.
Go
20
star
13

ruby-bootcamp

Ruby
18
star
14

nemo

Rendering form elements and validating user input. It supports a modified version of the siren data structure to dynamically construct the form.
JavaScript
18
star
15

docker-registry-exporter

Prometheus exporter for docker registry
Python
17
star
16

client-lib-ios-test-foundation

Sky Italia Test Foundation Framework for iOS
Swift
17
star
17

merlin

Distributed IPVS Loadbalancer
Go
16
star
18

terraform-provider-infoblox

Terraform Infoblox provider
Go
15
star
19

clusterverse

Full-lifecycle cloud infrastructure cluster management, using Ansible
Groovy
15
star
20

kfp-operator

Go
15
star
21

architecting-css

Examples as part of my Architecting CSS presentation for Online Services
CSS
14
star
22

supercell

Grid-like Layout System
CSS
14
star
23

vergo

Go
12
star
24

vagrant-vrealize

VRealize provider plugin for Vagrant
Ruby
10
star
25

what-bump

Detect required version bump based on conventional commit messages
Rust
10
star
26

terraform-provider-vrealize

Terraform vRealize provider
Go
9
star
27

etcd-bootstrap

bootstrap etcd nodes in the cloud
Go
8
star
28

cezanne

Visual regression testing tool
Ruby
7
star
29

android-tdd-introduction

Java
7
star
30

govrealize

A Go library for interacting with vRealize Automation 6.2 REST API
Go
6
star
31

gonsx

Go library for VMware vSphere NSX API
Go
6
star
32

csp-tech-radar

The Sky Plc Content Supply Platforms department technology radar.
6
star
33

terraform-provider-pulsevtm

Terraform PulseVTM provider
Go
5
star
34

go-pulse-vtm

Go Bindings for Pulse Secure Virtual Traffic Manager
Go
5
star
35

licence-compliance-checker

Validate project dependencies licence compliance
Go
4
star
36

kafka-topic-loader

Reads the contents of provided Kafka topics
Scala
4
star
37

q-go-assessment

Assessment Project for QGo Desktop Team
JavaScript
4
star
38

front-end

A forum for best practice of Front End Development within Sky.
3
star
39

cleanup-docker-registry

Shell
2
star
40

droidcon-streaming-app

Sample code from #DroidconUK15 presentation by Andrew Jack
Java
2
star
41

fs2-kafka-topic-loader

Reads the contents of provided Kafka topics
Scala
2
star
42

skyinfoblox

Go library for the Infoblox appliance
Go
2
star
43

scio-tests

Scala
1
star
44

go-rest-api

A fairly generic HTTP API
Go
1
star
45

fluentd-docker

Fluentd docker image with plugins : prometheus, rewrite-tag and elasticsearch
Go
1
star