Přejít na výběr barvy

CSS color-mix() a relativní barvy: světlejší varianty, hover a průhlednost

color-mix() smíchá dvě barvy v barevném prostoru, který si zvolíte, a syntaxe relativních barev vám dovolí upravit jeden kanál existující barvy, například oklch(from var(--brand) calc(l - 0.1) c h). Obojí běží v prohlížeči, funguje s proměnnými CSS a nahradí většinu barevných funkcí Sass. Světlejší varianty a hover míchejte v oklab, průhlednost v srgb.

Čtení na 6 min

Jak funguje color-mix()

color-mix() přijme barevný prostor a dvě barvy s nepovinnými procenty a vrátí barvu mezi nimi. color-mix(in oklab, var(--brand) 90%, black) znamená 90 % firemní barvy a 10 % černé, smíchané v Oklab. Když zadáte jedno procento, druhá barva dostane zbytek. Když nezadáte žádné, každá dostane 50 %.

Prohlížeč počítá výsledek za běhu, takže to funguje s vlastními vlastnostmi, currentColor i přepínáním motivů. Funkce Sass proběhnou jednou při sestavení a hodnoty var() nevidí.

Pokud obě procenta dají dohromady méně než 100 %, výsledek bude navíc částečně průhledný: color-mix(in srgb, red 30%, blue 30%) je rovnoměrná směs s krytím 60 %. Pokud to nechcete, držte součet na 100 %.

CSS

.button {
    --brand: #2563eb;
    background: var(--brand);
}

.button:hover {
    background: color-mix(in oklab, var(--brand) 90%, black);
}

.badge {
    background: color-mix(in oklab, var(--brand) 10%, white);
    border-color: color-mix(in srgb, var(--brand) 30%, transparent);
}

V jakém barevném prostoru míchat: srgb, oklab, nebo oklch

Prostor mění výsledek víc, než by většina lidí čekala. Níže je čistá modrá #0000ff smíchaná půl na půl s čistou žlutou #ffff00, spočítaná stejnou matematikou, jakou používá prohlížeč.

V srgb se kanály zprůměrují přesně na 128, 128, 128: směs je #808080, šedá s nulovou chroma. Oklab také míchá po přímce a modrá se žlutou leží na jejích opačných stranách, takže se většinou vyruší do matné šedomodré. Oklch místo toho interpoluje úhel tónu a jde kratší cestou z 264° na 110°, takže uprostřed je sytá modrozelená s tónem 187°, která si drží chroma obou vstupů.

ProstorModrá + žlutáOKLCH L, CBlue-600 + yellow-400OKLCH L, C
srgb#8080800.600, 0#9098800.665, 0.035
oklab#6cabc70.710, 0.077#90a3ad0.703, 0.026
oklch#00bdb00.710, 0.262#00bd9e0.703, 0.194

Druhá dvojice jsou barvy #2563eb a #facc15 z Tailwindu. Výsledky v oklch leží mimo sRGB, proto je chroma uvedena před mapováním do gamutu a HEX je nejbližší barva, kterou obrazovka sRGB umí zobrazit.

Dvě věci stojí za pozornost. Srgb skončí na světlosti 0,600, zatímco vnímaný střed mezi modrou (0,452) a žlutou (0,968) je 0,710: to je ten tmavý, kalný střed gradientů v srgb. A jen oklch udrží směs sytou, za cenu průchodu tónem, který nemá ani jeden vstup.

Orientační pravidlo: světlejší a tmavší varianty a stavy hover míchejte v oklab, kde zůstáváte u jednoho tónu a chcete rovnoměrné kroky světlosti. V oklch míchejte, když jsou obě barvy syté a chcete sytý výsledek. V srgb míchejte průhlednost, protože odpovídá tomu, jak prohlížeč skládá vrstvy.

Recepty: hover, světlá pozadí a průhledné varianty

Všechny hodnoty níže používají #2563eb jako --brand. Bílý text na ní má kontrastní poměr 5,17:1.

Přimíchání 10 % černé ztmaví v oklab víc než v srgb: bílý text stoupne na 6,50:1 proti 6,11:1. Oklab a oklch dávají stejný výsledek, když je druhou barvou černá nebo bílá, protože ty nemají tón, který by se interpoloval.

