When selecting system colors, match but don’t mix


Here's a question that came in from a customer:

Is there a way to view all the Windows color schemes at once? We want to display text in the COLOR_BTNTEXT color against a background of COLOR_INACTIVECAPTION, and we want to check that this looks good in all of the themes.

A mistake I see from some programs is mixing system colors that are not meant to be mixed. The colors I'm talking about are the ones obtained from the GetSysColor function. Here are the text and background color pairs, with a sample of what those colors are on a default install of Windows XP.

Text Background Sample
COLOR_WINDOWTEXT COLOR_WINDOW sample
COLOR_HOTLITE COLOR_WINDOW sample
COLOR_HIGHLIGHTTEXT COLOR_HIGHLIGHT sample
COLOR_INFOTEXT COLOR_INFOBK sample
COLOR_MENUTEXT COLOR_MENU sample
COLOR_BTNTEXT COLOR_BTNFACE sample
COLOR_CAPTIONTEXT COLOR_ACTIVECAPTION sample
COLOR_INACTIVECAPTIONTEXT COLOR_INACTIVECAPTION sample

If you're going to combine colors, and you need them to contrast against each other (for example, because you're going to draw text with them as the foreground and background colors), choose a pair from one of the rows above. Do not choose colors from different rows because there is no guarantee that they will be readable against each other.

For example, I like to use black on #71FFFF as my color scheme for highlighted text. I've seen programs which break the above rule and draw text in the COLOR_HIGHLIGHT color against a background of COLOR_WINDOW, on the assumption that the highlight color contrasts against the window color. (They get away with this in the default Windows XP color scheme because the window color is white and the highlight color is medium blue.) Unfortunately, on my machine, this results in text that is extremely painful on the eyes.

Remember: When it comes to system colors, match. Don't mix.

