def L(r, g, b):
r, g, b = [float(x) / 255 for x in (r, g, b)]
r, g, b = [(x/12.92 if x <= 0.03928 else ((x + 0.055) / 1.055) ** 2.4) for x in (r, g, b)]
return r * 0.2126 + g * 0.7152 + b * 0.0722

def bgcolor(r, g, b, setmin=0, setmax=255, setratio=7):
rgbmin = min(r, g, b)
rgbmax = max(r, g, b)
if r == g == b:
xr = xg = xb = 1
else:
xr, xg, xb = [(float(x) - rgbmin) / (rgbmax - rgbmin) for x in (r, g, b)]
color = [int(setmin + (setmax - setmin) * x) for x in (xr, xg, xb)]
newmax = setmax
newmin = setmin
ratiook = False
for n in range(255):
ratio = 1.05 / (L(*color) + 0.05)
colordiff = sum(255 - x for x in color)
if ratio > setratio:
ratiook = True
if ratiook and colordiff >= 500:
return ('#%02X%02X%02X' % tuple(color), ratio, colordiff)
break
if ratio > setratio and not ratiook:
newmin = newmin + 1
else:
newmax = newmax - 1
color = [int(newmin + (newmax - newmin) * x) for x in (xr, xg, xb)]

def fgcolor(r, g, b, setmin=0, setmax=255, setratio=7):
rgbmin = min(r, g, b)
rgbmax = max(r, g, b)
if r == g == b:
xr = xg = xb = 1
else:
xr, xg, xb = [(float(x) - rgbmin) / (rgbmax - rgbmin) for x in (r, g, b)]
color = [int(setmin + (setmax - setmin) * x) for x in (xr, xg, xb)]
newmax = setmax
newmin = setmin
ratiook = False
for n in range(255):
ratio = (L(*color) + 0.05) / 0.05
colordiff = sum(x for x in color)
if ratio > setratio and (not r == g == b or ratio < setratio + 0.5):
ratiook = True
if ratiook and colordiff >= 500:
return ('#%02X%02X%02X' % tuple(color), ratio, colordiff)
break
if ratio > setratio and not ratiook:
newmax = newmax - 1
else:
newmin = newmin + 1
color = [int(newmin + (newmax - newmin) * x) for x in (xr, xg, xb)]

def light(color, dividedby):
color = color.strip('#')
r, g, b = int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16)
r, g, b = [255 - int((255 - x) / dividedby) for x in (r, g, b)]
return '#%02X%02X%02X' % (r, g, b)

hue = ('200', '201', '202', '102', # red to blue
'002', '012', '089', '097', # blue to green
'020', '790', '980', '210', # green to red
'111')                      # gray

bgcolors = [bgcolor(int(h[0]), int(h[1]), int(h[2])) for h in hue]
fgcolors = [fgcolor(int(h[0]), int(h[1]), int(h[2]), setratio=12) for h in hue]
lightcolors = [(light(c[0], 2), light(c[0], 4), light(c[0], 10)) for c in fgcolors]

colors = zip(bgcolors, fgcolors, lightcolors)
table = '''<table style="border-spacing: 3px; border: 1px solid #B2B2B2; text-align: center">
<tr><th>Dark<br>color</th>
<th><a href="https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast7">Contrat ratio<br>level AAA</a></th>
<th><a href="https://www.w3.org/TR/AERT/#color-contrast">Color<br>difference</a></th>
<th>Light<br>color</th>
<th><a href="https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast7">Contrat ratio<br>level AAA</a></th>
<th><a href="https://www.w3.org/TR/AERT/#color-contrast">Color<br>difference</a></th>
<th>1/2 light<br>color</th>
<th>1/4 light<br>color</th>
<th>1/10 light<br>color</th></tr>
%s
</table>''' % '\n'.join('''<tr><td style="background-color:{0};color:white">{0}</td><td>{1:.2f}</td><td>{2}</td>
<td style="background-color:{3}">{3}</td><td>{4:.2f}</td><td>{5}</td>
<td style="background-color:{6}">{6}</td><td style="background-color:{7}">{7}</td>
<td style="background-color:{8}">{8}</td></tr>'''
.format(*(bg + fg + lt)) for bg, fg, lt in colors)
from IPython.core.display import display, HTML
display(HTML(table))

Dark
color
Contrat ratio
level AAA
Color
difference
Light
color
Contrat ratio
level AAA
Color
difference
1/2 light
color
1/4 light
color
1/10 light
color
#B600007.03583 #FFAFAF12.00605 #FFD7D7#FFEBEB #FFF7F7
#B000587.03501 #FFABD512.04639 #FFD5EA#FFEAF5 #FFF7FB
#8400849.07501 #FFA4FF12.01674 #FFD2FF#FFE9FF #FFF6FF
#5800B110.24500 #DAB5FF12.03654 #EDDAFF#F6EDFF #FCF8FF
#0000FF8.59510 #BFBFFF12.11637 #DFDFFF#EFEFFF #F9F9FF
#0057AF7.04503 #93C9FF12.04603 #C9E4FF#E4F2FF #F5FAFF
#00626F7.05556 #11E4FF13.57500 #88F2FF#C4F9FF #E8FDFF
#00654E7.07586 #27FFCF16.29501 #93FFE7#C9FFF3 #EAFFFB
#0068007.05661 #7BFF7B16.43501 #BDFFBD#DEFFDE #F2FFF2
#4A60007.08595 #CFFF2717.99501 #E7FF93#F3FFC9 #FBFFEA
#6559007.04575 #FFE41116.36500 #FFF288#FFF9C4 #FFFDE8
#8C46007.02555 #FFB56B12.07543 #FFDAB5#FFEDDA #FFF8F1
#5858587.11501 #C7C7C712.42597 #E3E3E3#F1F1F1 #FAFAFA