Going Dark: Generating Clarity’s Dark Theme
The Clarity team members sometimes joke that they are “going dark” when they need a block of time to work without interruption. Going dark is more than than just ignoring other priorities for a short block of time. It’s using that block of time to put one’s focus on a single task and making progress. Whether fixing a bug or adding a feature, at the end of the dark session the goal is to deliver output that enhances Clarity in a specific way. The work that went into modifying Clarity to support themes was similar to ‘going dark’ in that there were several areas that needed to be focus at different times.
Here, I’m going to talk about what went into implementing the new themes feature as well as show an example of the two themes now shipping with Clarity. A dark theme is often used in content sparse yet interactive environments where limiting eye strain for the user helps them focus on their work. Because of Clarity’s enterprise focus, the dark theme has been one of our top feature requests since we began. However, it was difficult to do efficiently, even for those of us familiar with the SCSS codebase. Because it’s natural that designers and developers need to be able to customize the look-and-feel of their application we also focused on removing the barriers that made it difficult to overwrite the Clarity components with custom theme colors.
When I set out to implement theming I had three goals:
- Improve the developer experience for creating a custom theme.
- Centralize Clarity component SCSS variables in an easy to use and accessible way.
- Generate a (dark) theme that can be used as a reference for anyone who wants to customize the look-n-feel of their application.
Prior to building the dark theme, the extent of my theming experience involved overriding bootstrap-sass variables in AngularJS applications. I took a bit of time and looked into some of the other UI libraries that already offered theming to make sure that the approach I had in mind, overriding SCSS variables, was viable for us and Clarity consumers. I wanted to make sure that this approach was:
- not a one-off solution that I had only seen with Bootstrap
- something that would be familiar to front end engineers even if they were not familiar with Angular
As I poked around a few UI library projects, it became clear that using variables and overriding them is a popular solution many UI libraries use today. The variables they provide are often colors which allows for changes of common attributes to be distributed across different components. Things like text color, border color, background color, overlays, popover windows and modal dialogs - all need to be customizable in order for consumers to create a custom theme. Once, I felt comfortable with the approach, it was time to answer the question:
“How can I turn the original Clarity component SCSS into little pieces of themeable joy so that anyone armed with modern SCSS knowledge can easily jump in and start theming their Clarity application?”
Reuse -> Reduce -> Recycle
Product managers do not seem fond of the word “refactor” so I won’t say that I refactored anything in the Clarity SCSS codebase. Even though Clarity has only been open source for a year, there were CSS styles from the early days that did not follow our current best practices. This meant I would have to make some complicated changes in order to maintain backwards compatibility for the folks who were already using Clarity in their applications.
Instead of refactoring, I took the approach of looking at what we had and reusing it where I could (maps & functions). Reducing the top level `SCSS` imports so that it was easy to start at the top of our SCSS file organization and work your way down into the nitty gritty implementation details if you chose to follow that path. And finally, I recycled things where it made sense to use common values of different variables into one variable that could be used as a pointer to different components.
Here are a few examples.
One of the things that had to change was the organization of our top-level SCSS files, reducing the number of imports at the top of the pyramid. The original theme, which we refer to as the Light Theme, had a many imports in the top-level file used to build the clarity-ui.css output Clarity UI. In order to reduce these, I had to reorganize the files and create structure underneath the dependencies. This included pulling variables out of component files so that they could be aggregated into a single variable file. Later, this enabled me to override just the variables I needed for the dark theme.
Maps & Functions
For a couple of our components, we use maps to generate CSS during compile time. I have mixed feelings about this approach. On one hand, it shortens the amount of SCSS you have to write and maintain. But it also obfuscates the codebase, making it harder to debug issues and understand how things are put together.
Once I started wrapping my thinking around how we were using these maps to generate CSS I was able to figure out how to consolidate and reuse our maps in a way that made them easy to override.
Recycle & Save
As I went through our `SCSS files I saw a few things that were used across multiple components. Where it made sense I consolidated them into a single global variable that could easily be reused for parts of the dark theme.
Rectify (/ˈrektəˌfī/ — put (something) right; correct.)
There are still some areas that need to be better. One area that can improve is recycling more variables so that there are fewer of them to overwrite when customizing a theme. Another is that we don’t have a standard way of implementing and using our color palette that is easy for our consumers. Some components make heavy use of this approach and others do not. Since the main deliverable for me was the dark theme, I ended up not spending as much time reducing variables and maps as I would have liked.
Put (somethings) Right
- While Clarity still supports IE11, that won’t always be the case. The future of CSS is coming soon and it will bring CSS variables (a.k.a. custom properties) with it. Once we can take advantage of those, we open up more possibilities for dynamic theming of Clarity components.
- I’d also like to add a few more prebuilt themes for Clarity but building them in an accessible way takes time. This scope of work was focused on solidifying our foundation for the future and building the dark theme on top of it.
- I would like to build a sample application that uses both the dark and light theme, allowing the user to toggle style sheets for their preference.
- We recently switched our build over to webpack. The current implementation could be improved to make for a better developer experience when working on Clarity components.
So what does it look like?
Another good example that shows how important good use of color is are the Alerts. There are four standard alerts and three app level alerts. Besides the background color you can see that there are subtle differences in the status types that complement the dark or light tones in the background. These colors were chosen first to communicate the the meaning of the alert and second to be accessible. I think they look pretty good and it re-enforces the importance of working collaboratively with someone well versed in design.
You can also see the effect a dark background color has on the components. It accentuates the bright, full toned colors of the app alerts and mutes the earthier tones above in the standard alerts. To me its what allows the font color to work well in both cases. Accomplishing this wasn’t as simple as flipping all of the colors to an inverse value.
In order to keep things clear and accessible many of the color changes had to be researched and verified during the design and development iteration cycles that themes went through. If you are interested seeing the differences between light and dark themes for all of the clarity components you can compare the light and dark demo apps that have all the clarity components with various features declared on them.
We are excited to add a dark theme to Clarity. You can get started with it on the new documentation page here. If your application has a need for the dark theme, we hope you find it useful. If not, we hope the ability to create a custom theme helps you realize your product brand using Clarity in such a way that you can make your application your own.