Skip to main content
Warning This document has not been updated for a while now. It may be out of date.
Last updated: 23 Oct 2020

whitehall: Whitehall CSS Styleguide

To be read in conjunction with the GDS Way CSS styleguide

File structure and scope

Tech-debt creep in CSS is usually an symptom of a lack of confidence in changing or removing existing CSS. By structuring CSS in the following way, we can help reduce this risk by clearly communicating the scope of any given CSS.

The stylesheets are split between frontend and admin. The frontend ones are in a much better state and should be the way the admin ones move in the future.

They are structured to take advantage of the conditionals from the frontend_toolkit. This means you should put your IE fixes inline not in a separate file.

Within the frontend folder the basic structure of the files looks like:

./base.scss
./base-ie6.scss
./base-ie7.scss
./base-ie8.scss
./helpers/
./views/
./resets/
./styleguide/

The base.scss is the file that will be compiled with Sass. All other files should be referenced from it in the relevant sections. The IE variants (base-ie[6-8].scss which you should never need to edit as they include base.scss) enable us to use mixins which only show css to certain IE versions.

./helpers

Helpers are blocks of reusable widely-scoped sass which cannot be said to be coupled to any particular partial or template. They may style the markup generated by a rails helper, or they may be more general-purpose styles, for example the style of an out-going link.

When introducing a new helper, take care to consider exactly what it is for, how it's going to be used and if it's needed at all. Helpers can be extremely difficult to manage from a legacy point of view as they can introduce coupling between markup elements creating a kind of CSS soup where it's impossible to change anything without something else changing without there being regressions.

./views

Views are where styling for individual layouts or partials live. In general, the css for a template should live in a scss file named after that template, but scss for partials used in multiple templates should be extracted to a separate file named after that partial. SCSS rules within these view files should never affect anything other than the coupled view file.

Files should be placed and named to match the partial they are styling:

styling for /app/views/corporate_information_pages/index.html.erb should live at app/assets/stylesheets/frontend/corporate-information-pages/_index.scss styling for /app/views/shared/_featured.html.erb should live at app/assets/stylesheets/frontend/editions/_featured.scss

By storing CSS in this way, we are being clear about it's scope. When a segment of the view is removed, the relevant CSS is easy to clean up.

./resets

This contains the base html resets which remove most of the default styling a browser adds to elements. It also houses a reset to change any of the styles which have been added by static which might be flowing into the app.

./styleguide

These are a collection of Sass mixins. They shouldn't output any CSS when included and should only produce CSS when called from another file. Things should be put here and used before being standardised and moved into the frontend_toolkit.

Layouts

The frontend is built using responsive design in a mobile up fashion. That means that we define the mobile styles by default and then using a Sass mixin add on tablet or desktop styles. The whole site is also fluid so has been built using percentage widths for layout.

The frontend follows a loose grid based on a 1020px wide base with columns taking either 25% or 33.33% widths or multiples of them. They columns all have a 30px gutter between them. To achieve this we are forced to use extra spacing divs as CSS doesn't allow you to say width: 50% - 60px; without using the calc function which isn't available in most browsers.

We structure most of our pages like such:

<div class="block heading-block">
  <div class="inner-block">
    ... my heading ...
  </div>
</div>
<div class="block navigation-block">
  <div class="inner-block">
    ... my navigation ...
  </div>
</div>
<div class="block content-block">
  <div class="inner-block">
    ... my content ...
  </div>
</div>

The inner-block div has been styled globally to apply the correct amount of padding on desktop and reduce that padding for mobile. All you will need to do in your view Sass file is to define the styles of your block elements for width and float.

So to create a standard top heading with navigation taking 25% width and content floating next to it which is in a linear column on mobile you would use something like:

.navigation-block {
  @include media(tablet){
    width: 25%;
    float: left;
  }
}
.content-block {
  @include media(tablet){
    width: 75%;
    float: left;
  ]
}

Fonts

The ig-core-[0-9]{2} font mixins are deprecated. All new Sass should use the core-[0-9]{2} equivalents.

Always use the helper mixins. We don't have any generic styling for content markup, as such each view should define the font for its headings and paragraphs. Govspeak (markdown) is the exception to this where it should automatically get standard styling.

Sizings

We use a standard set of dimension variables which are defined in frontend/styleguide/_dimensions.scss. You should use them where ever possible. The idea of using standardised spacings is the whole site will look uniform and won't be pixels out here and there.

Right to left

The right to left support has been built the same way as the IE support. So that you can add styles to pages which display right to left text using the right-to-left mixin:

.my-element {
  float: left;
  @include right-to-left {
    float: right;
  }
}