I spoke at SYDCSS in October on why Change is Good, Even if the Outcome Isn’t, where I had a blast. With the talk seeming to resonate with a larger-than-expected percentage of the audience, I’d like to go into more detail about the process, not the outcome.
We make it no secret that CSS is a struggle. Like many other teams, we’ve faced a few hurdles in making our environment more manageable. We’ve changed a lot over the last year, and we’re at a better place for it. Here’s how we’re still happy, even after mistakes:
Every developer knows they work in a field that is constantly changing. It seems every day we’re faced with a new (and “better”!) way to tackle development. Resisting something new and shiny is hard; everyone is talking about it and it ticks all the boxes. You don’t want to get stale, you want to keep your team fresh, so why shouldn’t you adopt this new method?
I don’t like that change. Even though it might seem better, it’s largely unwarranted and pretty difficult to justify if something goes wrong. It’s difficult for me to reason with anyone who wants to change our process, tools or frameworks just because they’re becoming popular or it’s a new idea that sounds cool. However, The good change isn’t perfect either, it can be a change for the worse.
There were three clear issues we had to find solutions for. We’d had random
segmentation fault fault issues with libsass, so that was the first thing we needed to focus on removing. We also wanted something more modular (the why) and we needed a better system for variables.
Without a doubt, Sass is a great tool and I’m not here to convince you not to use it. Sass just wasn’t the right fit for us. Ignoring the segmentation fault problems, it’s is just too powerful for what we needed. Giving the team so much power often ended in abuse. I found myself abusing built in color modifiers, mixins and functions because I was lazy. This was happening to others in the team too – sure, we could put the hammer down and say “don’t use this feature”, but I was far more comfortable with removing the temptation.
Looking at our options, as a team, anyone that was affected had input on a favored direction. It was my decision, after a few discussions, to try POSTCSS. The plan was to use enough plugins so we only had to change out existing Sass syntax a little. That way we’d have a similar environment, intending to have ‘scss’ without libsass. After this had been merged, then we would remove the plugins one by one, cleaning up syntax and structure.
I’m very honest about this part of the process whenever it comes up. If you’re changing process and it doesn’t work out, you have to take responsibility. When I put up the pull request, it had been around two weeks work. Not a few hours a day, but eight hours a day, every day for just over ten days.
A sunk cost fallacy is often referred to as a sunk cost effect; which is wrong it’s not an effect, it’s a fallacy, a mistake. You’ve sunk so much time into a feature, or in this case, a change, that it’s ‘silly’ to throw it all away. That’s so far from the truth, and ‘silly’ is faulty reasoning. I could of been selfish and told the team that I’m not wasting two weeks worth of work (how it became such a mass of work without another perspective is a different blog post). In the future, it’s easy to see this two weeks worth of work probably would have cost the team a whole lot more.
The POSTCSS solution was peculiar and I look back on it with such clarity. It’s easy to be embarrassed that it was even suggested, let alone implemented. That’s a tough thing to deal with, especially in a company full of people you respect and look up to. Once you learn that your team appreciates honesty and transparency you learn to be more confident in yourself.
Technically, what I’d done with POSTCSS was a mess. It was difficult to see what I’d changed – the ‘similar environment’ had required some wrangling. We had to use too many plugins. Color functions weren’t the same (in naming or functionality) and mixins flowed differently. Eventually that pull request was rightly closed, and it was back to the drawing board.
The idea of inlining your CSS in each component had been gaining popularity. Just because it was popular didn’t mean it was a good idea – however as a team we spoke about it and it seemed a fitting solution. After spending two weeks learning our Sass structure like the back of my hand (silver lining!), I was apprehensive to implement something like Radium. I didn’t want something I hadn’t used thoroughly in the pipeline, only to potentially become another Sass. So I suggested let’s just use plain old inline styles, and then we can add features as we need them.
Around this time, I’d noticed the curse of the Sass segmentation fault had been lifted. We hadn’t seen it on any of our machines in a few weeks – so that eased the pressure of ‘remove libsass now!’. We were still focused, though, and it was time to convert a few components to inline CSS. The conversion process was relatively simple, but after I’d done one component I realised I needed to let the team know this process was not going to be pretty.
Simplicity is both the blessing and curse of standard inline CSS. We didn’t have a variable system outside of Sass – I simply hard coded all of our color values with the argument: if it works for a few components, we’ll look at a variable structure later. Being ignorant was bliss, for a while. I even ripped Radiums :hover concept to style the pseudo event because I was still on the fence about implementing the entirety of Radium.
The truth is, even after all I had researched, I didn’t like inline CSS. It required Radium (or similar) to be functional, the syntax was worse than reading terribly nested SASS and it was hard to trace in the browser. It was modular, but not the modular I was expecting. I’m not sure if we’ve faced the ‘too modular’ thought yet, but it was weird to compose (think
@extend) styles. You’re allowed to be opinionated – I didn’t like inline styles, but there I could justify myself. The results of our exploration into inline CSS still exists in our application, and that’s okay.
Breaking news to the team that this foray was another solution that didn’t work was hard. I didn’t go into the discussions empty handed, though. Talking to your team about why this didn’t work is more important than talking about wasted time. Offering another solution is also important, so I spoke with Nathan about what we were going to do next, and then had a chat to the team about our current position.
That’s where we are today. We’ve begun implementing css-modules across our repositories and so far, so good. We’ve had to take a closer look at things like variables and theming. We have a mix of SASS, inline CSS and CSS Modules. The team is working towards making everything utilise CSS Modules as soon as we can, but it involves work and lots of understanding from everyone involved.
As a leader, you have to realise that everyone in your team has the same intentions as you. I didn’t set out to burn through a few weeks with no merged outcome. I planned to create a better environment. It didn’t work out the first two times, but everyone around me understood that it’s not a deliberate act.
Failures have been errors of judgment, not of intent. – Ulysses S. Grant
Your team trusts you, but remember, no one is perfect. Your team doesn’t expect you to get everything correct all of the time, to make the best decisions. They know you’ll get it wrong, they get it wrong themselves. It doesn’t matter how switched on you are, how much research you’ve made or how much you’ve spoken about your plans. When you make your mistakes, be open and upfront. Your mistakes will make you a better developer and your team more productive.