HSV to HEX: from picker numbers to CSS
Most desktop color pickers show three numbers labelled H, S and B (or V). CSS has no hsv() function, so those numbers cannot be pasted into a stylesheet as they are. This HSV to HEX converter turns them into the hex code every browser, design tool and brand guide understands.
HSB and HSV are the same model under two names, and the tool accepts both spellings: hsv(210, 80%, 90%) and hsb(210, 80%, 90%) give the same result.
The conversion, step by step
HSV is converted to RGB first, then each channel is written in base 16. With S and V as fractions:
C = V × S (chroma)
X = C × (1 − |(H / 60) mod 2 − 1|)
m = V − C
0–60°: (C, X, 0) 60–120°: (X, C, 0) 120–180°: (0, C, X)
180–240°: (0, X, C) 240–300°: (X, 0, C) 300–360°: (C, 0, X)
R, G, B = (component + m) × 255, rounded
Worked example: hsb(210, 80%, 90%)
C = 0.9 × 0.8 = 0.72. H / 60 = 3.5, so X = 0.72 × (1 − 0.5) = 0.36, and m = 0.9 − 0.72 = 0.18. The hue falls in the 180–240° sector, giving (0, X, C):
R = (0 + 0.18) × 255 = 45.9 → 46 → 2E
G = (0.36 + 0.18) × 255 = 137.7 → 138 → 8A
B = (0.72 + 0.18) × 255 = 229.5 → 230 → E6
hsb(210, 80%, 90%) → #2E8AE6
Notice that the largest channel is always V × 255 (here 229.5) and the smallest is V × (1 − S) × 255 (here 45.9). That makes a quick sanity check on any result.
Accepted input and edge cases
- Percent signs are optional:
210 80 90works, and so do fractions such ashsv(207, 0.61, 0.71). - A hue of 360 is the same as 0, so
hsv(360, 100%, 100%)gives#FF0000. - Value 0 is always black, whatever the hue and saturation.
- Opacity comes from the Alpha (opacity) slider, not from a fourth number.
hsv(9, 72%, 100%)at 50% becomes the 8-digit#FF634780.
Picker values are rounded
Pickers usually display whole numbers, while the color underneath may be stored more precisely. Converting hsv(207, 61%, 71%) gives #4783B5, one step away from steelblue's #4682B4. If the picker lets you copy a hex code directly, that is the exact value; otherwise expect an occasional difference of one in a channel.
For the reverse direction use HEX to HSV. If you need channel numbers instead of a code, try HSV to RGB, and the random color generator is handy for testing inputs.
Convert HSV to HEX in Python
There is no single function for HSV to HEX in Python; it takes two steps. colorsys.hsv_to_rgb() turns the HSV values, scaled to 0–1, into RGB fractions, then each channel is multiplied by 255, rounded and written as two hex digits. The detail that goes wrong is the format code. 02X pads to two digits, whereas a plain X or hex() writes a channel below 16 as a single digit and leaves you with a code that is too short.
import colorsys
def hsv_to_hex(h, s, v):
"""h in degrees, s and v in percent; returns #RRGGBB."""
rgb = colorsys.hsv_to_rgb(h / 360, s / 100, v / 100)
return "#" + "".join(f"{round(c * 255):02X}" for c in rgb)
print(hsv_to_hex(9, 72, 100)) # #FF6347
print(hsv_to_hex(207, 61, 71)) # #4783B5
print(hsv_to_hex(146, 67, 55)) # #2E8C57
print(hsv_to_hex(240, 100, 3)) # #000008, padding keeps six digits
Run the example, then enter the same values in the tool above to check that the codes agree; for the reverse conversion, use HEX to HSV.