CSS’s :has()
can obviate JS
Controlling Transparent Colors
Last Updated
A version of this article appeared on newmediacampaigns.com
A strong, cohesive color palette is key when coming up with a visual design. Colors influence a viewer’s emotions and so set the mood.[1] Along with typography, color scheme is important to branding and creating corporate identity. Transparency—a common feature of modern web design—affects color appearance and so can add unwanted variation into a site’s palette, but this change can be accounted for by calculating a new starting color.
In our web designs, we use a unified color palette across graphics, text, visual features such as backgrounds and borders, and interactive features like buttons and mouseover hover effects. This ties a site together and gives it a deliberate “designed” feel which in turn encourages viewers to take your brand more seriously.
Where this gets tricky for the front-end developer is transparent elements. You can start with a carefully selected palette, but that control goes out the window when a drop-down navigation menu lets you see the page underneath it, or block of text in front of an image has a semi-transparent background to aid legibility. Lowering the element’s transparency will tone down, wash out, and just generally change its colors… and next thing you know, your perfect Carolina Blue box has turned into a relative of Alice.
See the problem in this CodePen:
The typical solution is to just let transparency introduce new colors to the final palette. This non-solution isn’t necessarily bad: the human mind understands transparency, understands that it changes the way colors look; and there are times when the underlying layer is complex enough that any attempt to control the transparency’s color would be meaningless. But there are also times when it would be really nice to not sacrifice that design control, and when the background is simple enough that you know the necessary adjustment must be possible, starting with stronger color which when made transparent will tone down to the color you want.
Happily, calculating the fundamental “full opacity” color is easy, given the color you want to end up with, the opacity it will have, and the color it will stack on top of. To determine the color rgb(ropaque,gopaque,bopaque)
that will end up rgb(rfinal,gfinal,btranfinalsparent)
when its transparency is alpha
and it’s in front of a background rgb(rbackground,gbackground,bbackground)
, the calculation for each of the three channels is
Simple enough, but still inconvenient… unless you use a CSS preprocessor to make the calculations for you! NMC uses LESS, and this mixin —a solution by StackOverflow user ephemer— works great
Try it out!
I used this technique on a site with a four-color palette of dark blue, light blue, red, and white. The navigation drop-down menus have a semi-transparent dark blue background. When a menu item is hovered over, its background turns light blue — and the correct light blue, not a lightened dark blue or a semi-transparent light blue.
It’s a small thing, insisting on sticking to your website’s palette at times when transparency would otherwise introduce some variation. But it’s the sort of little thing that makes all the difference. Websites are a visual medium, and you’re taken seriously when you take excellent visual presentation seriously.
Notes
Footnotes
The modern field of color psychology is often traced back to Goethe and the late 18th Century. In marketing and advertising, there are all sorts of intriguing anecdotal and soft-science claims about the effect of color on emotional state. While there’s still much for us to learn, the common-sense impression that color perception influences emotion is supported by more rigorous study. ↩︎
Articles You Might Enjoy
-
Accessible CSS-Only Light/Dark Toggles (with JS persistence as progressive enhancement)
-
Writing zsh tab completions can be straightforward
How I add tab completion for the zsh command line
-
Hometown: A Dynamic, Highly Configurable Git-Focused Zsh Theme
A fast zsh prompt that packs in a lot of Git status info