HEX, RGB, HSL a novější barevné prostory

Jak spolu souvisejí HEX, RGB, HSL, LCH a OKLCH, proč paleta v HSL ve středních tónech zašpiní a co s výslednou barvou udělá ořez gamutu a kompozice s alfa kanálem.

Barva v CSS jsou tři nebo čtyři čísla plus pravidlo, jak je číst: barevný prostor. Palety, které na obrazovce vypadají nerovnoměrně, jsou obvykle odstupňované v prostoru, který neodpovídá tomu, jak funguje zrak.

HEX a RGB jsou tatáž čísla

#3B82F6 jsou tři bajty v šestnáctkové soustavě: 3B je 59, 82 je 130, F6 je 246, takže rgb(59, 130, 246) je tatáž barva v desítkové soustavě a převodník barev mezi nimi přechází beze ztráty.

Třímístná zkratka každou číslici zdvojí, místo aby ji doplnila nulou, takže #F80 se rozvine na #FF8800, ne na #F08000; krátkou podobu má jen 4096 barev. #RGBA přidává stejným způsobem číslici pro alfu a #RRGGBBAA vypisuje všechny čtyři bajty, přičemž tento alfa bajt jde od 0 do 255 (1A je 10 %, 80 je 50 %, CC je 80 %), zatímco každá jiná alfa v CSS jde od 0 do 1. Moderní syntaxe přijímá i složky oddělené mezerami s alfou za lomítkem: rgb(59 130 246 / 50%).

Tato čísla nejsou množství světla. sRGB kóduje každý kanál přes přenosovou křivku zhruba 2,2, takže 128 vyzáří asi 21,6 % světla oproti 255, ne polovinu, a každé mísení počítané na surových hodnotách tuto křivku zdědí.

HSL, HSV a světlost, která žádnou světlostí není

HSL přeskládává tutéž krychli RGB do válce: odstín je úhel (0 červená, 120 zelená, 240 modrá), sytost je vzdálenost od centrální šedé osy a světlost jde od 0 přes 50 %, kde je čistý odstín, až ke 100 %, což je bílá. HSV vyměňuje světlost za hodnotu, jejímž vrcholem je čistý odstín místo bílé, takže světlé varianty vznikají snížením sytosti. Ani jeden z nich neví o vnímání nic.

BarvaHSLRelativní luminanceSvětlost v OKLCH
#FFFF00hsl(60 100% 50%)0,9280,97
#0000FFhsl(240 100% 50%)0,0720,45

Obě si nárokují 50% světlost; jedna vyzařuje asi třináctkrát víc světla než druhá. Řada tokenů, kde je každý odstín přišpendlený na 50%, působí jako změť různých vah.

Odstupňování světlosti v HSL při pevném odstínu a sytosti selhává ze stejného důvodu a ještě z jednoho: sytost se měří vůči prostoru dostupnému při dané světlosti, takže krok na 50 % je nejbarevnější a všechno na obě strany vybledá. Úhel odstínu přitom drží, zatímco vnímaná chroma se hroutí, a právě to způsobuje, že střední kroky vypadají zašpiněně. Nejsou to ztmavené základní barvy, jsou to základní barvy zešedlé o hodnotu, kterou nikdo nevybral.

Nejhůř to ukazuje žlutá. Snižování světlosti v HSL odvede žlutou rovnou do olivové, protože tmavá žlutá na tom úhlu odstínu prostě olivová je, a udržet ji žlutou znamená cestou dolů otáčet odstín směrem k oranžové. Modrá má opačný problém, leží v luminanci tak nízko, že celá její použitelná variace žije nad 50 %.

LCH a OKLCH

LCH je polární forma CIE Lab, postavená na experimentech s párováním barev: světlost 0 až 100, chroma (barevnost, bez pevného maxima) a úhel odstínu. OKLCH má stejný tvar nad Oklabem, který opravuje posuny odstínu, jimiž je Lab známý, nejviditelněji modré ujíždějící do fialové, jak se zesvětlují.

.a { color: oklch(0.62 0.21 260); }        /* L 0 to 1, C about 0 to 0.37, H in degrees */
.b { color: oklch(62% 0.21 260 / 50%); }   /* percentages and alpha both allowed */
.c { color: lch(52% 82 285); }             /* L runs 0 to 100 here */

