CSS refactoring with Wraith
Whilst this site started out as a simple blog layout it has grown with new sections being added and I use it to experiment and develop new techniques. Without a defined structure the CSS had become difficult to extend and maintain so it needed refactoring.
As the purpose of the refactor was to improve the code structure rather than add new functionality the appearance of the site shouldn't change. This being the case I decided to use the BBC's visual diffing tool Wraith[other visual diffing tools are available], which will highlight if something had been incorrectly refactored.
Using Wraith
I'm not going to cover setting up Wraith here, it's well documented on their site and it took me about half an hour to go from scratch to a fully configured install. One word of caution: it's a command line utility with a few dependencies so if you're not comfortable with that kind of thing it could take you a lot longer and be very frustrating. I'm used to dealing with this kind of thing and still wouldn't describe it as "easy".
In order for Wraith to have something to compare it needs two instances of the pages you are working on. One of these will be your local development server and, whilst you could use the production site for the other, it's better to run a second local development server that is running the same code as production. In my case I ran a version of the server from master - which is what production follows - and, from another working directory, I ran a second server on another port from the CSS refactor feature branch. Aside from the speed benefits of running both instances on your local machine there is the additional benefit that they can share the same content store which will mean that the only differences Wraith will highlight are due to code changes, not content differences.
With everything in place to start using Wraith you will need to add a representative set of pages to the config in order to test them. The pages you choose will depend on the scope of your refactor but it's worth identifying them before you start. Once you have your pages configured you can then run Wraith to generate a set of visual diffs. It also produces a web page that shows thumbnails of all the pages at each width with their diffs and a percentage difference which is very useful for quickly identifying where to focus your attention.
As it has to render two pages using a headless browser, generate screen shots and and then run a visual comparison, Wraith can take some time to complete for a large set of pages. Before you start you should run a full diff of all your reference pages to ensure there are no differences at this stage and you are starting from a clean base line. As you're working it's a good idea to comment out pages from the config to focus on what you need without having to wait too long before getting feedback.
Refactor the code
Before changing anything we run a diff to make sure we are working from a clean baseline.
We then make changes to our code and run another diff. In this case we can see from the areas that Wraith has highlighted in blue that something we've done has changed the vertical spacing of the list items.
If we look at the diff of another page that also has a list on it we can see that the page is the same up to the point where we have a list but then we start to get differences so this looks like it might be an issue affecting all lists.
Going back to revisit our changes we identify what's caused the change and correct it before running another diff. If we've got things right, this time we will be rewarded with a clean diff.
In this case it was an issue with a mixin that was being used by both of these list classes so being able to see it affecting different lists made it trivial to track down.
By rinsing and repeating this process we can work through and complete our refactor leaving us with CSS that's much better structured but keeping the same visual appearance.
Dynamic functionality
As Wraith takes static screen shots after the page has loaded it's not suitable for testing dynamic functionality.
If you are using data selectors as hooks for your JavaScript then changing classes for CSS should minimise the effect of this kind of refactor. In fact this is a perfect example of the main advantage of that technique.
If your functionality uses CSS to control display - and it's usually a good idea if it does - then you'll need to find another way to test this. As I have limited dynamic functionality on this site (and this is by design) I was able to it this manually.
However, if you do have more dynamic functionality then some form of automated browser driven testing, such as Selenium, would allow you to check that it still functions as required.
Conclusion
When working on CSS it can be difficult to spot visual regressions, especially over a number of layouts and breakpoints. Using a visual diffing tool such as Wraith can cover this range and efficiently highlight areas that need attention.
See also follow up article dealing with cross platform issues.