💥 Check out this awesome post from Hacker News 📖
📂 **Category**:
💡 **What You’ll Learn**:
Let’s say you’re creating
a CLI tool which has to display
syntax highlighted source code.
You begin by choosing some colors
which look nice with
your chosen terminal theme:
~ — zsh — Sorcerer — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 💬
Finished highlighting in 0.02 seconds.
% █
Nice!
However,
who knows if it’ll still look good
for people who use
a theme different to yours?
It seems sensible to try out
the defaults, at least.
Let’s start with
the macOS Terminal.app default theme:
~ — zsh — Basic — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 🔥
Finished highlighting in 0.02 seconds.
% █
~ — zsh — Basic — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 ⚡
Finished highlighting in 0.02 seconds.
% █
Youch!
It seems fair to try the Tango themes next,
since those are the default on e.g. Ubuntu:
~ — zsh — Tango Light — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 ⚡
Finished highlighting in 0.02 seconds.
% █
~ — zsh — Tango Dark — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 {
return “hello world\n“
}
Finished highlighting in 0.02 seconds.
% █
Hmm, better, but not by much.
Finally,
let’s try what is likely
the most popular custom terminal theme – Solarized:
~ — zsh — Solarized Light — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 {
return “hello world\n“
}
Finished highlighting in 0.02 seconds.
% █
~ — zsh — Solarized Dark — 51×11
% highlight foo
# just some docs
func HelloWorld() [12]u8 {
return “hello world\n“
}
Finished highlighting in 0.02 seconds.
% █
Well then …
Let’s take a look at each palette
and investigate.
Sorcerer
~ — zsh — Sorcerer — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
In Sorcerer,
all colors are readable
on the default background
except for black,
which is in fact darker than the background.
This is useful as the background color
for status bars and the like.
white is the same color as
the default foreground,
and brblack is a nice faded color.
Additionally, brwhite is
even lighter than the foreground;
this allows for subtle emphasization
of important text
like error messages and titles.
Basic
~ — zsh — Basic — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
~ — zsh — Basic — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
The Basic themes are, well, horrendous.
Really owning that 90s xterm look, it seems.
bryellow is unreadable in light mode
(check out that function name
from the code sample earlier),
while in dark mode
both blue and brblue
are totally illegible.
That leaves us with thirteen colors
we can safely use:
~ — zsh — Sorcerer — 51×11
% colortest –only-usable
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
Tango
~ — zsh — Tango Light — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
~ — zsh — Tango Dark — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
In my opinion
these did a lot better than
Terminal.app’s Basic themes,
but they are still far from perfect.
bryellow is again unreadable in the light theme,
and perhaps brgreen is
a little difficult to see,
though it’s nothing that would
stop me from using brgreen
in an application.
At this point you may have noticed
how the greyscales –
black, brblack, white & brwhite –
have remained consistent
between light and dark themes
for both Basic and Tango.
Of course,
this means that
{,br}white is unreadable in Tango Light
(owing to the light background)
and black is unreadable in Tango Dark
(owing to the dark background).
In other words:
forget about
that idea of mine from earlier
about using brwhite to emphasize content.
Unless, of course,
you don’t mind if your
eminently emphasized words
are completely unreadable
for the user of your software
who deigns to use the default light theme
of A Popular Linux Distro.
On the other hand,
using brblack to de-emphasize content
still seems fine to me.
I suppose some extra contrast
for brblack in Tango Dark
would be nice,
but with text which is meant to be ignored
I don’t think this matters much.
And lo, but ten colors remain.
~ — zsh — Sorcerer — 51×11
% colortest –only-usable
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
Solarized
~ — zsh — Solarized Light — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
~ — zsh — Solarized Light — 51×11
% colortest
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
Solarized is a curious beast.
Every color in it
was chosen using L*a*b*,
a perceptually-uniform color space
from the 1970s.
(For what it’s worth,
color science has
progressed significantly since then;
the only reason
Ethan Schoonover used L*a*b*
is that it’s commonly used in photography,
and he used to be a professional photographer.)
Its lightnesses are perfectly symmetrical
so that Solarized Light and Dark
can share a set of accent colors
while maintaining identical contrast.
Moreover,
the warm tones of the light theme
and cool tones of the dark theme
are complementary.
(The hue gap is
closer to 150° than 180° in reality.
See here
and here
to compare hue values.)
Solarized is also incredibly popular.
I have no data here,
but as of the date of writing
it’s the most starred theme repository on GitHub
I can find.
Solarized has 15.4 thousand stars at the moment,
while the next-closest is Gruvbox
with 11.8 thousand.
Solarized is available as a plugin
or sometimes even as a built-in preset
in damn near every
popular terminal emulator and editor
on the planet.
To understand Solarized’s
peculiar arrangement of the 16-color palette,
we have to travel back in time to 2011
when Solarized was first released.
In this dark era,
terminals supporting 24-bit color
didn’t exist / weren’t widespread.
One option common among Vim themes at the time
was to round every color
to the nearest 256-color palette value.
In Solarized’s case,
this destroys the mathematical symmetry
at the heart of the theme.
(I’m not kidding, it looks awful.)
The solution
– rather, hack –
chosen at the time
was to distill
all the colors used in the Vim interface
down to a palette of sixteen colors.
Conveniently,
Solarized’s accent colors
fit nicely into the non-bright column
of the 16-color palette,
while Solarized’s monotones
fit into the bright column.
Once the user sets their terminal
to use the Solarized palette,
Vim can color its entire interface
using only the 16-color palette
and get correct color values,
no clunky color approximations needed.
The downside to all this is that
an application which uses
any of the bright colors
which Solarized co-opted for itself
will look strange.
Users of Solarized
– and, by god, there’s so many of them –
appear
frequently
on
issue
trackers
asking why command-line output
is inexplicably gray or even invisible
as a result of CLIs
using these forsaken bright colors.
Our beloved brblack
is unreadable in Solarized Dark,
so we’ll have to strike it from the table
in addition to the affected bright colors.
~ — zsh — Sorcerer — 51×11
% colortest –only-usable
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
% █
A sad note about bold
Far back in the past,
there was no way for terminals
to display bright colors.
As a workaround,
manufacturers
(we’re talking about
physical terminals here)
started making all bold text bright
instead of using a heavier font weight.
One way or another
this ended up in the default settings of
many modern terminal emulators
(in spite of not being in the standard),
meaning that
regular colorful text made bold
can become bright too,
depending on the user’s configuration.
Conclusion
And so, I present to you the final version
of our table of acceptable colors:
~ — zsh — Sorcerer — 51×21
Regular:
██ black ██ brblack
██ red ██ brred
██ green ██ brgreen
██ yellow ██ bryellow
██ blue ██ brblue
██ magenta ██ brmagenta
██ cyan ██ brcyan
██ white ██ brwhite
Bold:
██ boldblack ██ boldbrblack
██ boldred ██ boldbrred
██ boldgreen ██ boldbrgreen
██ boldyellow ██ boldbryellow
██ boldblue ██ boldbrblue
██ boldmagenta ██ boldbrmagenta
██ boldcyan ██ boldbrcyan
██ boldwhite ██ boldbrwhite
% █
Only eleven out of our
thirty-two possible color settings
are permissible,
given that we want applications
to remain readable
for as many people as we can.
If you’re developing a command-line tool
which will be used by
anyone apart from yourself,
I strongly recommend
you limit your use of color
to the ones I’ve identified here
as being “mostly alright”
and “not unreadable in
a common configuration
used by tons of people”.
Appendix
You probably didn’t notice,
but I styled the “terminal windows”
in this post to look
as similar as possible
to macOS Terminal.app windows
through painstaking
color picking and pixel counting.
The dimensions in each window’s titlebar
matches as closely as I can
with its actual dimensions on-screen.
The colortest and highlight utilities
are entirely fictional.
Terminal.app doesn’t actually provide
individual access to
the light and dark variants of Basic;
they appear as a single theme,
which switches seamlessly
when the OS theme changes.
As far as I know,
this reactive functionality
isn’t exposed to any other theme,
whether pre-installed or user-created.
In order to capture this,
I made the terminal windows in this post
react to whether the rest of the site
is in light or dark mode,
except for the Basic windows.
They remain fixed in
either light or dark mode,
since in real life you’ll never see,
for example,
a light Basic terminal
with dark window chrome.
Luna Razzaghipour
29 January 2023
{💬|⚡|🔥} **What’s your take?**
Share your thoughts in the comments below!
#️⃣ **#Choose #Colors #CLI #Applications #Lunas #Blog**
🕒 **Posted on**: 1769700107
🌟 **Want more?** Click here for more info! 🌟
