How to refactor CSS
How to refactor your current (S)CSS codebase on your project safely and quickly into SPOT CSS?
You've come to the right place if:
- your (S)CSS code base has grown significantly (hundreds or thousands of lines);
- the project has grown to tens or hundreds of screens;
- the CSS code is tangled and confusing;
- bug fixes or new features break other screens (unwanted side effects);
- nobody on the team wants to take on CSS tasks, they avoid it and procrastinate;
- developers' depression has caused them to not even follow the agreed rules anymore;
- CSS development has slowed down or even stopped.
Do any of the above apply to you? It would be nice to refactor the CSS code, but you don't know how? Then you are in the right place.
This is a very detailed and illustrative step-by-step guide on how to refactor CSS code that is already very messed up. By following this procedure, you will be able to rewrite such code in a few days, and most importantly, with the confidence that you haven't broken anything.
The most important precondition: You like the SPOT CSS
This is about how to organize the CSS code as best as possible. It is based on the SPOT CSS methodology and the refactor is aimed at how to rewrite your code in the SPOT CSS framework.
Basically, it is possible to refactor and organize your code according to the SPOT CSS principles without using the framework and SASS syntax, but before that check the article Is it possible without the SPOT CSS framework?.
If you want to see a quick demonstration of the code, see the homepage slideshow A Common Component Code vs The SPOT CSS Way.
This solution is not for everyone and for every type of project. So check if it is for you. The following conditions have to be met:
- love SPOT CSS - you want to rewrite your code into SPOT CSS (and SASS syntax);
- component based - your CSS code is component based / BEM approach (or at least tried to, but some exceptions are acceptable);
- no utility classes only - you don't use the utility class approach like tailwind (only sometimes/somewhere for some edge cases);
- any CSS preprocessor - if your code is SCSS (or LESS) with nesting that's great, but also pure CSS is possible;
What does this refactor solve
The approach presented here does not solve all the problematic aspects of CSS.
It will help with:
- unmaintainable code - when your code has gotten into an unmaintainable state over time, it is hard to navigate it, the development of visual things goes slowly or almost stopped;
- unexpected side effects - when fixing bugs creates unwanted side effects and new bugs in other places and other screens that we are not looking at and therefore it is impossible to predict the result of new modifications;
- inconsistency - rules in file structure, naming conventions, order in files and components are not unified or respected, each team member does it his own way and therefore the situation only gets worse over time;
- team morale - nobody wants to touch the CSS code anymore, because it is difficult to understand and very risky to make changes to it, the project becomes a burden and working on it stops being fun.
It solves these problems with a unique approach:
The resulting CSS OUTPUT is not changed!
This is totally in line with the well-known definition of refactoring:
Refactoring is ... the process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal structure. ---Martin Fowler
With this approach to refactoring, we only change the internal structure (the SCSS or LESS source files), but the CSS output will be preserved.
Refactoring to SPOT CSS in this way will benefit you in many ways and I'll mention a few things here to encourage you:
Benefits that will convince you to start refactoring - it's fast, it can be done in increments, it's safe, you can do a quick try out, you can outsource it, and other (see more details);
Benefits during refactoring - no time pressure, selectors are not changed, no new CSS needs to be written, easy to verify, you can measure progress, and it's the most satisfying feeling (see more details);
Benefits after refactoring - you would have project standard, faster development, linter out of the box, well-documented components, increased the readability for newcomers, boosted usability of components, and especially the joy of developers, and more (see more details).
further refactor and optimization - after you complete this refactor procedure and clean up the code you can more easily identify remaining problems and make further optimizations easier (see next section What is not solved here).
Step 1: First component
As a first step I would strongly recommend to try to refactor one component for a test. Don't choose the smallest component with 5 lines, or a very complicated one (typically a button). Choose something medium, up to 200 lines, a component with some sub-elements and some variants (mutations).
This way you will be able to see what the work of such a refactor is, how the result will look like, consider whether it is worth it and ideally present it to the team (see Step 2: Convince the team).
Estimated time: It would take an experienced person up to an hour, but you'd be safer with 3 hours.
So let's get to it:
- create a new GIT branch or backup/make a copy of your current project;
- install the SPOT CSS framework with NPM or Yarn;
- choose a medium size component up to 200 lines, a component with some sub-elements and some mutations;
- measure your time - the start is slower, with time you will surely get into it and you will be a lot faster, but it is not bad to measure the time and estimate the rest of the whole project now;
- rewrite the choosen component into the SPOT CSS (see Step 4: Single component refactor);
- assess the time and result - Do you find the result easier to understand than the code before? Did you have to move some CSS code to this component from other components? Was there any code that didn't belong to this component, but was just the context of another component? Do you find it useful to have a component documented like this in the registry section? Do you find the time spent on the refactor acceptable? Would you like to have the whole CSS codebase cleaned up like this?
- If the answer to most of the questions is yes, then continue to the next step.
- If you had a problem doing it yourself, or it was slow and you don't have the time, but you would like to refactor the CSS code on your project, see the last section Outsource it!.
- If anything else and you would like to ask a question, let me know on our Discord - Johnny Seyd (@Seyd#6245).
Step 2: Convince the team
TODO until August 29, 2023
- Discuss first with the team How to convince the team to use SPOT CSS
Step 3: Preparation
TODO until August 29, 2023
- plan - at once or by increments
- save the output of CSS (is it only one single file?)
- how many lines of css are in my project?
- Angular problem - to use both SCSS and SASS syntax at once
Step 4: Single component refactor
TODO until August 29, 2023
get familiar with all kinds of mutations
you can use Cheat Sheet
if it is your first testing component, go back to Step 1
Step 5: Measure
For each refactored component, write down which component, how many lines the source code had before the refactor and how long it took.
If there was something exceptionally problematic, or you got stuck on something, but next time you will know better, write that down too and try to estimate how long it would have taken without the stuck next time.
Calculate or estimate, based on the number of lines of components already refactored and the total number of lines of all components, what stage of the refactor you are in (in %).
And from the measured times and the remaining number of rows, try to estimate the remaining time. Or combine this with another estimate - the remaining percent of the rebuild vs how long the previous rebuild took (measured time).
Step 6: Repeat step 4 and 5 for all components
If you didn't choose the "increment" tactic, which means rebuild component by component one by one, then repeat steps 4 and 5 for the next component until you have refactored all of them.
Step 7: The rest...
Not every style and (S)CSS code is assignable to a component. SPOT CSS specifies only how to structure the CSS code of components. It does not address anything else. You don't even have to have the other code in SASS syntax, but you can have SCSS if it suits you better.
Exceptions are for example:
- CSS reset styles
- imported fonts
- html and body elements
- global simple HTML elements
- @mixins, @functions and $variables
- global CSS variables
- CSS animations
- utility classes
- 3rd party stylesheets
So don't try to write everything in SPOT CSS. Always think if the given CSS code belongs to some component. And if not, don't force it in SPOT CSS. Just leave it as it is.
Step 8: Testing
check the CSS output - whether the size has changed compared to the original one, or throw it into some visual diff tool, although it should be taken into account that the order of some selectors may have changed.
manual visual test - in some cases it can happen that if the style is not written in such a way that the selectors address only a specific element of the component, changing the order of the selectors (even if the order of selectors within a specific element will not change) can cause an unwanted change. Run the project with the original style in one browser tab, and the refactored project in the other browser tab. Then navigate through the application and switch back and forth between the tabs. Use the Page Up/Down keys to scroll to exactly the same position in both windows. If you see any visual difference, investigate the reason and fix the problem.
visual regression testing - If you have implemented automated visual testing, you are lucky. Then the refactor should simply not cause any change and if it does, you have made a mistake somewhere and you need to fix it.
other automated tools - we are currently inventing and working on tools that will help to control changes in CSS output and visual deviations. But it's not ready yet and so we can't share it yet. But soon...
Step 9: Cleaning up
Before you are done, you have to clean up a bit:
delete all the old (S)CSS files - we haven't deleted them yet for verification reasons;
check for completeness - after deleting the overwritten component files, check what S(CSS) subfiles are left in the project and whether some of them should have been refactored as well;
check uniform formatting - click/scroll through all components and check the header, if there are properly documented recommendations and other notes to the component, forgotten notes, commented blocks, TODO comments, empty lines, indentations, etc;
Step 10: Create pull request
The first thing to do is to check if there have been any changes in (S)CSS in the project in the meantime.
1.1. A very straightforward approach is to look at what commit the refactor was based on and what commits have been added in the meantime and whether they changed the S(CSS).
1.2. If there are changes, implement them in the refactored SASS files as well.
If we are up-to-date with
masterbranch (or your main dev branch), you can create a GIT pull request.
After the pull request has been approved, it may happen that someone has changed the (S)CSS code in the meantime and it is necessary to repeat the procedure from point 1.
Notify the team that you are going to merge SPOT CSS refactored code.
Successful merge to the
masterbranch (or your main dev branch).
The refactor is done!
We all know that stakeholders don't want to hear that a team stops working on a product because something needs to be refactored. That something will change internally, but nothing externally, it will just be better - for us programmers, because we will be more efficient. It's just going to take time, it's going to cost a bit and, most importantly, nothing else will be done until then.
That's why this way of refactoring CSS is unique. You dont'have to do it by yourself. We can do it instead of you.
We've done this many times before, we have the experience, the know-how and we're probably faster than you.
You can have it done in a few days (on average 10-15 MDs on a larger project), it's a one-time delivery, safe because the CSS output remains unchanged (and it can be verified), parallel to your development, and it has a good price/impact ratio.
If you are interested in more, please contact us via this form and we will get back to you: https://form.jotform.com/231643839866066
Don't hesitate to ask
If you have any questions, don't hesitate to ask us on Discord (see below).
If you have a different opinion, if you disagree with something, or if I made a mistake somewhere, or if I don't see something according to you, let me know on our Discord - Johnny Seyd (@Seyd#6245).