Percepční uniformita znamená, že stejná číselná vzdálenost je blízko stejné vnímané vzdálenosti. Škála po krocích 0,08 světlosti vypadá jako rovnoměrné kroky, řada odstínů přišpendlená na jednu světlost působí jako jedna řada a změna světlosti nechá odstín tam, kam jste ho dali. Interpolace může tento prostor použít také, jako v linear-gradient(in oklch, #0000FF, #FFFF00). Jedno varování: světlost v OKLCH je zdánlivému jasu mnohem blíž než HSL, ale není to vzorec luminance podle WCAG, takže textové dvojice pořád prožeňte kontrolou kontrastu.

Gamut a ořez

Gamut je množina barev, které prostor dokáže vyjádřit. sRGB je dlouhodobě výchozí; Display P3 pokrývá zhruba o čtvrtinu víc viditelných barev, přičemž skoro celý zisk leží v sytých červených a zelených. Chroma v OKLCH není omezená, takže zapsat barvu, kterou žádná obrazovka neukáže, je snadné.

@supports (color: color(display-p3 1 1 1)) {
  .vivid { background: color(display-p3 0.9 0.1 0.14); }
}

Ořez po kanálech vrátí barvu mimo gamut zpět tak, že každý kanál nezávisle přišpendlí na jeho mez, což posune odstín a slepí sousední odstíny na jednu hodnotu, takže se přechody pruhují a detail mizí. CSS Color 4 místo toho mapuje: drží světlost a odstín a snižuje chromu v OKLCH, dokud se barva nevejde.

Proto může snímek obrazovky se sytou fotkou vypadat ploše. Fotka nese profil P3 a displej ji zobrazí naplno; export převedený do sRGB namačká ty syté pixely do menšího objemu a červené a zelené mají nejdelší cestu.

Kompozice s alfa kanálem

Poloprůhledná barva nad podkladem vytvoří třetí, neprůhlednou barvu, kanál po kanálu:

result = alpha * source + (1 - alpha) * backdrop

Černá na 50 % nad bílou dá (127.5, 127.5, 127.5), tedy #808080. Z této shody okolností pochází představa, že „černá s 50% krytím je šedá“, a platí na bílé a nikde jinde: tatáž černá nad #3B82F6 dá zhruba #1E417B, tmavou modrou, a nad fotografií dá v každém pixelu jinou barvu. Poloprůhledná černá je ztmavovací operátor, ne šedá.

Kompozice běží na kódovaných hodnotách, takže #808080 má relativní luminanci asi 0,216, ne 0,5. Měřte výslednou hex hodnotu, nikdy tu deklarovanou. Ani alfa se nevrství, jak by člověk čekal: dvě vrstvy po 50 % pokryjí 75 %, protože ta druhá působí jen na to, co první propustila.

Zesvětlení, ztmavení, tóny a harmonie

PojemTradiční receptV OKLCH
Tint (zesvětlení)základ plus bílázvýšit L, mírně snížit C
Shade (ztmavení)základ plus černásnížit L
Tone (zešednutí)základ plus šedásnížit C při pevném L

Harmonie jsou posuny odstínu. Vyberou akcent; systém nepostaví.

HarmoniePosunyK čemu je dobrá
Komplementární+180°jeden akcent proti dominantnímu odstínu, i když při sytosti obou vibruje
Analogická±30°klidná seskupení, pozadí, stavy uvnitř jedné rodiny
Triadická+120°, +240°kategoriální sady, například série v grafu

Posuny na kruhu RGB nejsou percepčně rovnoměrné, protože tento kruh věnuje zelené nepoměrně velký oblouk, takže vypočítanou harmonii berte jako první návrh a dolaďte ji okem. Generátor palet, který z jednoho základu staví zesvětlení, ztmavení a harmonie, dostane takový návrh na obrazovku rychle.

Neutrální škála si žádá vlastní rozhodnutí. Čistá šedá, kde se červená, zelená i modrá rovnají, působí vedle barevného rozhraní mrtvě a lehce špinavě. Dejte neutrálům malou chromu, zhruba 0,005 až 0,02 v OKLCH, blízko firemnímu odstínu: teplé šedé kolem 60° až 90° působí jako papír, studené šedé kolem 250° působí technicky. Směrem k nejsvětlejším krokům tuto chromu ztenčujte, aby pozadí nevypadala zabarveně.

Barvoslepost

Zhruba 1 z 12 mužů a 1 z 200 žen má poruchu barvocitu. Téměř celý podíl tvoří červeno-zelené typy, s velkým náskokem deuteranomálie; modro-žluté tritanové typy postihují méně než 1 z 10 000.

Záměny, na kterých v rozhraních záleží, jsou červená proti zelené při podobné světlosti, zelená proti hnědé a oranžové, fialová proti modré a růžová proti šedé. Protanopické vidění navíc červené ztmavuje, takže červená zvolená kvůli naléhavosti může skončit jako nejtišší věc na obrazovce.

Barva proto nikdy nesmí být jediným nositelem významu. Ke každému stavu přidejte popisek, ikonu, tvar nebo pozici a zajistěte, aby se párové stavy lišily i světlostí, nejen odstínem, protože červená a zelená se shodnou světlostí v OKLCH jsou nejhorší možná kombinace. Převod snímku obrazovky do stupňů šedi takové kolize odhalí během několika sekund.