ReceptCSSVýsledekKontrast
Hover, o 10 % tmavšícolor-mix(in oklab, var(--brand) 90%, black)#1f55cc6.50:1 s bílým textem
Active, o 20 % tmavšícolor-mix(in oklab, var(--brand) 80%, black)#1947ae8.22:1 s bílým textem
Hover míchaný v srgbcolor-mix(in srgb, var(--brand) 90%, black)#2159d36.11:1 s bílým textem
Světlé pozadí, 10 %color-mix(in oklab, var(--brand) 10%, white)#e8f0ff4.51:1 s firemním textem
Světlé pozadí, 20 %color-mix(in oklab, var(--brand) 20%, white)#d2e2ff3.95:1 s firemním textem
Průhledná, 20 %color-mix(in srgb, var(--brand) 20%, transparent)rgba(37, 99, 235, 0.2)Na bílé vypadá jako #d3e0fb

Pozor na světlá pozadí. Text ve firemní barvě má na bílé 5,17:1, na 10% pozadí 4,51:1 a na 20% pozadí jen 3,95:1, což u běžného textu neprojde WCAG AA. Když dáváte text ve firemní barvě na její světlé pozadí, použijte pro text tmavší barvu ze stavu hover.

Míchání s transparent zachová barvu a sníží jen alfa kanál, protože prohlížeč míchá hodnoty s předem vynásobenou alfou. Výsledek se přizpůsobí tomu, co je pod ním: stejné pravidlo vypadá na bílé jako #d3e0fb a na tmavém povrchu #0f172a jako #132651. Světlé pozadí smíchané s bílou zůstane na tmavé stránce bledý, takže pro komponenty, které se objevují v obou motivech, je průhledná varianta obvykle lepší volba.

Syntaxe relativních barev: úprava jednoho kanálu

Syntaxe relativních barev vezme existující barvu, rozloží ji na kanály a dovolí vám kterýkoli z nich přepsat pomocí calc(). V oklch(from var(--brand) l c h) obsahují klíčová slova l, c a h světlost (0 až 1), chroma a tón barvy --brand.

Na rozdíl od color-mix() mění přesně jednu vlastnost: sníží světlost, aniž by sáhla na chroma, otočí tón beze změny světlosti nebo přidá alfa kanál barvě uložené jako HEX.

ReceptCSSVýsledek z #2563ebBílý text
Tmavšíoklch(from var(--brand) calc(l - 0.1) c h)#0442c88.02:1
Světlejšíoklch(from var(--brand) calc(l + 0.1) c h)#4484ff3.51:1
Poloviční chromaoklch(from var(--brand) l calc(c * 0.5) h)#4e6faf4.98:1
Tón +30°oklch(from var(--brand) l c calc(h + 30))#7a49df5.46:1
Komplementárníoklch(from var(--brand) l c calc(h + 180))#9567004.98:1
Šedá se stejnou světlostíoklch(from var(--brand) l 0 h)#7070704.95:1
Alfa 50 %oklch(from var(--brand) l c h / 0.5)rgba(37, 99, 235, 0.5)Záleží na pozadí

CSS

:root {
    --brand: #2563eb;
    --brand-hover: oklch(from var(--brand) calc(l - 0.08) c h);
    --brand-muted: oklch(from var(--brand) l calc(c * 0.5) h);
    --brand-ring: oklch(from var(--brand) l c h / 0.4);
    --accent: oklch(from var(--brand) l c calc(h + 30));
}

Podívejte se na čtyři řádky, které ponechávají l: změna chroma nebo tónu posune kontrast bílého textu jen mezi 4,95:1 a 5,46:1, proti 5,17:1 u původní barvy. Kontrast určuje světlost, takže varianty tónu vytvořené tímto způsobem mají zhruba stejnou přístupnost. Světlejší a komplementární barva leží při plné chroma mimo sRGB a prohlížeč je namapuje na nejbližší barvu, kterou umí zobrazit.

color-mix(), relativní barvy, nebo Sass darken()

color-mix() použijte, když uvažujete ve smyslu „trochu černé“ nebo „trochu průhlednosti“. Syntaxi relativních barev použijte, když uvažujete v kanálech: „stejná barva, o 0,1 tmavší“. Obojí nahradí většinu barevných funkcí Sass a přizpůsobí se změně motivu bez nového sestavení.

color-mix()Syntaxe relativních barevSass darken()
Kde běžíV prohlížečiV prohlížečiPři sestavení
Funguje s var() a currentColorAnoAnoNe
Barevný modelProstor, který zadáte: srgb, oklab, oklch, hsl a dalšíJakákoli barevná funkce: oklch(), rgb(), hsl(), lab()Jen HSL
Nejlepší naSvětlejší a tmavší varianty, průhlednost, míchání dvou tokenůZměnu jednoho kanálu: světlosti, chroma, tónu nebo alfyStarý kód s pevnými barvami
Velikost krokuPodíl vzdálenosti k druhé barvěPřesná, v jednotkách kanáluPevné body HSL, pro oko nerovnoměrné
Podpora odChrome 111, Safari 16.2, Firefox 113Chrome 119, Safari 18, Firefox 128Jakýkoli prohlížeč, výstup je statický

