Matching Brightness of Two Different Colors
You can calculate the perceived gray-scale brightness of a color on a “typical” monitor with the following formula:
Y = 0.2126 * (R/255)^2.2 + 0.7151 * (G/255)^2.2 + 0.0721 * (B/255)^2.2
So, for example, high saturation pure green (0, 255, 0) has a brightness of:
Y = 0.2126 * (0/255)^2.2 + 0.7151 * (255/255)^2.2 + 0.0721 * (0/255)^2.2
Y = 0.7151
For shades of yellow, I’ll assume you mean colors where R = G, and B = 0. Let X = R = G. So the brightness of yellow is:
Y = 0.2126 * (X/255)^2.2 + 0.7151 * (X/255)^2.2 + 0.0721 * (0/255)^2.2
Y = (0.2126 + 0.7151) * (X/255)^2.2
Y = 0.9277 * (X/255)^2.2
Solving for X:
X = ((Y/0.9277) ^ 0.4545) * 255
So to match the brightness of green (Y = 0.7151):
R = G = X = ((0.7151/0.9277) ^ 0.4545) * 255 = 227
Or, an RGB of 227, 227, 0. Pretty close to what your eyeballs told you. It’s never exact in any case because monitors vary from one to another.
Matching Contrast between Two Pairs of Colors
Two colors with the same Y value will appear equally bright (except for monitor variations). To get two pairs of colors with equal brightness contrast (e.g. to get green text on a greenish background to be as legible as yellow text on a yellowish background), you need to calculate and compare the contrast of each pair. To get contrast, calculate the Y’s for each color in a pair (call them Y1 and Y2), and calculate the brightness ratio C for each pair:
C = (Y1 + 0.05) / (Y2 + 0.05)
For comparing brightness ratios, always put the brighter color (larger Y) on top.
To match contrasts, adjust the colors until the C for both pairs is equal. You have four colors, so there are a lot of options. For example, in your table, the red “Foo” is 255, 0, 0, so Y2 = 0.2126. It’s pale red background is 255, 221, 221, so Y1 = 0.7873. The brightness ratio is:
C = (0.7873 + 0.05) / (0.2126 + 0.05) = 3.19
For the yellow “Foo” (255, 255, 0) on the pale yellow background (255, 255, 221):
C = (0.9804 + 0.05) / (0.9278 + 0.05) = 1.05
The lower the contrast, the harder it is to read, which is why your yellow on pale yellow is harder to see than your red on pale red.
One way to match the contrast of yellow to your red is, as you suggest, to darken the yellow. Cut-and-try (because I’m too lazy to derive another formula) finds that 146, 146, 0 does the job:
C = (0.9804 + 0.05) / (0.2720 + 0.05) = 3.20
The darkened yellow’s Y (0.2720) is brighter than your red’s Y (0.2126) because you’re showing the yellow on a brighter background (0.9804 vs. 0.7873)
BTW, for accessibility, W3C recommends C of text on a background be at least 3.0.
Why is Yellow so Bright?
The human eye evolved to be most sensitive to the strongest light frequencies found on Earth in daytime. That would be light from the sun. The sun is strongest around the yellow frequencies (that’s why it looks yellow), so that’s why yellow appears brightest to us. As an added kicker, LCDs make yellow by shining light through two subpixels rather than one (e.g., like green does). Second brightest are the frequencies near yellow –green, cyan, and orange, so high-saturation values of these contrast poorly with pale colors and well with dark colors. The frequencies furthest from yellow, blue and red, appear darkest, and their high-saturation values contrast relative well on pale colors and poorly on dark.
I’ve more details on colors and contrast at Breaking the Color Code.