<color name="grey">#666666</color>
<color name="lightGrey">#999999</color>
<color name="tooManyShadesOfGrey">#9F9F9F</color>
<color name="seriouslyTooManyGreys">#AFAFAF</color>
<color name="lighterGrey">#CCCCCC</color>
<color name="lightestGrey">#EBEBEB</color>
<color name="darkestGrey">#1A1A1A</color>
<color name="notTheDarkestButCloseGrey">#262626</color>
<color name="darkerGrey">#333333</color>
<color name="darkGrey">#4A4D4E</color>
Sequence of greys with increasingly desperate names

Resource Smells

This small snippet was taken from a project I have seen recently, and no, it is not contrived in any way. The colour resource file in question contained between 20-30 colours in the white to black range. When adding the primary, secondary and tertiary colours for the app it reached 40-50 colours. Most brands, with just a cursory look, have between 5 to 15 colours for their entire palette. If we were to be generous and take into account an additional 10-15 for errors and the typical range of blacks and whites, we still don’t reach our 40-50. More than likely this explosion of colours can be attributed to a lack of pairing between design and engineering. This lack likely meant that any original colour palette was not reflected in the application, this then had the knock on effect of not influencing the styles or components created in the application. Finally, resulting in the infinite colour variations you can see above. Being aware of this scale up of colours can help prevent this happening and encourages you to keep your design and implementation clean and usable, in such a way that you can iterate quickly and apply changes more easily.

Not leveraging theme attributes enough is the main culprit with rapidly expanding colour resources. Theme attributes allow developers to update a single reference in a theme that can impact the whole application. Most of the colours in this file are referenced directly in the layout or style resource in which they are used, forcing a laborious refactoring process whenever a colour update is required. Constraining colours to a theme not only makes it easy to change the style of an application but it provides immediate feedback when a colour is added and is not conforming to a theme.

My process for dealing with this scenario was to create a new color-palette colour resource file, deprecating the previous color resource file. The new color palette is based on the design library that is used when designing new screens for the application. Using the design system as a template enables our implementation to speak in the same language easing communication across disciplines. Following this process, with a designer and my iOS counterpart (cross-platform, yay!), we introduced custom attributes that covered the function of a colour, i.e. primaryColor, onPrimary etc. Each of these functions is then referenced in the layout or style in which the colour would normally be used. This enables a developer, or designer to update the look and feel of an application by simply tweaking the colour association of a theme attribute, in a single place.


Name all the things

<color name="cardview_title">#FF333333</color>
<color name="cardview_subtitle">#FF666666</color>
<color name="notification_text">#FF333333</color>
<color name="feedback_input_label">#FF333333</color>
Colours named after usage

Don’t do it. This is probably going to cause you a whole world of pain at some point in the future. This strategy can get wildly out of control very quickly. Very quickly. Before you know it you will have well over 100 colours, some of which are just referencing the same base hex value. It’s probably obvious to say, but if you are using this strategy, you are probably not leveraging theme attributes so you are already putting yourself at a disadvantage for quick changes.

If you really like the functional naming strategy, I did before I discovered theme attributes, then there are a few processes you can put in place to make this more successful.

  1. Have a base colour palette that lives close to your design system. This will allow cross team collaboration and ensure that the application is not drifting in terms of the colours that are being introduced.
  2. Have clearly defined layers for how you deal with colours. Try to avoid directly referencing colours from your base colour palette in the layout and style resource files. Instead, use the functionally named colours in these files and have them themselves reference your base colour palette.
  3. You are going to have a lot of colours with a functional naming scheme. Create separate colour resource files that can represent different screens / components. The aim of this, because you won’t be able to leverage theme attributes as effectively, is to allow anyone to pick up a screen’s colour resource files and make quick easy changes.

But seriously, just try to use theme attributes


Exception to the rule

<style name="BaseButton">...</style>
<style name="BaseButton.Raised">...</style>
<style name="BaseButton.Flat">...</style>
<style name="BaseButton.Raised.Black">...</style>
<style name="BaseButton.Flat.Black">...</style>
Inheritance in styles 😭

Styles are great. Styles facilitate quick design changes for a given component if done correctly. When looking at styles I like to think of inheritance in styles as an exception to a rule 😉.

You have your first style which establishes your rule, this is the style for the buttons across the whole application. I now extend to introduce my second style, if I am adding to the base style then I am extending this rule to apply to an additional component. If I modify something in the base style, I am introducing an exception to this rule. It's the exceptions that can be the most dangerous because they deviate from an expected, established pattern. They become especially dangerous when they begin to leak out of the styles and into the layout resources themselves. Making an innocuous change to a base style may not have the desired effect across the application because of these exceptions that have been introduced.

The solution is rather simple. Work with your counterparts in other disciplines, add the components that the app uses to the design library. Establish the components that make up the application and introduce styles that carefully match this design library. If you do this carefully you will likely notice that you do not need to have inheritance several layers deep. And remember, use theme attributes!


Who's the parent?

<style name="BaseButton">...</style>
<style name="BaseButton.Raised.Black">...</style>
<style name="BaseButton.Raised.Grey" parent="SomeOtherButton.Raised">...</style>
Dot vs parent inheritance in styles

Please. Make. Up. Your. Mind.

Personally I prefer dot notation because it is easy to see how out of hand your inheritance is getting. There's only really one good reason to use parent and that's when you need to extend from the platform, which can't be done through dot notation. But whatever you decide, please pick one and stick to it. Dot notation that then uses parent just shows that the inheritance hasn't been carefully considered.


Conclusion

A design system that is to the point and contains all of the elements necessary for a user journey can help to unify the practices of design and engineering through a common language created by both parties. This common language enables seamless communication between the different team members allowing them to iterate quickly. Switching the branding of an application, supporting light or dark mode become trivial when we begin to leverage theme attributes, keep style inheritance simple and carefully consider our applications use of a colour palette.