Terminal Color Schemes (Part 1)
Since I am switching to Alacritty on my daily driver, I am allotting a bit of time to work on the color scheme. I have not been satisfied with the color schemes that I find online, so I use a custom color scheme. There are still some things that I have yet to understand, so I may as well blog about it. This is the first of a series of blog entries on the topic.
I prefer dark color schemes for editing text, especially source code. I will only consider dark color schemes in this blog entry.
Color Settings
As I developer, I select a color using three parameters, a result of the ANSI Select Graphic Rendition design. The following types and constructors are from ansi-terminal, a library that I frequently use.
Color
Black
Red
Green
Yellow
Blue
Magenta
Cyan
White
ColorIntensity
Dull
Vivid
ConsoleIntensity
BoldIntensity
FaintIntensity
NormalIntensity
Alacritty configuration
allows you to specify (a hex value for) each Color
for
three levels of brightness.
- normal
- bright
- dim
The ColorIntensity
and ConsoleIntensity
map
to these brightness levels as follows. Note that the
BoldIntensity
also results in the use of a bold font.
(IMHO, mixing color selection with font selection is an unfortunate
aspect of the design. Perhaps it is a result of gradual expansion of the
ANSI standards…)
ColorIntensity |
ConsoleIntensity |
Brightness Level |
---|---|---|
Dull |
FaintIntensity |
dim |
Dull |
NormalIntensity |
normal |
Dull |
BoldIntensity |
normal |
Vivid |
FaintIntensity |
normal |
Vivid |
NormalIntensity |
bright |
Vivid |
BoldIntensity |
bright |
Aside from mixing color selection with font selection, this looks
pretty straightforward. Unfortunately, it is not
straightforward in practice. Many color schemes ignore the semantics of
colors and intensities, assigning arbitrary colors to each value in
order to create the desired output. A developer setting a
Red
foreground cannot rely on a red color being used;
whatever color is assigned to Red
is used, even if it is a
hue of blue.
Terminal emulators also explicitly configure default foreground and background colors, which may be different from any of the above colors . A developer may change the foreground color to any of the above colors and reasonably expect it to be readable with the default background color. (A possible exception is that some color schemes may make the color corresponding to the background color the same as the background color.) When setting the background color to any of the above colors, one cannot really expect all text to be readable, though good color schemes make an effort to maximize readability in these cases.
Common Problems
When searching for a dark color scheme, I often run into three problems.
- Many color schemes use a background that is lighter than I like. I do not like it when the background looks visibly gray, and I really dislike tinted background colors.
- Some color schemes include colors that have a low contrast ratio, making text in those colors difficult to read. Blues are particularly problematic.
- I like to use bright colors sparingly. I would like to reserve them for errors and other types of alerts. I do not want strings or keywords in my source code to be much brighter than other parts of the code, for example.
The fact that I am unable to find a color scheme that I like indicates that my preferences are not common…
Color Theory
Some time ago, I experimented with creating a color scheme based on color theory, taking into account relative luminance and contrast ratios of the colors in the palette. Ultimately, I would like to write a program that helps design a color palette by providing warnings and optional assistance (color calculations) based on color theory. Perhaps I will dust this experiment off someday, but I do not have time to go that deep now.
The popular Solarized color scheme is based on similar ideas! The designer used CIELAB lightness relationships to select accent colors with similar lightness, with hues selected using color wheels. I really like the idea, and it is well designed, but I am not a fan of the results.
I created an SVG file to demonstrate color schemes. Click on a hex color to use that color as the background color. Alt-click on a hex color to use that color as the foreground color (for the label text on the top and left). This functionality makes it easy to visually determine the readability of text when using different colors of the palette. Note that I did not minimize the SVG code, making it easy to edit the file and change the colors.
The following image demonstrates the dark Solarized color scheme. Note that the Solarized project does not provide dim colors. The dim colors in the above SVG are calculated automatically by Alacritty.
Using the default background, text in all colors but black is readable. Solarized does a great job in this respect. When, using other colors as the background, most text is still readable. Not bad!
One reason why I do not like this color scheme, however, is that I find the background to be too bright. Subjectively, I prefer darker backgrounds, and I really dislike the blue tint. Objectively, darker backgrounds allow for more contrast.
Another aspect of the color scheme that I dislike is that the bright
colors provide little variation. The bright colors for
Green
, Yellow
, Blue
, and
Cyan
cannot be easily distinguished! I prefer to have more
variation in color available, especially when limited to such a small
palette.