Comments (35)
  1. mastmaker says:

    Isn’t there ONE hacker among the readership of this blog who can make these ‘pingback’ers eat their crow? This is getting to be too much!

  2. NoiseEHC says:

    I have a question:

    Is there somewhere some documentation which shows what colors does Windows use while drawing controls (especially common controls)?

    The problem is that when I implement a custom drawn listview for example I want to know what colors to use for example for the unfocused selection rectangle (the color when the listview is unfocused but has an always-show-selection). It seems to be gray, but is it always gray? Is there a GetSysColor for it?

  3. Dan says:

    mastmaker: I think pingbacks are what are supposed to make blogs "special" when compared to traditional news scripts.  That and comments.  It’s sort of like a reverse hyperlink that shows whenever another blog links to yours.

    NoiseEHC:  Google for a program called "3D Color Changer", it allows you to change a few more system colors than Windows’ built in tool does.  What I do is i set each element to a different bright and ugly color.  Since every element is now a different color, it becomes easier to see what color is being used to draw a control.

    An annoying thing I’ve noticed is that webpages assume all <input> fields default to color: black when instead they default to BTNTEXT (at least in Firefox; I guess this is sort of a bug in Firefox because I disabled the option which uses system colors as defaults in HTML documents).

    The result is that some sites change the background-color of input elements (buttons and textboxes in particular), for example to white, and leave the color property alone.  I liked having an inverted theme, with white on black for WINDOWTEXT/WINDOW and dark BTNFACE and light BTNTEXT.  Of course, I ended up with white on white textboxes on many websites and I ended up writing a few Stylish CSS rules to fix a few specific websites.

    This mistake is actually pointed out to you if you use the w3c CSS validator, which complains if you set background-color without color or visa-versa.

    I am happy to say in my programs (and websites) I have never been guilty of system color "mixing".

    A related thing that you should never do is mix system colors with hardcoded colors, because it’s very easy to end up with eye-tearing color schemes that way (even easier than Raymond’s example… this is pretty much what the aforementioned websites do).

  4. John says:

    Well, you could call SetSysColors() with each enumeration until the color changes.  Then you know which one you need to use.  But my guess would be that it’s probably hard-coded.

  5. Mike Weiss says:

    Maybe this is common knowledge among web developers – but i didn’t realize that you could use Windows system colors as named HTML colors (which is what Raymond has done in this item).

    http://msdn2.microsoft.com/en-us/library/aa358804.aspx

  6. Dave says:

    Mike, it was news to me. Seems to work in Firefox Opera, and even Safari/Win. I wonder what it does on a Mac?

  7. BryanK says:

    Mike and Dave:  Well, it is part of CSS2.1 (but deprecated in CSS3, in favor of an "appearance" setting in the UI module instead; appearance also affects the cursor, outline, etc.), so I suspect that anything that supports CSS2 will work with it.

    The CSS2.1 spec says that if you don’t have a given system color, you should map to "the nearest system value" (whatever that is) or "a default color".

  8. mastmaker says:

    Dan:

    I was referring to ‘comment spam’ming pingbacks from ‘abosultely people search’ fella(s). Oh…I really wish there were a hell and I could send these spammers there.

  9. Jivlain says:

    Mike: look at the source. I’m assuming that means it’s IE only.

    <TR><TD><CODE>COLOR_BTNTEXT</CODE></TD>

       <TD><CODE>COLOR_BTNFACE</CODE></TD>

    <!–[if gte IE 5]>

       <TD BGCOLOR=buttonface><FONT COLOR=buttontext>sample</FONT></TD>

    <![endif]–><![if !gte IE 5]>

       <TD BGCOLOR=#ECE9D8><FONT COLOR=black>sample</FONT></TD>

    <![endif]>

       </TR>

  10. sandman says:

    @Mike: Thats not quite what Raymond’s done.

    What Raymond has done is to do it an IE>=v5 only section, and it falls back to using colour defined in the CSS/HTML specs if this  clause isn’t matched.

    For instance I don’t think windows colour names would work for me, running iceweasel on Debian.

    Raymond – thanks for doing this in a sensible backwards compatible way .

    [I have no choice. If I don’t do it, I get flamed. (See: VML.) -Raymond]
  11. MadQ says:

    @NoiseEHC: The color ListViews use for selected items when unfocused seems to be the COLOR_3DFACE. The background color of the selected column in detail view isn’t a system color. It seems to be the same hue as COLOR_WINDOW with different saturation and luminance values, which happens to clash with my preferred COLOR_3DFACE. It would be nice to know how the listview control creates that color. Does anyone know? Bueler? Bueler?

  12. I should point out that Office 2003 UI had some large number of colors that were carefully chosen by designers. How large – offhand, I recall that the spec contained something like ~200 x 4 colors in a matrix – we used them in many ways across the custom UI components in all Office apps. The colors mapped in one of 4 ways, depending on if the user was using one of the 3 XP theme colors or if they were running without themes (as was the case in Windows 2000). I can’t remember how we handled High Contrast Mode, but I am positive there were even more special cases for it.

    I didn’t work with Office 2007’s UI theming, so I can’t say what is different about it except that there is an option to set one of 3 skins for the UI: Blue, Silver, or Black.

    That’s just talking about the UI. For documents, Office has color schemes which are designed to contrast by default (and to help customers make schemes that contrast). In Office 2007, we standardized document color schemes across the core apps. The color schemes in Office 2007 give you 2 pairs of dark/light colors for text/background to chose from, 6 accent colors which in general should contrast well with both pairs of dark/light, and 2 hyperlink colors. Customers can add new themes via the UI which provides a little rendering of a chart to demonstrate how well the currently chosen colors would work against each other. These theme colors are used everywhere in Office 2007 so that to as much an extent as possible when you change the theme or color scheme, you change all colors used in your documents / presentations / worksheets.

    You can read more on the color schemes from the Lead PM of the Schemes/Styles team in Office 2007, Howard Cooperstein in one of his blog posts:

    http://blogs.msdn.com/jensenh/archive/2006/02/22/537054.aspx

    http://blogs.msdn.com/powerpoint/archive/2006/07/13/664413.aspx

    -Mike

  13. Zamboch says:

    Dan: could you please share your CSS for firefox ? Thanks!

    I like to have inverted windows theme as well, but because of issues with web pages, I would like to keep usual white background for firefox. Does anyone know how to hack firefox, so that it will use different colors for OS UI components like textbox ? Or how to change system colors for single application ?

  14. Grant says:

    [Maybe this is common knowledge among web developers – but i didn’t realize that you could use Windows system colors as named HTML colors]

    http://www.w3.org/TR/CSS2/ui.html#system-colors

    My understanding is these have been deprecated in CSS 3.0 because not all browsers implemented them the same way, making them worse than useless.

  15. Dan Cox says:

    My pet peeve in this arena are the large # of applications that honor your tooltip foreground color but not the background color. I like to use a darkish blue background and white-ish text. Becomes unreadable of course. ABC is a classic example of an app that does this – at least with the default theme and the smoke theme that I use.

  16. GreaseMonkey says:

    It probably *is* implemented in the Windows version of Firefox, as it was designed to be compatible with IE-based pages (minus ActiveX, of course).

    Oh, BTW, looks like that pingbacker got owned:

    http://www.absolutely-people-search.info/

    Look at the page source:

    <body>

    <?php

    Header( “HTTP/1.1 301 Moved Permanently” );

    Header( “Location: http://www.absolutely-free-people-searches.com” );

    ?>

    <p class=”style1″>&nbsp;</p>

    They didn’t even bother with a META redirect XD XD XD

    [That’s not ownage. That’s just part of their business model. -Raymond]
  17. ender says:

    I’ve used an inverted color scheme for years now, and the thing that’s most annoying is when programs hardcode some colors, but use the system colors for something else (usually by hardcoding the text to black while keeping the system background color).

    This makes me wonder, is an EULA I can’t see still legally binding?

  18. John Elliott says:

    The thing that gets me is those two-tone menus, where the highlight gets done by blending the window colour and the highlight colour. On my system I end up with unselected items as black-on-#F3F3F3 and the selected item as black-on-#F2F2F2.

  19. NoiseEHC says:

    Thanks for the answers! Probably it is time for Raymond to kick some ass at MS to finally in 2007 create a documentation about colors… I do not dare to even think about what happens in Vista…

  20. Daniel says:

    I’ve noticed the exact same problem with XYZ‘s control panel.  I’m not sure the exact constants they used, but when I look at the tree view down the left hand side, all of the text within is *completely invisible.*  White-on-white.

    On a related note, back when I had an ABC video card, they apparently had never tested their fancy control panel with different font sizes.  Because you couldn’t resize the window, I lost about 30% of the control panel off the sides, and almost none of the text was readable.

    Sometimes, I really wish companies would just stop trying to be clever; it only seems to cause problems.

  21. meh says:

    @NoiseEHC: Forgive me if I don’t understand a word of what you’re saying…

  22. NoiseEHC says:

    @meh:

    Translation:

    The conclusion is that there is no documentation about colors. The best I can hope for is that Raymond somehow pushes MS developers to document what colors they are using in Windows code since as you can see, a lot of programs cannot draw their UI consistent with the selected Windows color scheme. Clearly it is a little bit late in 2007 but better than never.

    Anyhow I thank you for the info you have given to me but somehow I feel that testing every control’s colors in every version of Windows (like Vista) is a little bit too much work for me…

    ps:

    If you still do not understand it then it is clearly the fault of my limited English skills.

  23. David Walker says:

    My window (background) color is a faint blue.  It’s easier on the eyes than stark white.

    Sometimes, Web pages or other apps will randomly set the window color to white or leave it at the user’s default — leaving some funny-looking patches of white and light blue scattered around.

    And as Raymond says, if an application displays text against the user’s default window color, it might not be visible.

  24. NoiseEHC says:

    BryanK, of course when I talk about colors I mean COLOR_INFOTEXT like system color indexes. For example what is the color of the SysLink Control? If I want to create a link control (for example in a data grid) then probably I want to match its color to the color of the system’s control.

    A page with control screen shots with numbered color constants would suffice on MSDN I think.

    [Publishing a diagram like the one you suggest would have precluded the introduction of visual styles. And then when people ask, “Why can’t Microsoft update the Windows look so it doesn’t look so dorky?”, I’ could tell them “Because NoiseEHC locked us into the dorky look.”  -Raymond]
  25. NoiseEHC says:

    Okay Raymond, for a table like that I will take the blame… :)

    My MSDN (for VS2005) says:

    COLOR_HOTLIGHT = 26

    Color for a hot-tracked item. Single clicking a hot-tracked item executes the item.

    See, after all, somebody at MS took the time in the last 2 years to document it. I think it is not too much to ask for a little table.

    IMHO owner drawn controls will never be compatible with UxTheme so matching colors would at least help if I do not want my UI to fall apart with a different color theme…

  26. NoiseEHC says:

    [And whatever answer you get will be wrong in Windows Vista+n (n>0), so what’s the point? (You already saw it happen – any answer from Windows 2000 was wrong in Windows XP when the GetThemeSysColor function was introduced.) -Raymond]

    Yes, that table should include all the Windows versions. To tell you the truth, I believe in that this themed controls thing is incompatible with custom drawn controls so I do not even try to keep them consistent (but it is clearly outside of this conversation). I would be totally happy if at least the colors would match.

    [For the table to be useful, it would have to include all future versions of Windows, too. Otherwise, your program breaks in Windows Vista+n. I don’t know whether the “predicting the future machine” or the “time travel machine” is higher priority over there in the research division. -Raymond]
  27. NoiseEHC says:

    [For the table to be useful, it would have to include all future versions of Windows, too. Otherwise, your program breaks in Windows Vista+n. I don’t know whether the “predicting the future machine” or the “time travel machine” is higher priority over there in the research division. -Raymond]

    I am aware of that this table would break down in future Windows versions. However I would be happy if my program would work OK with the existing versions.

    What you are arguing is effectively that GetThemeSysColor and GetSysColor and the like are useless because in Windows 2015 it is possible that for example they would have different gray colors for an unfocused ListView and TreeView. However what I would need is some documentation up to Windows 2008 for the mentioned two functions. The simplest documentation would be a table, that’s it.

    As I said I am certain of that this custom UI problem cannot even be solved but what I am proposing is better than the current unusable documentation syndrome.

    [I disagree that this is better than what we have today. Your proposal effectively guarantees that programs written today will stop working on future versions of Windows. -Raymond]
  28. Igor Levicki says:

    Why does Vista default file/folder selection has such a poor contrast? I am not that much visually impaired but I can barely notice it. Perhaps someone from Microsoft mixed and matched what they shouldn’t?

  29. cjacks says:

    I can’t tell you how many times I’ve had to shim up LOB apps with FakeLunaTheme because people got so overly psyched about theme support in .NET 2.0 that they used it everywhere, assuming nobody would ever use anything other than Luna. Ever.

    And, of course, my latest adventure (http://blogs.msdn.com/cjacks/archive/2007/12/07/investigating-windows-vista-compatibility-issues-by-decompiling-vb-code-don-t-be-afraid-to-cheat.aspx), whereby they decided Title Bar Text was a good text color for the background of the form. ‘Cause that will never be anything other than white. *sigh*

  30. BryanK says:

    > The best I can hope for is that Raymond somehow pushes MS developers to document what colors they are using in Windows code since as you can see, a lot of programs cannot draw their UI consistent with the selected Windows color scheme.

    No, that’s the wrong solution.  Documenting "the RGB value of COLOR_HIGHLIGHT under each theme" makes people rely on that info, and it changes with every OS release.  (Not to mention new themes!)  Documenting it would merely encourage people to say "well we know that the highlight color is this shade of blue, so we can paint text in all kinds of weird places in this app using #ffffff, and we can use COLOR_HIGHLIGHT as the background!"

    The *correct* way to do it is to figure out which row in the table above you need to use, and then use both system colors from that row.  If you’re actually painting a highlighted area, then use COLOR_HIGHLIGHTTEXT text with a COLOR_HIGHLIGHT background.  DON’T use #ffffff text on a COLOR_HIGHLIGHTTEXT background, because the RGB value for COLOR_HIGHLIGHTTEXT can change.

    (And in fact, users can already change the theme colors, so even *if* Microsoft decided to document the colors that they use, that documentation would be useless as soon as one user decides they want COLOR_HIGHLIGHTTEXT to be black and COLOR_HIGHLIGHT to be yellow, or something like that.  Now your program is painting white on yellow: exactly what people here are complaining about programs doing.)

    Alternately, if none of the rows in the table above work for whatever you’re painting, you MUST use explicit colors (e.g. #ffffff on #0, or whatever the equivalent is in win32).

  31. Ian Boyd says:

    i think NoiseEHC is wondering what COLOR_Xxx constant do i need to pass to GetSysColor or GetThemeSysColor in order to have the color that a SysLink uses for it’s text.

    i wouldn’t want to hard-code a blue-ish color – in case some preferences or OS change and links are not supposed to be blue anymore.

    But since the control text is blue-ish, it is probaby using one of:

      COLOR_HOTLIGHT

      COLOR_HIGHLIGHT

      COLOR_ACTIVECAPTION

      COLOR_INACTIVECAPTION

    But which one? A quick search of MSDN for COLOR_HOTLIGHT says, “Color for a hyperlink or hot-tracked item.”  So it seems a reasonable *assumption* that SysLink uses COLOR_HOTLIGHT for it’s text color – but it’s not a given.

    On the other hand, if i wanted to know the background color of a ListView control, GetSysColor offers no insights. i could do a reasonable guess and say COLOR_WINDOW, but who knows.

    Can’t really blame someone for guessing wrong…

    [And whatever answer you get will be wrong in Windows Vista+n (n>0), so what’s the point? (You already saw it happen – any answer from Windows 2000 was wrong in Windows XP when the GetThemeSysColor function was introduced.) -Raymond]
  32. Dean Harding says:

    I think what NoiseEHC is asking for is some documentation for each control that describes which of the system colours it uses for each "part". For example, for a tree view, you might have:

    background = COLOR_WINDOW

    normal text = COLOR_WINDOWTEXT

    selected background = COLOR_HIGHLIGHT

    selected text = COLOR_HIGHLIGHTTEXT

    selected, unfocues background = whatever it is

    etc

    The idea is that if you wanted to emulate a treeview control (or some part of it, e.g. owner draw) you can look up this table for that control.

    The values would have to be updated with each version of Windows, sure. And if the controls ever use a different COLOR_* for their drawing in a newer version of Windows it means any custom controls that try to emulate the functionality will be different, but that’s obviously going to be true anyway if you just guess.

    You can generally figure out which one is used by looking up GetSysColor, but it’s not always completely obvious (as in the case of the selected, unfocused "gray" background of the treeview control)

  33. Ian Boyd says:

    Will it always be appropriate to show text that is COLOR_WINDOWTEXT on a background that is COLOR_WINDOW? Or will that be different in Windows 3.1+n(n>0)?

    [I’m afraid you missed the point of the article. -Raymond]
  34. ender says:

    Speaking of COLOR_HOTLITE, it’s been available since Windows 98, right? How can you set this color without editing the registry directly or using TweakUI – the Appearance tab doesn’t let you do it.

  35. Dean Harding says:

    ender: I think you already answered your own question. I can’t believe I had to write that.

    Hehe, that’s fun :-)

Comments are closed.