Why we had to refactor our CSS for BGP

Sharlene Wong
Government Digital Services, Singapore
5 min readAug 30, 2016
Photo Credit: xmodulo.com

“Our CSS ah? CMI la…”

If you understood that smattering of Singlish, you’ll know that the CSS written for Business Grants Portal (BGP) was not in a pretty shape… and it was entirely due to our negligence!

Quick facts

Before we go on, here are some facts about our tech stack:

Problems with our CSS

From the beginning, we were never very conscientious about implementing best practices for CSS, focusing instead on perfecting the rest of our tech stack.

From the beginning, we were never very conscientious about implementing best practices for CSS, focusing instead on perfecting the rest of our tech stack.

Designers and developers would contribute towards the CSS without much communication or planning beforehand. This meant that the CSS codebase was allowed to grow organically (read: haphazardly).

One day, this happened:

dashboard.scss contains 519 lines of code, followed by 268 lines of comments

We saw that dashboard.scss, which dictates the visual style of our Dashboard, was filled with hundreds of lines of comments, which easily made up 1/3 of the file. There were also several other problems with the code:

1. Deep nesting

We had nesting up till 5 levels…

.nav-tabs.dashboard-tabs {
li {
&:hover {
a {
@include border-default;
color: desaturate($color-brand-friendly ,20%);
}
}

2. Inconsistent class namings

At the beginning of development, the team decided to use Bootstrap. Along the way, however, we found ourselves writing CSS to get around Bootstrap’s constraints and produce customized styles. These classes were appended with “bgp” in front.

However, as the demand for design customization grew, it seemed increasingly redundant to keep up with this practice. Eventually, we stopped doing that altogether, resulting in inconsistent namings for “customized” classes.

.bgp-tabcontent {
background: white;
padding: 34px 24px;
box-shadow: 0 1px 2px #aaa;
min-height: 500px;
}
.row.dashboard-button-group {
margin: 0 -10px;
}

3. Failure to exploit Sass’ capabilities where appropriate

Although we wrote in Sass, we did not enforce the use of its features as much as we should have. This was probably due to a general unfamiliarity with using Sass. In the example below, we could have used mixins over having multiple CSS classes.

Before mixin:

.dashboard-company-icon, .dashboard-apply-icon, .dashboard-smartadvisor-icon{
width: 35%;
height: 100px;
background-repeat: no-repeat ;
background-size: 75% 75%;
background-position: 50% 50%;
vertical-align: middle;
display: table-cell;
padding-left: 30px;
}
.dashboard-company-icon{ background-image: image-url('dashboard-companyicon.svg'); }
.dashboard-apply-icon{
background-image: image-url('key-grant.svg'); }
.dashboard-smartadvisor-icon{
background-image: image-url('dashboard-advisor.svg'); }

After mixin:

/* This set-image mixin is re-used 28 times to style images. */@mixin set-image($href, $width, $height, $background-size, $display-type) {
background-image: image-url($href);
background-size: $background-size;
display: $display-type;
width: $width;
height: $height;
background-repeat: no-repeat;
background-position: 50%;
vertical-align: middle;
}
/* Inside dashboard.scss: */.dashboard-company-icon {
@include set-image('dashboard-companyicon.svg', 35%, 100px, 75px 75px, table-cell);
}

.dashboard-apply-icon {
@include set-image('key-grant.svg', 35%, 100px, 75px 75px, table-cell);
}

.dashboard-smartadvisor-icon {
@include set-image('dashboard-howitworks.svg', 35%, 100px, 75px 75px, table-cell);

4. Unused classes

We always make it a habit to remove code that is no longer in use. However, we realized that there were still unused CSS classes lying around. This was because people were no longer sure about which code was still in use, and we did not have any tests set in place to alert us if the User Interface (UI) breaks due to a change in CSS.

All of these four problems spotted in dashboard.scss were also found in a good majority of our 50+ SCSS files.

CSS Statistics

After running our code through some analysis, we realized several other big-picture problems too.

CSS Specificity Graph of BGP’s CSS codebase

Our CSS specificity graph, which displays selector specificity across our project, has several troughs and peaks. However, an ideal graph would have been an upward-trending one. This means we have much room to improve in ensuring that overly specific selectors do not appear too early on.

We also noticed several other nitty-gritty issues:

  • We had 25 unique Z indicies, which ranged from 2 to 500, 000. In other words, we had no proper Z-index scale.
  • We had 21 media queries, with a few max-width properties having only 1px difference of each other. In other words, it was time that we standardize breakpoints.
  • We declared 101 unique colours in our CSS, though we are quite sure that we do not actually use all of them.

The Team

Upon discussion, we realized that many of our CSS problems arose from a general lack of communication between people (designers and developers) who touch the CSS.

Upon discussion, we realized that many of our CSS problems arose from a general lack of communication between people (designers and developers) who touch the CSS.

Thus, our UI designers and a few developers came together to form the BGP Front-end Chapter. This chapter committed to writing top quality code for the implementation of visual design, as well as bridging gaps between designers and developers.

Naturally, the first important task for this chapter was to refactor existing CSS. The chapter began to run weekly Friday morning stand-ups. We also set up a Pivotal Tracker project (our choice management tool) exclusively for CSS refactoring tasks. And got to work.

Stay tuned for more about what we did to solve our issues in the next piece: How we refactored our CSS for BGP.

--

--