tinted-theming / home

Style systems and smart build tooling for crafting high fidelity color schemes and easily using them in all your favorite apps.
MIT License
283 stars 14 forks source link

The "red" colour prominence in base16 editor colourschemes for non-error code #10

Closed JamyGolden closed 2 years ago

JamyGolden commented 2 years ago

I once showed a few base16 text editor colourschemes to someone and they said that they would not use it because they all use the colour “red” a lot and “red” indicates an error to them (which is a reasonable).

Since then I haven’t really been able to get that out my head. BASE_08 is often used as the standard text colour but it’s also used for errors and is often red. Errors don’t stand out because it’s the colour of text and you need to understand the context in which errors are shows to understand it’s an error. Syntax highlighting is meant to convey meaning (it’s nice if it looks good too) and meaning is lost when it comes to errors compared almost any other editor theme I've used before. The base16 styling page mentions:

base08 - Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted

I'm guessing it's used for errors due to the Diff Deleted colouring? Here is a side by side example of a sample piece of code from base16-builder-go with vscode using the top theme vscode extension for that specific theme:

Theme Base16 version (vim) VSCode extension version
Ayu dark base16-ayu-dark ayu-ayu-dark
Gruvbox dark medium base16-gruvbox-dark-medium gruvbox-theme-gruvbox-dark-medium
Monokai base16-monokai monokaipro-monokai
Nord base16-nord nord-nord
Solarized light base16-solarized-light solarized-solarized-light

Below is an example of side by side typescript with errors in VSCode. I've included Gruvbox which is quite "red" heavy and nord which has basically no "red".

Theme VSCode Base16-Theme-Generator VSCode Nord extension
Gruvbox dark medium base16-vscode-gruvbox-dark-medium-error vscode-gruvbox-dark-medium-error
Nord base16-vscode-nord nord-nord-error

I picked these themes because they're all very popular themes.

Conservatively, Base16 has at least double the amount of "red" in it's themes than the "official" or most popular VSCode equivalents when not displaying errors. I suspect this is a systemic problem, otherwise it wouldn't be so prevalent in basically ever theme (but I could be wrong).

@base16-project/base16-project-team what your thoughts are on this? Is there something we can do about it?

forrestli74 commented 2 years ago

I think it's working as intended, since we are just showing BASE_08 for variables, etc. But apparently, variables are pretty common in code and lots of red is not pretty.

I guess the simple solution is use a theme where BASE_08 is not red. The reason we don't want that is that the errors will become non-red as well.

Base9 addressed it and is explained here

From an implementation stand point. It's achieved the following way:

Given list of colors specified by the theme, programmatically calculate the color that's closest to red. Assign it to a mustache variable called red or error. Then, the template can decide on whether to use BASE_08 (which can be any color) or red (color that's closest to red in the theme). Reference: Code that calculate what's closest to red Example of use of red in template

Base16 could also do something similar.

joshgoebel commented 2 years ago

For reference if someone would like to see a wider variety of Base16 themes and broader sample of languages/code samples you could check out the Highlight.js Demo site...

https://highlightjs.org/static/demo/

All the Base16 themes are grouped together... so just find a few languages you like then just click the themes sequentially on the left to switch between themes... How Highlight.js maps base08:

.hljs-bullet,
.hljs-variable,
.hljs-template-variable,
.hljs-selector-tag,
.hljs-name,
.hljs-deletion {
  color: #{{base08-hex}}; }

Personally I don't see a huge problem (with just a quick glance)... it's definitely way worse if you're handed variable heavy code... (as with the original examples posted in this issue)

actionless commented 2 years ago

semantic meaning of base-colors is good topic to raise, i'd also add what for using base-colors for theming GUI apps it'd be useful to also have an understanding of at least following colors: 1) background 2) foreground 3) accent/selection 43) error 5) success 6) warning

JamyGolden commented 2 years ago

