RGB color in Python: three numbers behind every color
Sage, oat, clay, navy. Your brand's colors have names for people, but every screen needs numbers: how much red, how much green, how much blue.
The big idea
A screen color is three numbers from 0 to 255 for red, green, and blue, often written as a six-digit hex code.
See it in code
Store a color as three numbers and unpack them into named channels:
sage = (138, 154, 91)
red, green, blue = sage
print("Red:", red, "| Green:", green, "| Blue:", blue)
print("Strongest channel:", max(sage))Red: 138 | Green: 154 | Blue: 91 Strongest channel: 154
Green is the largest value and blue the smallest, which is why sage reads as a muted, yellowish green. Equal values in all three would give a gray.
Websites write the same three numbers in hexadecimal, two digits per channel. The format spec :02x converts each one:
red, green, blue = 138, 154, 91
hex_code = f"#{red:02x}{green:02x}{blue:02x}"
print("Sage in hex:", hex_code)
print("White in hex:", f"#{255:02x}{255:02x}{255:02x}")Sage in hex: #8a9a5b White in hex: #ffffff
8a, 9a, and 5b are 138, 154, and 91 written in base 16. ff is 255, the maximum, so #ffffff is all three channels at full: white.
Because colors are numbers, you can compute with them. Moving each channel part of the way toward 255 produces a lighter tint of the same hue:
palette = {"sage": (138, 154, 91), "oat": (222, 205, 170), "clay": (182, 106, 80), "navy": (31, 42, 68)}
def to_hex(color):
red, green, blue = color
return f"#{red:02x}{green:02x}{blue:02x}"
def tint(color, amount=0.5):
return tuple(round(channel + (255 - channel) * amount) for channel in color)
for name, color in palette.items():
print(f"{name:<5} {to_hex(color)} tint {to_hex(tint(color))}")sage #8a9a5b tint #c4ccad oat #decdaa tint #eee6d4 clay #b66a50 tint #dab4a8 navy #1f2a44 tint #8f94a2
tint closes half the gap between each channel and 255. All three channels move together, so the color gets lighter without changing character.
Images are grids of these triples. Generative art picks them at random, data charts map values onto them, and Tailwind's bg-slate-950 is a name for one specific triple.
Try it yourself
Write shade(color, amount) that moves each channel toward 0 instead of 255, for a darker version. Then compute the average of two palette colors, channel by channel, to blend them.
The common mistake
Letting a channel leave the 0 to 255 range. Adding 100 to every channel of oat pushes red to 322, which isn't a valid color. Scale toward a limit, or clamp with min(255, value).
What it unlocks
A color triple is a tuple, a named palette is a dictionary, and hex formatting is an f-string trick. On the web, Tailwind's color classes name these values for you.