Proč Sass darken() dává nerovnoměrné kroky

darken($color, 10%) odečte 10 bodů světlosti v HSL. Světlost v HSL není vnímaná světlost, takže viditelná změna závisí na tónu. Tady je darken(10%) vedle oklch(from … calc(l - 0.1) c h) na čtyřech běžných barvách rozhraní, měřeno v ΔE OK, kde zhruba 0,02 je nejmenší rozdíl, který postřehnete.

BarvaSass darken(10%)ΔE OKOKLCH l − 0.1ΔE OK
#2563eb#134cca0.078#0442c80.099
#facc15#d7ad050.099#d9ab000.101
#16a34a#1076360.136#00842b0.094
#dc2626#b21d1d0.090#b700000.089

Stejné darken(10%) změní zelenou 1,7krát víc než modrou. Verze v OKLCH zůstává u každého tónu mezi 0,089 a 0,101, malý rozptyl způsobuje mapování do gamutu, protože některé tmavší barvy vypadnou těsně mimo sRGB. Samotný Sass doporučuje místo darken() color.adjust() nebo color.scale() a v čistém CSS nepotřebujete ani jedno.

Podpora v prohlížečích a záložní řešení

color-mix() funguje v Chrome a Edge 111, Safari 16.2 a Firefoxu 113, všechny vyšly v roce 2023. Syntaxe relativních barev přišla v Chrome a Edge 119 a Firefoxu 128, Safari dodalo ranou verzi v 16.4 a současnou syntaxi v Safari 18. Všechny aktuální prohlížeče podporují obojí.

Obvyklý trik s prostou hodnotou na řádku předtím nefunguje, když nová hodnota obsahuje var(). Deklarace s var() se při parsování přijme vždy, takže prohlížeč váš záložní řádek zahodí, a pokud color-mix() spočítat neumí, použije zděděnou nebo výchozí hodnotu. Moderní verzi proto zabalte do @supports.

CSS

.button:hover {
    background: #1f55cc;
}

@supports (color: color-mix(in oklab, red, blue)) {
    .button:hover {
        background: color-mix(in oklab, var(--brand) 90%, black);
    }
}

@supports (color: oklch(from red l c h)) {
    .badge {
        border-color: oklch(from var(--brand) l c h / 0.3);
    }
}

Otázky a odpovědi

Co dělá color-mix() v CSS?

color-mix() smíchá dvě barvy v barevném prostoru, který zadáte, a vrátí výsledek, například color-mix(in oklab, var(--brand) 90%, black) pro barvu o 10 % tmavší než firemní. Běží v prohlížeči, takže funguje s proměnnými CSS i currentColor.

Jaký barevný prostor použít v color-mix()?

Pro světlejší a tmavší varianty a stavy hover použijte oklab, protože dává rovnoměrné kroky světlosti a drží tón. Oklch použijte při míchání dvou sytých barev, když chcete sytý výsledek, a srgb při míchání s transparent. Modrá a žlutá smíchané v srgb dají plochou šedou #808080, v oklch sytou modrozelenou.

Jak v čistém CSS ztmavit barvu při hover?

Použijte background: color-mix(in oklab, var(--brand) 90%, black) nebo background: oklch(from var(--brand) calc(l - 0.1) c h). Pro #2563eb dá první #1f55cc a druhé #0442c8, čímž se kontrast bílého textu zvýší z 5,17:1 na 6,50:1 a 8,02:1.

Jak udělat barvu z proměnné CSS průhlednou?

Napište color-mix(in srgb, var(--brand) 20%, transparent) nebo oklch(from var(--brand) l c h / 0.2). Obojí funguje, i když je --brand uložená jako HEX, a samotnou barvu nemění, snižuje jen její krytí.

Podporují color-mix() všechny prohlížeče?

Ano, podporují ho všechny aktuální prohlížeče: Chrome a Edge od verze 111, Safari od 16.2 a Firefox od 113. Pro starší prohlížeče dejte nejdřív statickou barvu a verzi s color-mix() do @supports, protože řádek s var() se sám na záložní hodnotu vrátit neumí.

Jaký je rozdíl mezi color-mix() a syntaxí relativních barev?

color-mix() míchá dvě barvy v daném poměru, což se hodí na světlejší a tmavší varianty a průhlednost. Syntaxe relativních barev, například oklch(from var(--brand) l c calc(h + 30)), přepisuje jednotlivé kanály jedné barvy, což se hodí na přesné kroky světlosti, posuny tónu a alfa kanál.

Vyzkoušejte v PickShade

Související návody