Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

End user colour configuration (colourblindness) #212

Closed
michjnich opened this issue Nov 15, 2024 · 13 comments
Closed

End user colour configuration (colourblindness) #212

michjnich opened this issue Nov 15, 2024 · 13 comments
Labels
new feature New feature or request style

Comments

@michjnich
Copy link

(yes, it's me that asked the question at your Pycon SE talk ...)

I would like a way for the end users of a package that uses rich-click (i.e. not the package maintainers) to be able to override the default colours specified by the package and configure it to their own needs. This would allow those packages that configure problematic colours (eg. red on a black terminal is a common problematic colour-combo for me, and it's a very common one for errors ...)

I was going to start a discussion but it kind of seems they're not being used here so I'm raising this as an issue for the moment, but happy to move this there if you like ...

A brief thought on what doesn't work:

  • Configuring my terminal to change eg red ==> yellow

I've had this suggested to me before (by a very large python package!), but it's not a sensible option becuase each pacakge can use different options. I could, for example, change red into yellow in my terminal, which is great for package A, but then pacakge B uses yellow for something else, and also uses light green - now I can't really tell the difference between yellow and light green, which means red and yellow are the same thing for package B, and both look the same as light green. If package C then uses light green for something different too you can see how trying to synchronise that kind of change across my terminal becomes problematic.

So my conclusion is that pacakges need to offer a way to configure colours for that pacakge alone (either that or every single pacakge maintainer agrees to use the same colour scheme ... can't see that happening :D )

Suggestions

  1. Add the ability to use themes

You suggested this as a possible solution, and I think this would work as long as it "just works" on a common setting and would apply to any pacakge using rich-click

So in my local config I'd have something like:

RICH_CLICK_THEME=colourblind

Then package maintainers could define and set a default theme in their own pacakge that would be used out of the box, but I could override this if I wanted.

  1. Allow local colour overrides by package

This one is probably a little more complicated, and I'm not sure if it's really feasible - perhaps if rich-click included by default a command that shows the end user all the colours used by the package, and allows them to change those defaults and save them to some local config file.

  1. Some other option?

Not sure what that might be.

Option 1 probably feels like the most sensible at first glance. Option 2 seems a little messy, and I'm not sure what options 3..x might even be.

Incidentally, this is a site I recommend to anybody designing UX stuff: https://www.whocanuse.com

It shows who might have problems with specific colour schemes and isn't limited only to colourblindness.

In general, contrast is a good thing to aim for, but that's not the be all and end all. I have no idea for example what kind of issues those with the blue/yellow form of colourblindness have.

As I say, I'm, opening this issue to start a discussion as to what a good solution might look like. Happy to participate in that discussion. Not sure if I will have time to contribute or if I do have time how much that might be, but I'm certainly open to the possibility of doing some of the work.

@ewels
Copy link
Owner

ewels commented Nov 16, 2024

Didn't see this and opened #213 in parallel. Sounds like we're suggesting the same stuff though :)

It would be great to have a style config set that is colour-blind friendly which can be invoked by the presence of an environment variable.

Then anyone who has that env var set in their terminal will have colour-blind friendly CLI output from every tool that uses rich-click (without any need for the developers of those tools to do anything).

Could work well with the planned style sets - maybe generalise to end users being able to set global configuration for any rich-click tools.

@ewels ewels added new feature New feature or request style labels Nov 16, 2024
@ewels
Copy link
Owner

ewels commented Nov 16, 2024

I'm curious what @dwreeves thinks as this overlaps suggestions in #179 and #186

@dwreeves
Copy link
Collaborator

Accessibility is very important, and we can definitely take a few steps to improving it.

Overview

Adding something like a colorblind mode should be seen not just as a convenience for users but for developers as well:

  • User should be able to do something like, add RICH_CLICK_COLOURBLIND_MODE=true / RICH_CLICK_COLORBLIND_MODE=true to their ~/.zshrc or .env. (This is just an example and not my final proposal-- see below for that.)
  • Developer should be able to do nothing and get accessibility for free.

Challenges

However, there are a few challenges with adding an explicit colorblind mode and I'm a little hesitant to add something quite as explicit as that.


First, the default rich-click config uses the 8 ANSI colors, which render differently on each terminal, and can be configured by a good terminal (including for accessibility). For example, here's iterm2:

image

And here's PyCharm:

image

So users with color accessibility requirements should first try their best to run in a terminal that has these settings, as this solves issues with not just rich-click but all terminal applications using ANSI colors.

I guess this is my main concern with a very fine-tuned colorblind mode in general, if I am being honest: If a user finds (for example) red on black to be hard to see, then it seems like the user would benefit more from adjusting their terminal's settings so that all ANSI red is impacted, not just rich-click's.

Let me know if I am missing something that makes it more complicated than what I'm saying, for I am not colorblind myself. The main complication I can see is that more basic terminals aren't very configurable, so let me know if there's more.


The second challenge is, it's not clear what to do when the users changes the default config.

The user may be using hex values for colors, for example, and that can be tricky to rebalance. One option here is we can apply a color shifting algorithm based on an environment variable. But this can get tricky and requires going deep into internals. And my feeling is this is something better suited for Rich: https://github.com/Textualize/rich

Next steps

Two things spring to mind pretty immediately as things we can do that are essentially costless from a technical maintenance perspective.

First, there is a pretty straightforward escape hatch that rich-click should add. The rich.console.Console() object has a kwarg called no_color, which we currently don't use. I think the user should be able to force no_color to be True, such as with an environment variable like RICH_CLICK_NO_COLOR=true. So the gradient example in the presentation would look like this:

image

Of note, there are some developer implications here as well. Take the above as an example. If the developer passes the gradient in as header_text, then we get black+white everything. But if the developer does their own console.print(), it would still render the gradient.

Which gets me to the second thing I would propose. The docs should absolutely have a section on accessibility. I think we should mention the following:

  • Overview (For both users and developers):
    • rich-click by default uses ANSI colors, which differ across terminals.
    • Most full-featured modern terminal environments (iTerm2, JetBrains, VSCode) give users the ability to customize ANSI colors.
    • This customization makes ANSI colors more accessible.
  • Accessibility as a user:
    • If you are having issues with the rich-click defaults, this may suggest your terminal's default ANSI colors should be customized. If this option is available to you, then that may be a good starting point.
    • If this is either not an option, or you are using a CLI that uses non-ANSI colors, you can set RICH_CLICK_NO_COLOR=true to disable colors.
  • Accessibility for developers:
    • Because ANSI colors are not set in stone, using ANSI colors is the safest bet for ensuring your software is not only accessible to colorblind users, but looks good across as many terminals as possible (since people have different background colors).
    • We strongly recommend doing something like: header_text=Gradient(...) over console.print()ing the Gradient(...) yourself because the latter does not allow your end users to utilize rich-click's accessibility option.

(Also a note, not sure where to put this, but in code we should prefer COLOR to COLOUR, since it's called color everywhere in code. Though in docs we can continue to use the British English noun "colour" in the more general sense of the term.)

After that

Do the above two things (RICH_CLICK_NO_COLOR=true and docs changes) solve the problem of color accessibility? I am curious to hear. I think it should definitely get us very far.

I imagine the solution may be a little underwhelming for rich-click CLIs using hex values, but those are just much harder to address. Again, I think that is more of a Rich thing than a rich-click thing, especially given how rare it is for users to use hex values in rich-click. So I would open an issue there if this is a concern.

Also, just to be clear, I am not ruling out a colorblind mode for the default config. I am just making sure that we can address accessibility first with something that requires us adding less opinionated complexity. For a colorblind mode, if we were to implement it: if the biggest problem is red on black, as you mention, we can do something like, "bold blue" if truthy(os.getenv("RICH_CLICK_COLORBLIND_MODE")) else "bold red" for those things which use red. rich-click uses red basically just for deprecated messages and "required" reminder text. We can apply this to the default config, and it should be fine.

@ewels
Copy link
Owner

ewels commented Nov 17, 2024

I thought we already had NO_COLOR env var? I think that's built into rich so should already work.

https://rich.readthedocs.io/en/latest/console.html#environment-variables

The more I think about it, the more I just want user configurable styles which would then apply to every CLI using rich-click. We can't cater to everyone, and each user knows best what works for them.

Looks like Textual is also implementing something like this with TEXTUAL_THEME so maybe we could alias that? Though maybe we want to stick to rich-click configuration properties so may not work well.

https://x.com/willmcgugan/status/1857861094448025786?s=46&t=sQoaYa8QL3Pp7XfT5G_rhg

If we do this then it's a general user feature which happens to also be good for user accessibility. We can ship some defaults for various types of colour blindness as well as letting people define their own. If the env var is left undefined then the developer's config is used.

@dwreeves
Copy link
Collaborator

I was not aware of NO_COLOR in Rich! 😅 I should add that to any rich-click docs on accessibility. And in that case we don't need one specific to rich-click.

If Textual is doing theming, we can possibly piggyback on that. I think that would be reasonable, and it would solve some problems too.

@michjnich
Copy link
Author

My 2p worth ...

I think anything like COLOURBLIND_MODE env var is probably not appropriate.

Colourblindness is more than one thing - different people have different problems with different combos. One env var implies some kind of colourscheme that will be visible by all colourblind folks and that's just not possible (afaik).

https://media.healthdirect.org.au/images/inline/original/eye-colour-blindness-diagram-d78167.jpg

Add to that, if you were doing that anyway it obviously involves setting some different theme, so the absolute best would (imho) be to allow a RICH_CLICK_THEME setting somewhere, and perhaps ship with a couple of built-in themes that are colourblind friendly so the end user can set whichever one makes sense to them and go from there (and, if they need to they can also then copy that theme and tweak it to their own ends).

Theming gives colourblind (and possibly other sight impaired folks) the ability to configure things as they need to, and also gives the rest of the community something they might like too, so win-win all around.

tl:dr: +1 for theming :)

@dwreeves
Copy link
Collaborator

@michjnich, do you have any thoughts on putting in the docs an accessibility page that has (1) a mention of the NO_COLOR env var, (2) a suggestion that users with accessibility requirements configure their terminals' ASCI colors with instructions for ITerm2, VSCode and IntelliJ/PyCharm, and (3) a note to developers that their applications will be more accessible using the ANSI colors?

We have the intention to do more to support themes in the 1.9 and 2.0 roadmaps, it's a good idea, but it could be a little while and a little brainstorming until that happens (we want to make sure we get it right as a general feature). So we definitely have code-related features on the roadmap that will directly address the issue, and I don't mean to make it seem like that isn't the case by asking about a docs change; I am just curious if you think this is reasonable for the meanwhile. 🙂

@michjnich
Copy link
Author

I think (1) is absolutely something you should add to the docs. It's the obvious 1st response for any user having problems reading things.

(2) I'm afraid is not really a solution ... (and I say this as somebody that actually does this for the servers at work). It's a bit of a hacky workaround at best, and it never really works 100%.

Basically, if I redefine colour A to be colour B (even if colour B is simply a lighter version of colour A) then some other thing may well use colour B (or something that's close enough to colour B for us poor colourblind folks that it makes no difference) and suddenly I have 2 things that are exactly the same colour but have different meanings.

So, say I redefine red as yellow (just to make it obvious) and this is lovely. Then another thing uses yellow to indicate something else. Not only that but they also use light green for a different thing, and I can't really see the difference between their light green and yellow either. A third thing then uses light green and red as well, and maybe they throw in some form of orange which clashes with one or both of the green and red ... well, I'm sure you can see how that just gets complicated really quickly.

It's a common suggestion though, and one I've had from at least one large package in the past when they just didn't want to address the problem. So I'm just very happy that you're giving it full consideration, as fixing it here will have a significant knock on effect to other packages!

(3) Asking devs to think about this stuff just plain doesn't work I'm afraid. You'll just have to take my word for that - I've been doing it forever :D I can't even get people at work to use reasonable colours in excel sheets or powerpoints, let alone when they're coding! You could potentially throw in a link to https://whocanuse.com with a suggestion to check it out for any colour combinations they may be thinking about using - if even one person learns of that site and starts to use it a little more I think it's a good thing :)

Also, just to say, I don't expect any immediate solution to this, and a "proper" solution that allows the end user to properly theme for themselves any app that uses rich-click is most definitely the preferable solution. If that means waiting a while so it can be done properly, then I personally think that is the way to go.

@dwreeves
Copy link
Collaborator

Adding a link to whocanuse.com is a great idea!

Thank you for your insights. We'll work on docs in the short-term, and then work on override-able theming in the longer-term.

@michjnich
Copy link
Author

Not promising time at this point as I have no idea how things will look then, but by all means ping me when you get to the point where this is reasonable to do if you're looking for help :)

@dwreeves
Copy link
Collaborator

dwreeves commented Dec 2, 2024

We have a docs PR open with an accessibility page: #216

@ewels
Copy link
Owner

ewels commented Dec 20, 2024

Ok, new docs should now be live - @michjnich shout if you have any feedback!

Closing this now, I've split the theming idea out into a new issue: #219

@ewels ewels closed this as completed Dec 20, 2024
@michjnich
Copy link
Author

Looks good @ewels - thanks so much for listening!

I think the only comment I'd have is regarding configuring terminal colours to "work around" issues. I agree that's a potential solution, but as previously mentioned I wouldn't say it's a "recommended" one as mentioned in the text:

If you are having difficulty distinguishing colors, it is recommended that you adjust these settings.

The reason for that is that different tools use different colours, and while making eg. red a little lighter so it displays better on black is fine, you can end up with a bit of an arms race between different tools to make sure colours don't clash. Most tools use only a small number of colours, but they're all different, and while, for example, both yellow and light green display well on black, they often look too similar to be useful when used together in the same tool.

With one or two tools, it's fine, but as the number of tools increases, it kind of becomes harder to set a colour palette that works. I'm not even sure I could pick 16 different colours that would all be "at a glance" easily distinguishable in the same tool. (Like I say, usually this is fine because most tools don't use that many).

This problem will of course go away once we can theme things :) Becuase then I can decide for myself which of the ANSI colours (or just hex codes) to use, and avoid any of those clashes. I'd likely still adjust the ANSI terminal colours for myself, but then I can do so without the risk of clashes between different tools (well, different tools that use rich-click, but one thing at a time :D )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request style
Projects
None yet
Development

No branches or pull requests

3 participants