@lijiaqigreat I really like the idea of absolute colours. @actionless some of those are addressed in https://github.com/base16-project/base16/blob/main/styling.md but would definitely be good to have colours to use fo error/warning/success.

actionless commented 2 years ago

@JamyGolden thanks, i'll check if my adapters for base16 are following that guideline

JamyGolden commented 2 years ago

And there's the issue of different templates implementing the colours differently, for example this vim vs vscode of a python file:

image

actionless commented 2 years ago

regarding Error/Success/Warning, what about reusing these 3:

base08 - Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted base0B - Strings, Inherited Class, Markup Code, Diff Inserted base0E - Keywords, Storage, Selector, Markup Italic, Diff Changed

joshgoebel commented 2 years ago

Are those differences in the template implementation itself though or in the editors syntax highlighting engine? (engines often vary from one editor to another)

JamyGolden commented 2 years ago

I'm not sure yet but I just assumed template implementation, I just opened this up to compare a few minutes ago and didn't expect the big difference.

joshgoebel commented 2 years ago

what about reusing these 3:

I think that goes back to the original problem that there is a desire here for "absolute" colors... right now people are reusing those 3 with (sometimes) bad results. It seems that in a perfect world a theme would be able to set it's variable color independent of it's "diff deleted (red)" color...

It may be that we need to start allowing themes broader control over how their colors are used?

actionless commented 2 years ago

@joshgoebel in many css themes of apps or websites such approach is used but idk how close we could get there from our current situation:

--red: #00ff00;
--blue: #00ff00;
--green: #0000ff;

--error: var(--red);
--success: var(--green);

basically the idea is what absolute colors are assigned to color names, and element colors are assigned from named colors instead of absolute colors

but i personally still thinking what establishing and forcing stricter guidelines for base16-color-meanings would be more viable

joshgoebel commented 2 years ago

and element colors are assigned from named colors instead of absolute colors

I don't know how that helps if I want errors to be RED but variables to be GOLD and the standard says I only have a single color, Base08 to do that with... this isn't a naming problem AFAICT.

joshgoebel commented 2 years ago

Wouldn't a better way to study this be to just analyze mathematically the base08 and base0B color of ALL schemes and see what that color distribution looks like?

If this can be shown concretely then I'd say we have a problem that styling needs to address. When designing a theme I don't think one's hands should be tied in this matter - choosing between making diffs look "reasonable" and picking the colors you might otherwise want.

One could of course say there are no canonical/reasonable colors for diffs, but if all our theme designers skew one direction for base08/base0B I'd say that's evidence that there is. Personally I think there is (that diffs should be red/green).

I'm not sure that 16 unnamed, numbered colors will continue to be sufficient... it may be that I want to specify:

It seems that as long as I still have 16 total colors that I should be able to say:

joshgoebel commented 2 years ago

And if this were shown (statistically) to be a problem I'd propose a minimal fix, the addition of a small number of named aliases that are allowed to point back into the existing palette. Templates could use these by name and builders would default to the style guidelines when the named aliases were not present... ie, if diff_removed was not present, then it would default to base08, as it has historically.

scheme: "Scheme Name"
...
base0A: "993300"
base0F: "ffffff"
...
diff_added: base03
diff_removed: base0A
error: base0A
actionless commented 2 years ago

yeah, the latter i think would be less painful considering it would have reasonable fallbacks

JamyGolden commented 2 years ago

Yeah I think that’s a good idea. I’m going to be away from my computer for a few days; does anyone want to write a script for the analysis? If not, then I’ll do it when I’m back next week.

forrestli74 commented 2 years ago

Made a chart for it: https://docs.google.com/spreadsheets/d/1ejVo3o_CD9PtnC02kVhi9h3JyC2s0ZoewdTylorvF-E/edit#gid=286940616 Gave everyone edit access. Please don't abuse it...

It works in LAB color space. For each scheme, it computes the average LAB for all 16 colors, then plots (BASE_08.A - average A) against (BASE_08.B - average B) as a dot on the chart for each scheme.

Here is a visualization of LAB color space: https://www.fsw.cc/wp-content/uploads/2017/01/CIELAB-Full-Color-Graphic-e1485790949295.png

I think it shows that there is a big skew toward red. But how much skew and variation is a good amount is up to debate.

actionless commented 2 years ago

amazing job @lijiaqigreat

could you please share here the averaged hex(#ff0000) values of all the themes?

(we could even create a new theme from it and call base16-hivemind 😹)

forrestli74 commented 2 years ago

I added a data dump for rgb values. Feel free to add a tab with your name or clone the sheet to do your own analysis. Made an error in excel, the skew is much worse and spread is much worse than the previous result.

actionless commented 2 years ago

thanks! the resulting palette if anyone is curious:

#57585B #5F5F62 #676B6A #727575 #899093 #9A9E9E #A4A6A7 #B0B3B3 #C3555C #C9864F #C7A94E #74AD60 #5BA5AB #5689BF #9E6AB2 #9E6A6A

NOTE: it would make more sense doing average-ing for dark and light themes separately - otherwise when they all mixed together the first 8 of averaged colors are getting too low contrast

UPD: averaged dark theme:

#191C20 #2E3035 #464B4C #626667 #939C9D #B9BCBC #CCCDCD #E1E4E2 #C45E65 #C88B56 #CBB157 #7EB769 #65ADB1 #5D92C2 #A574B5 #9D6A6B

averaged light theme:

#F6F4F1 #DDD8D4 #BCBEB8 #999B99 #6E7377 #4B4F53 #3D4048 #333539 #BF3F44 #CB7A3B #BE9636 #5B944B #40929A #4274B6 #8C4FAA #A16B68

forrestli74 commented 2 years ago

If this can be shown concretely then I'd say we have a problem that styling needs to address.

I think it's fair to say it concretely shown that there is a systematic skew towards red for BASE08 and green for BASE0B.

actionless commented 2 years ago

NOTE2: if you'd do averaging in a different color space (my favorites are hsv/hsl) and would convert the result to rgb - it may slightly vary but i not expect too big difference to bother trying

joshgoebel commented 2 years ago

Is the real problem just with red and green, or are too many themes only minor variants of the colors from the logo? Do we need to have a filter function here to filter out that "noise"? I've noticed this before in passing that a lot of themes follow that pattern... You might expect for a theme that prefers "more colors" to have a wide spectrum (a green, a red, a yellow, etc.)... but that a majority should all decide to use the same colors for the same things semantically - seems to be kind of weird.

Sorry if I'm the slow one. Is this perhaps skewed for terminal color schemes? Where there is the expectation that a certain numbered colors will have a certain hue? But if so I think this majorly breaks the ability to use the schemes as a creative tool... (unless we just admit that some schemes ONLY target certain templates)... IE, if you rearrange all the colors creatively your use as a terminal color scheme might be a bit questionable?

Nope, that's not it... Hmmmm.

# Terminal colors
0 = Black       8 = Gray
1 = Blue        9 = Light Blue
2 = Green       A = Light Green
3 = Aqua        B = Light Aqua
4 = Red         C = Light Red
5 = Purple      D = Light Purple
6 = Yellow      E = Light Yellow
7 = White       F = Bright White
JamyGolden commented 2 years ago

Closing this since the issue has achieved the goal of creating discussion around the systemic problem and a proposal to solve the underlying issue has been created https://github.com/base16-project/base16/issues/11

joshgoebel commented 2 years ago

@actionless Can you share your code for building the averages?

forrestli74 commented 2 years ago

It's all in the sheet https://docs.google.com/spreadsheets/d/1ejVo3o_CD9PtnC02kVhi9h3JyC2s0ZoewdTylorvF-E/edit?usp=drivesdk

joshgoebel commented 2 years ago

Oh I was hoping for source that I could run against the actual schemes repository dataset...

belak commented 2 years ago

I'll look into adding a hivemind generator to the go builder. That could be fun.