![Adam Argyle](https://web.dev/images/authors/argyle.jpg) Adam Argyle [X](https://twitter.com/argyleink) [GitHub](https://github.com/argyleink) [Bluesky](https://bsky.app/profile/nerdy.dev)

<br />

The CSS [`color-mix()`](https://www.w3.org/TR/css-color-5/#funcdef-color-mix)
function lets you mix colors, in any of the supported color spaces, right from your CSS.


Browser Support

- ![Chrome: 111.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='-10 -10 276 276'%3E%3ClinearGradient id='a' x1='145' x2='34' y1='253' y2='61' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%231e8e3e'/%3E%3Cstop offset='1' stop-color='%2334a853'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' x1='111' x2='222' y1='254' y2='62' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fcc934'/%3E%3Cstop offset='1' stop-color='%23fbbc04'/%3E%3C/linearGradient%3E%3ClinearGradient id='c' x1='17' x2='239' y1='80' y2='80' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23d93025'/%3E%3Cstop offset='1' stop-color='%23ea4335'/%3E%3C/linearGradient%3E%3Ccircle cx='128' cy='128' r='64' fill='%23fff'/%3E%3Cpath fill='url(%23a)' d='M96 183a64 64 0 0 1-23-23L17 64a128 128 0 0 0 111 192l55-96a64 64 0 0 1-87 23Z'/%3E%3Cpath fill='url(%23b)' d='M192 128a64 64 0 0 1-9 32l-55 96A128 128 0 0 0 239 64H128a64 64 0 0 1 64 64Z'/%3E%3Ccircle cx='128' cy='128' r='52' fill='%231a73e8'/%3E%3Cpath fill='url(%23c)' d='M96 73a64 64 0 0 1 32-9h111a128 128 0 0 0-222 0l56 96a64 64 0 0 1 23-87Z'/%3E%3C/svg%3E)
- ![Edge: 111.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='0 0 27600 27600'%3E%3ClinearGradient id='A' gradientUnits='userSpaceOnUse'/%3E%3ClinearGradient id='B' x1='6870' x2='24704' y1='18705' y2='18705' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%230c59a4'/%3E%3Cstop offset='1' stop-color='%23114a8b'/%3E%3C/linearGradient%3E%3ClinearGradient id='C' x1='16272' x2='5133' y1='10968' y2='23102' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%231b9de2'/%3E%3Cstop offset='.16' stop-color='%231595df'/%3E%3Cstop offset='.67' stop-color='%230680d7'/%3E%3Cstop offset='1' stop-color='%230078d4'/%3E%3C/linearGradient%3E%3CradialGradient id='D' cx='16720' cy='18747' r='9538' xlink:href='%23A'%3E%3Cstop offset='.72' stop-opacity='0'/%3E%3Cstop offset='.95' stop-opacity='.53'/%3E%3Cstop offset='1'/%3E%3C/radialGradient%3E%3CradialGradient id='E' cx='7130' cy='19866' r='14324' gradientTransform='matrix(.14843 -.98892 .79688 .1196 -8759 25542)' xlink:href='%23A'%3E%3Cstop offset='.76' stop-opacity='0'/%3E%3Cstop offset='.95' stop-opacity='.5'/%3E%3Cstop offset='1'/%3E%3C/radialGradient%3E%3CradialGradient id='F' cx='2523' cy='4680' r='20243' gradientTransform='matrix(-.03715 .99931 -2.12836 -.07913 13579 3530)' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%2335c1f1'/%3E%3Cstop offset='.11' stop-color='%2334c1ed'/%3E%3Cstop offset='.23' stop-color='%232fc2df'/%3E%3Cstop offset='.31' stop-color='%232bc3d2'/%3E%3Cstop offset='.67' stop-color='%2336c752'/%3E%3C/radialGradient%3E%3CradialGradient id='G' cx='24247' cy='7758' r='9734' gradientTransform='matrix(.28109 .95968 -.78353 .22949 24510 -16292)' xlink:href='%23A'%3E%3Cstop offset='0' stop-color='%2366eb6e'/%3E%3Cstop offset='1' stop-color='%2366eb6e' stop-opacity='0'/%3E%3C/radialGradient%3E%3Cpath id='H' d='M24105 20053a9345 9345 0 01-1053 472 10202 10202 0 01-3590 646c-4732 0-8855-3255-8855-7432 0-1175 680-2193 1643-2729-4280 180-5380 4640-5380 7253 0 7387 6810 8137 8276 8137 791 0 1984-230 2704-456l130-44a12834 12834 0 006660-5282c220-350-168-757-535-565z'/%3E%3Cpath id='I' d='M11571 25141a7913 7913 0 01-2273-2137 8145 8145 0 01-1514-4740 8093 8093 0 013093-6395 8082 8082 0 011373-859c312-148 846-414 1554-404a3236 3236 0 012569 1297 3184 3184 0 01636 1866c0-21 2446-7960-8005-7960-4390 0-8004 4166-8004 7820 0 2319 538 4170 1212 5604a12833 12833 0 007684 6757 12795 12795 0 003908 610c1414 0 2774-233 4045-656a7575 7575 0 01-6278-803z'/%3E%3Cpath id='J' d='M16231 15886c-80 105-330 250-330 566 0 260 170 512 472 723 1438 1003 4149 868 4156 868a5954 5954 0 003027-839 6147 6147 0 001133-850 6180 6180 0 001910-4437c26-2242-796-3732-1133-4392-2120-4141-6694-6525-11668-6525-7011 0-12703 5635-12798 12620 47-3654 3679-6605 7996-6605 350 0 2346 34 4200 1007 1634 858 2490 1894 3086 2921 618 1067 728 2415 728 2952s-271 1333-780 1990z'/%3E%3Cuse fill='url(%23B)' xlink:href='%23H'/%3E%3Cuse fill='url(%23D)' opacity='.35' xlink:href='%23H'/%3E%3Cuse fill='url(%23C)' xlink:href='%23I'/%3E%3Cuse fill='url(%23E)' opacity='.4' xlink:href='%23I'/%3E%3Cuse fill='url(%23F)' xlink:href='%23J'/%3E%3Cuse fill='url(%23G)' xlink:href='%23J'/%3E%3C/svg%3E)
- ![Firefox: 113.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 512 512'%3E%3Cdefs%3E%3CradialGradient id='ff-b' cx='428.5' cy='55.1' r='501' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23ffbd4f'/%3E%3Cstop offset='.2' stop-color='%23ffac31'/%3E%3Cstop offset='.3' stop-color='%23ff9d17'/%3E%3Cstop offset='.3' stop-color='%23ff980e'/%3E%3Cstop offset='.4' stop-color='%23ff563b'/%3E%3Cstop offset='.5' stop-color='%23ff3750'/%3E%3Cstop offset='.7' stop-color='%23f5156c'/%3E%3Cstop offset='.8' stop-color='%23eb0878'/%3E%3Cstop offset='.9' stop-color='%23e50080'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-c' cx='245.4' cy='259.9' r='501' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.3' stop-color='%23960e18'/%3E%3Cstop offset='.3' stop-color='%23b11927' stop-opacity='.7'/%3E%3Cstop offset='.4' stop-color='%23db293d' stop-opacity='.3'/%3E%3Cstop offset='.5' stop-color='%23f5334b' stop-opacity='.1'/%3E%3Cstop offset='.5' stop-color='%23ff3750' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-d' cx='305.8' cy='-58.6' r='363' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.3' stop-color='%23ffdc3e'/%3E%3Cstop offset='.5' stop-color='%23ff9d12'/%3E%3Cstop offset='.5' stop-color='%23ff980e'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-e' cx='190' cy='390.8' r='238.6' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.3' stop-color='%233a8ee6'/%3E%3Cstop offset='.5' stop-color='%235c79f0'/%3E%3Cstop offset='.7' stop-color='%239059ff'/%3E%3Cstop offset='1' stop-color='%23c139e6'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-f' cx='252.2' cy='201.3' r='126.5' gradientTransform='matrix(1 0 0 1 -48 31)' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.2' stop-color='%239059ff' stop-opacity='0'/%3E%3Cstop offset='.3' stop-color='%238c4ff3' stop-opacity='.1'/%3E%3Cstop offset='.8' stop-color='%237716a8' stop-opacity='.5'/%3E%3Cstop offset='1' stop-color='%236e008b' stop-opacity='.6'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-g' cx='239.1' cy='34.6' r='171.6' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23ffe226'/%3E%3Cstop offset='.1' stop-color='%23ffdb27'/%3E%3Cstop offset='.3' stop-color='%23ffc82a'/%3E%3Cstop offset='.5' stop-color='%23ffa930'/%3E%3Cstop offset='.7' stop-color='%23ff7e37'/%3E%3Cstop offset='.8' stop-color='%23ff7139'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-h' cx='374' cy='-74.3' r='732.2' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.5' stop-color='%23ff980e'/%3E%3Cstop offset='.6' stop-color='%23ff5634'/%3E%3Cstop offset='.7' stop-color='%23ff3647'/%3E%3Cstop offset='.9' stop-color='%23e31587'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-i' cx='304.6' cy='7.1' r='536.4' gradientTransform='rotate(84 303 4)' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23fff44f'/%3E%3Cstop offset='.1' stop-color='%23ffe847'/%3E%3Cstop offset='.2' stop-color='%23ffc830'/%3E%3Cstop offset='.3' stop-color='%23ff980e'/%3E%3Cstop offset='.4' stop-color='%23ff8b16'/%3E%3Cstop offset='.5' stop-color='%23ff672a'/%3E%3Cstop offset='.6' stop-color='%23ff3647'/%3E%3Cstop offset='.7' stop-color='%23e31587'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-j' cx='235' cy='98.1' r='457.1' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.5' stop-color='%23ff980e'/%3E%3Cstop offset='.6' stop-color='%23ff5634'/%3E%3Cstop offset='.7' stop-color='%23ff3647'/%3E%3Cstop offset='.9' stop-color='%23e31587'/%3E%3C/radialGradient%3E%3CradialGradient id='ff-k' cx='355.7' cy='124.9' r='500.3' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.2' stop-color='%23ffe141'/%3E%3Cstop offset='.5' stop-color='%23ffaf1e'/%3E%3Cstop offset='.6' stop-color='%23ff980e'/%3E%3C/radialGradient%3E%3ClinearGradient id='ff-a' x1='446.9' y1='76.8' x2='47.9' y2='461.8' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.1' stop-color='%23fff44f'/%3E%3Cstop offset='.1' stop-color='%23ffe847'/%3E%3Cstop offset='.2' stop-color='%23ffc830'/%3E%3Cstop offset='.4' stop-color='%23ff980e'/%3E%3Cstop offset='.4' stop-color='%23ff8b16'/%3E%3Cstop offset='.5' stop-color='%23ff672a'/%3E%3Cstop offset='.5' stop-color='%23ff3647'/%3E%3Cstop offset='.7' stop-color='%23e31587'/%3E%3C/linearGradient%3E%3ClinearGradient id='ff-l' x1='442.1' y1='74.8' x2='102.6' y2='414.3' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='.2' stop-color='%23fff44f' stop-opacity='.8'/%3E%3Cstop offset='.3' stop-color='%23fff44f' stop-opacity='.6'/%3E%3Cstop offset='.5' stop-color='%23fff44f' stop-opacity='.2'/%3E%3Cstop offset='.6' stop-color='%23fff44f' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M479 166c-11-25-32-52-49-60a249 249 0 0 1 25 73c-27-68-73-95-111-155a255 255 0 0 1-8-14 44 44 0 0 1-4-9 1 1 0 0 0 0-1 1 1 0 0 0-1 0c-60 35-81 101-83 134a120 120 0 0 0-66 25 71 71 0 0 0-6-5 111 111 0 0 1-1-58c-25 11-44 29-58 44-9-12-9-52-8-60l-8 4a175 175 0 0 0-24 21 210 210 0 0 0-22 26 203 203 0 0 0-32 73l-1 2-2 15a229 229 0 0 0-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121zM202 355l3 1-3-1zm55-145zm198-31z' fill='url(%23ff-a)'/%3E%3Cpath d='M479 166c-11-25-32-52-49-60 14 26 22 53 25 72v1a207 207 0 0 1-206 279c-113-3-212-87-231-197-3-17 0-26 2-40-2 11-3 14-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121z' fill='url(%23ff-b)'/%3E%3Cpath d='M479 166c-11-25-32-52-49-60 14 26 22 53 25 72v1a207 207 0 0 1-206 279c-113-3-212-87-231-197-3-17 0-26 2-40-2 11-3 14-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121z' fill='url(%23ff-c)'/%3E%3Cpath d='m362 195 1 1a130 130 0 0 0-22-29C266 92 322 5 331 0c-60 35-81 101-83 134l9-1c45 0 84 25 105 62z' fill='url(%23ff-d)'/%3E%3Cpath d='M257 210c-1 6-22 26-29 26-68 0-80 41-80 41 3 35 28 64 57 79l4 2 7 3a107 107 0 0 0 31 6c120 6 143-143 57-186 22-4 45 5 58 14-21-37-60-62-105-62l-9 1a120 120 0 0 0-66 25l17 16c16 16 58 33 58 35z' fill='url(%23ff-e)'/%3E%3Cpath d='M257 210c-1 6-22 26-29 26-68 0-80 41-80 41 3 35 28 64 57 79l4 2 7 3a107 107 0 0 0 31 6c120 6 143-143 57-186 22-4 45 5 58 14-21-37-60-62-105-62l-9 1a120 120 0 0 0-66 25l17 16c16 16 58 33 58 35z' fill='url(%23ff-f)'/%3E%3Cpath d='m171 151 5 3a111 111 0 0 1-1-58c-25 11-44 29-58 44 1 0 36 0 54 11z' fill='url(%23ff-g)'/%3E%3Cpath d='M18 261a242 242 0 0 0 231 197 207 207 0 0 0 206-279c8 56-20 110-64 146-86 71-169 43-186 31l-3-1c-50-24-71-70-67-110-42 0-57-35-57-35s38-28 89-4c46 22 90 4 90 4 0-2-42-19-58-35l-17-16a71 71 0 0 0-6-5l-5-3c-18-11-52-11-54-11-9-12-9-51-8-60l-8 4a175 175 0 0 0-24 21 210 210 0 0 0-22 26 203 203 0 0 0-32 73c0 1-9 38-5 57z' fill='url(%23ff-h)'/%3E%3Cpath d='M341 167a130 130 0 0 1 22 29 46 46 0 0 1 4 3c55 50 26 121 24 126 44-36 72-90 64-146-27-68-73-95-111-155a255 255 0 0 1-8-14 44 44 0 0 1-4-9 1 1 0 0 0 0-1 1 1 0 0 0-1 0c-9 5-65 92 10 167z' fill='url(%23ff-i)'/%3E%3Cpath d='M367 199a46 46 0 0 0-4-3l-1-1c-13-9-36-18-58-15 86 44 63 193-57 187a107 107 0 0 1-31-6 131 131 0 0 1-11-5c17 12 99 39 186-31 2-5 31-76-24-126z' fill='url(%23ff-j)'/%3E%3Cpath d='M148 277s12-41 80-41c7 0 28-20 29-26s-44 18-90-4c-51-24-89 4-89 4s15 35 57 35c-4 40 16 85 67 110l3 1c-29-15-54-44-57-79z' fill='url(%23ff-k)'/%3E%3Cpath d='M479 166c-11-25-32-52-49-60a249 249 0 0 1 25 73c-27-68-73-95-111-155a255 255 0 0 1-8-14 44 44 0 0 1-4-9 1 1 0 0 0 0-1 1 1 0 0 0-1 0c-60 35-81 101-83 134l9-1c45 0 84 25 105 62-13-9-36-18-58-14 86 43 63 192-57 186a107 107 0 0 1-31-6 131 131 0 0 1-11-5l-3-1 3 1c-29-15-54-44-57-79 0 0 12-41 80-41 7 0 28-20 29-26 0-2-42-19-58-35l-17-16a71 71 0 0 0-6-5 111 111 0 0 1-1-58c-25 11-44 29-58 44-9-12-9-52-8-60l-8 4a175 175 0 0 0-24 21 210 210 0 0 0-22 26 203 203 0 0 0-32 73l-1 2-2 15a279 279 0 0 0-4 34v1a240 240 0 0 0 477 40l1-9c5-41 0-84-15-121zm-24 13z' fill='url(%23ff-l)'/%3E%3C/svg%3E)
- ![Safari: 16.2.](data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='24' height='24' viewBox='195 190 135 135'%3E%3Cdefs%3E%3ClinearGradient id='s-a' x1='132.6' x2='134.4' y1='111.7' y2='-105.3' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%23d2d2d2' /%3E%3Cstop offset='.5' stop-color='%23f2f2f2' /%3E%3Cstop offset='1' stop-color='%23fff' /%3E%3C/linearGradient%3E%3ClinearGradient id='s-b' gradientUnits='userSpaceOnUse' /%3E%3ClinearGradient id='s-c' x1='65.4' x2='67.4' y1='115.7' y2='17.1' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%23005ad5' /%3E%3Cstop offset='.2' stop-color='%230875f0' /%3E%3Cstop offset='.3' stop-color='%23218cee' /%3E%3Cstop offset='.6' stop-color='%2327a5f3' /%3E%3Cstop offset='.8' stop-color='%2325aaf2' /%3E%3Cstop offset='1' stop-color='%2321aaef' /%3E%3C/linearGradient%3E%3ClinearGradient id='s-d' x1='158.7' x2='176.3' y1='96.7' y2='79.5' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%23c72e24' /%3E%3Cstop offset='1' stop-color='%23fd3b2f' /%3E%3C/linearGradient%3E%3CradialGradient id='s-i' cx='-69.9' cy='69.3' r='54' gradientTransform='matrix(.9 -.01 .04 2.72 -9 -120)' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-color='%2324a5f3' stop-opacity='0' /%3E%3Cstop offset='1' stop-color='%231e8ceb' /%3E%3C/radialGradient%3E%3CradialGradient id='s-j' cx='109.3' cy='13.8' r='93.1' gradientTransform='matrix(-.02 1.1 -1.04 -.02 137 -115)' xlink:href='%23s-b'%3E%3Cstop offset='0' stop-opacity='0' /%3E%3Cstop offset='1' stop-color='%235488d6' stop-opacity='0' /%3E%3Cstop offset='1' stop-color='%235d96eb' /%3E%3C/radialGradient%3E%3C/defs%3E%3Crect width='220' height='220' x='22' y='-107' fill='url(%23s-a)' ry='49' transform='matrix(.57 0 0 .57 187 256)' /%3E%3Cg transform='translate(194 190)'%3E%3Ccircle cx='67.8' cy='67.7' fill='url(%23s-c)' paint-order='stroke fill markers' r='54' /%3E%3Ccircle cx='-69.9' cy='69.3' fill='url(%23s-i)' transform='translate(138 -2)' r='54' /%3E%3C/g%3E%3Cellipse cx='120' cy='14.2' fill='url(%23s-j)' rx='93.1' ry='93.7' transform='matrix(.58 0 0 .58 192 250)' /%3E%3Cg transform='matrix(.58 0 0 .57 197 182)'%3E%3Cpath fill='%23cac7c8' d='M46 192h1l72-48-7-9-66 57Z' /%3E%3Cpath fill='%23fbfffc' d='M46 191v1l66-57-7-9-59 65Z' /%3E%3Cpath fill='url(%23s-d)' d='m119 144-7-9 66-57-59 66Z' /%3E%3Cpath fill='%23fb645c' d='m105 126 7 9 66-57-1-1-72 49Z' /%3E%3C/g%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-miterlimit='1' stroke-width='1.3' d='m287 278 3-2m-12-17 8-2m-8-3h4m-4-13 8 2m-8 3h4m-1-13 7 3m-4-11 7 4m-2-11 6 6m0-12 6 7m1-11 4 6m4-10 3 7m5-9 2 7m15-7-1 7m10-5-3 7m11-4-4 7m11-2-5 6m16 7-7 4m10 4-7 3m10 6-8 1m8 16-8-2m5 10-7-3m4 11-7-4m2 11-6-5m0 11-5-6m-2 11-4-7m-4 11-3-8m-6 10-1-8m-16 8 2-8m-10 5 3-7m-11 4 4-7m-11 2 5-6m-8 3 3-3m4 8 2-3m5 8 2-4m6 7 1-4m8 5v-4m8 4v-4m9 3-1-4m9 1-2-4m9 0-2-4m9-2-3-3m8-4-3-2m8-5-4-2m7-6-4-1m5-8h-4m4-8h-4m3-9-4 1m1-9-4 2m-1-9-3 2m-2-9-3 3m-4-8-2 3m-5-8-2 4m-6-6-1 3m-8-5v4m-8-4v4m-9-2 1 3m-9 0 2 3m-9 1 2 3m-9 2 3 3m-8 4 3 2m-8 5 4 2m-7 6 4 1m-4 25 4-1m-2 5 7-3m-6 7 4-2m-2 6 7-4m-13-21h8m41-41v-8m0 99v-8m49-42h-8' transform='translate(-65 8)' /%3E%3C/svg%3E)

[Source](https://developer.mozilla.org/docs/Web/CSS/Reference/Values/color_value/color-mix)

<br />

Before `color-mix()`, to darken, lighten, or desaturate a color, developers used
CSS preprocessors or
[`calc()`](https://developer.mozilla.org/docs/Web/CSS/calc) on color
channels.
Before with SCSS

```css
.color-mixing-with-sass {
  /* Sass: equally mix red with white */
  --red-white-mix: color.mix(red, white);
}
```

[Sass](https://sass-lang.com/documentation/modules/color#mix) has done great
work staying ahead of the color CSS specification. There has not, however, been
a real way to mix colors in CSS. To get close you need to do math of partial
color values. Here's a reduced example of how CSS may simulate mixing today:
Before with HSL

```css
.color-mixing-with-vanilla-css-before {
  --lightness: 50%;
  --red: hsl(0 50% var(--lightness));

  /* add "white" to red
     by adding 25% to the lightness channel
  */
  --lightred: hsl(0 50% calc(var(--lightness) + 25%);
}
```

[`color-mix()`](https://www.w3.org/TR/css-color-5/#funcdef-color-mix) brings the
ability to mix colors to CSS. Developers can choose which color space they mix
in and how dominant each color should be in the mix.
After

```css
.color-mixing-after {
  /* equally mix red with white */
  --red-white-mix: color-mix(in oklab, red, white);

  /* equally mix red with white in srgb */
  --red-white-mix-srgb: color-mix(in srgb, red, white);
}
```

That's what we want. Flexibility, power and fully featured APIs. Love it.

## Mixing colors in CSS

CSS exists in a [multiple color space and color gamut world](https://developer.chrome.com/docs/css-ui/high-definition-css-color-guide#meet_the_new_web_color_spaces), and because of this
it's not optional to specify the color space for mixing. Furthermore, different
color spaces can drastically change the results of a mix, so knowing the effects
of a color space will help you get the results you need.

For an interactive introduction, try this `color-mix()` tool:
- Explore the effects of each color space.
- Explore the effects of hue interpolation when mixing in a cylindrical color
space (`lch`, `oklch`, `hsl`, and `hwb`).
- Change the colors being mixed by clicking either of the top two color boxes.
- Use the slider to change the mixing ratio.
- Generated `color-mix()` CSS code available at the bottom.
<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/web-dot-dev/embed/JjBZLrm?height=500&amp;theme-id=light&amp;default-tab=result&amp;editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen JjBZLrm by web-dot-dev on Codepen">See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/embed/JjBZLrm"&amp;amp;gt;Pen JjBZLrm by web-dot-dev on Codepen&amp;amp;lt;/a&amp;amp;gt;</iframe>

### Mixing in the various color spaces

The default color space for mixing (and [gradients](https://developer.chrome.com/docs/css-ui/high-definition-css-color-guide#gradients_in_different_color_spaces)) is `oklab`. It provides
consistent results. You can specify alternative color spaces too, to tailor the
mix to your needs.

Take `black` and `white` for example. The color space they mix in won't make
that big of a difference, right? Wrong.

    color-mix(in srgb, black, white);
    color-mix(in srgb-linear, black, white);
    color-mix(in lch, black, white);
    color-mix(in oklch, black, white);
    color-mix(in lab, black, white);
    color-mix(in oklab, black, white);
    color-mix(in xyz, black, white);

![7 color spaces (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) each show their results of mixing black and white. Roughly 5 different shades are shown, demonstrating that each color space will even mix to a gray differently.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/7-color-spaces-srgb-lin-f139be872a18a.png) [Try the demo](https://codepen.io/web-dot-dev/pen/poZKLdw)

It does have a big effect!

Take `blue` and `white` for another example. I chose this specifically because
it's a case where a color space's shape can affect the results. In this case
it's that most color spaces go purple while traveling from white to blue. It
also shows how `oklab` is such a reliable color space for mixing, it's the
closest to most people's expectations of mixing white and blue (no purple).

    color-mix(in srgb, blue, white);
    color-mix(in srgb-linear, blue, white);
    color-mix(in lch, blue, white);
    color-mix(in oklch, blue, white);
    color-mix(in lab, blue, white);
    color-mix(in oklab, blue, white);
    color-mix(in xyz, blue, white);

![7 color spaces (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) each shown having different results. Many are pink or purple, few are actually still blue.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/7-color-spaces-srgb-lin-5415cf7a20d75.png) [Try the demo](https://codepen.io/web-dot-dev/pen/eYjKMVV)

Learning the effects of a color space with `color-mix()` is great knowledge for
[making gradients](https://developer.chrome.com/docs/css-ui/high-definition-css-color-guide#gradients_in_different_color_spaces)
too. Color 4 syntax also allows gradients to specify the color space, where a
gradient shows the mix over an area of space.

    .black-to-white-gradient-in-each-space {
      --srgb: linear-gradient(to right in srgb, black, white);
      --srgb-linear: linear-gradient(to right in srgb-linear, black, white);
      --lab: linear-gradient(to right in lab, black, white);
      --oklab: linear-gradient(to right in oklab, black, white);
      --lch: linear-gradient(to right in lch, black, white);
      --oklch: linear-gradient(to right in oklch, black, white);
      --hsl: linear-gradient(to right in hsl, black, white);
      --hwb: linear-gradient(to right in hwb, black, white);
      --xyz: linear-gradient(to right in xyz, black, white);
      --xyz-d50: linear-gradient(to right in xyz-d50, black, white);
      --xzy-d65: linear-gradient(to right in xyz-d65, black, white);
    }

![Black to white gradients in different color spaces.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/alttexthere-a16c67a3aee6c.png) [Try the demo](https://codepen.io/web-dot-dev/pen/QWBxmxv)

If you're wondering which color space is "the best," there isn't one. That's why
there are so many options! There also wouldn't be new color spaces being
invented either (see `oklch` and `oklab`), if one was "the best." Each color
space can have a unique moment to shine and be the right choice.

For example, if you want a vibrant mix result, use hsl or hwb. In the following
demo, two vibrant colors (magenta and lime) are mixed together and hsl and hwb
both produce a vibrant result, while srgb and oklab produce unsaturated colors.
![The mix results as described in the preceding paragraph.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/alttexthere-93bf2be27ac03.png) [Try the demo](https://codepen.io/web-dot-dev/pen/VwBdxGm)

If you want consistency and subtlety, use oklab. In the following demo which mixes
blue and black, hsl and hwb produce overly vibrant and hue shifted colors while
srgb and oklab produce a darker blue.
![The mix results as described in the preceding paragraph.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/alttexthere-f139d29a23359.png) [Try the demo](https://codepen.io/web-dot-dev/pen/gOjKzdG)

Spend five minutes with the [`color-mix()` playground](https://codepen.io/argyleink/pen/YzLMaor), testing different colors
and spaces, and you'll start to get a feel for each space's advantages. Also
expect more guidance around color spaces to happen as we all adjust to their
potentials in our user interfaces.

#### Adjusting the hue interpolation method

If you've chosen to mix in a cylindrical color space, essentially any color
space with a `h` hue channel that accepts an angle, you can specify if the
interpolation goes `shorter`, `longer`, `decreasing`, and `increasing`. This is
covered well in this [HD Color Guide](https://developer.chrome.com/docs/css-ui/high-definition-css-color-guide) if you want to learn more.

> [!NOTE]
> **Note:** The `color-mix()` playground will add an additional select dropdown if the color space is cylindrical. You can play there to see the effects on the mix.

Here's the same blue to white mix example, but this time, it's only in the
cylindrical spaces with different hue interpolation methods.
![The mix results as described in the preceding paragraph.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/alttexthere-5b90e9287d746.png) [Try the demo](https://codepen.io/web-dot-dev/pen/BaPVrMQ)

Here's another Codepen I made to help visualize hue interpolation, but
specifically for gradients. I believe this will help you understand how each
color space produces its mix result when hue interpolation is specified though,
give it a study!
<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/web-dot-dev/embed/MWBXVLV?height=500&amp;theme-id=light&amp;default-tab=result&amp;editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen MWBXVLV by web-dot-dev on Codepen">See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/embed/MWBXVLV"&amp;amp;gt;Pen MWBXVLV by web-dot-dev on Codepen&amp;amp;lt;/a&amp;amp;gt;</iframe>

> [!WARNING]
> **Warning:** Providing a hue interpolation method for a non-cylindrical color space is a syntax error in `color-mix()`.

### Mixing with varying color syntaxes

So far we've mostly mixed CSS named colors, like `blue` and `white`. CSS color
mixing is ready to mix colors that are from two different color spaces. This is
another reason it's key to specify the color space for the mixing, as it sets
the common space for when the two colors aren't in the same space.

    color-mix(in oklch, hsl(200deg 50% 50%), color(display-p3 .5 0 .5));

In the previous example, the `hsl` and `display-p3` will be converted to `oklch`
and then mixed. Pretty cool and flexible.

#### Adjusting the mixing ratios

It's not very likely that every time you mix you want equal parts of each color,
like most of the examples so far have shown. Good news, there's a syntax for
articulating how much of each color should be seen in the resulting mix.

To start this topic, here's a sample of mixes that are all equivalent (and [from the spec](https://www.w3.org/TR/css-color-5/#ex-mix-syntactic)):

    .ratios-syntax-examples {
      /* omit the percentage for equal mixes */
      color: color-mix(in lch, purple, plum);
      color: color-mix(in lch, plum, purple);

      /* percentage can go on either side of the color */
      color: color-mix(in lch, purple 50%, plum 50%);
      color: color-mix(in lch, 50% purple, 50% plum);

      /* percentage on just one color? other color gets the remainder */
      color: color-mix(in lch, purple 50%, plum);
      color: color-mix(in lch, purple, plum 50%);

      /* percentages > 100% are equally clamped */
      color: color-mix(in lch, purple 80%, plum 80%);
      /* above mix is clamped to this */
      color: color-mix(in lch, purple 50%, plum 50%);
    }

I find these examples to illuminate the edge cases well. The first set of
examples show how 50% isn't required but can be optionally specified. The last
example shows an interesting case for when the ratios exceed 100% when added
together, they're equally clamped to total 100%.

Notice too, that if only one color specifies a ratio, the other is assumed to be
the remainder to 100%. Here's a few more examples to help illustrate this
behavior.

    color-mix(in lch, purple 40%, plum) /* plum assigned 60% */
    color-mix(in lch, purple, 60% plum) /* purple assigned 40% */
    color-mix(in lch, purple 40%, plum 60%) /* no auto assignments */

These examples illustrate two rules:
1. When ratios exceed 100%, they're clamped and equally distributed.
1. When only one ratio is provided, the other color is set to 100 minus that ratio.

The last rule is slightly less obvious; what happens if percentages are supplied
for both colors and they don't add up to 100%?

    color-mix(in lch, purple 20%, plum 20%)

This combination of a `color-mix()` results in transparency, `40%` transparency.
When ratios don't add up to 100%, then the resulting mix won't be opaque.
Neither of the colors will be fully mixed.

#### Nesting `color-mix()`

Like all of CSS, nesting is handled well and as expected; inner functions will
resolve first and return their values to the parent context.

    color-mix(in lch, purple 40%, color-mix(plum, white))

Feel free to nest as much as you need to get the result you're working towards.

## Building a light and dark color scheme

Let's build color schemes with `color-mix()`!

### A basic color scheme

In the following CSS, a light and dark theme are created based on a brand hex
color. The light theme creates two dark blue text colors and a very light white
background surface color. Then in a dark preference media query, the custom
properties are assigned new colors so the background is dark and the text colors
are light.

    :root {
      /* a base brand color */
      --brand: #0af;

      /* very dark brand blue */
      --text1: color-mix(in oklab, var(--brand) 25%, black);
      --text2: color-mix(in oklab, var(--brand) 40%, black);

      /* very bright brand white */
      --surface1: color-mix(in oklab, var(--brand) 5%, white);
    }

    @media (prefers-color-scheme: dark) {
      :root {
        --text1: color-mix(in oklab, var(--brand) 15%, white);
        --text2: color-mix(in oklab, var(--brand) 40%, white);
        --surface1: color-mix(in oklab, var(--brand) 5%, black);
      }
    }

All of this is accomplished by mixing white or black into a brand color.
<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/web-dot-dev/embed/YzjvabP?height=500&amp;theme-id=light&amp;default-tab=result&amp;editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen YzjvabP by web-dot-dev on Codepen">See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/embed/YzjvabP"&amp;amp;gt;Pen YzjvabP by web-dot-dev on Codepen&amp;amp;lt;/a&amp;amp;gt;</iframe>

### Intermediate color scheme

This can be taken a step further by adding more than light and dark themes. In
the following demo, changes to the radio group update an attribute on the HTML
tag `[color-scheme="auto"]` which then enables selectors to conditionally apply
a color theme.
<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/web-dot-dev/embed/bGjKvyW?height=500&amp;theme-id=light&amp;default-tab=result&amp;editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen bGjKvyW by web-dot-dev on Codepen">See the Pen &amp;amp;lt;a href="https://codepen.io/web-dot-dev/embed/bGjKvyW"&amp;amp;gt;Pen bGjKvyW by web-dot-dev on Codepen&amp;amp;lt;/a&amp;amp;gt;</iframe>

This intermediate demo also shows a color theming technique where all of the
theme colors are listed in `:root`. This makes them easy to see all together and
adjust if needed. Later in the stylesheet, you can use the variables as they're
defined. This saves hunting through the stylesheet for color manipulations as
they're all contained in the initial `:root` block.

### More interesting use cases

[Ana Tudor](https://twitter.com/anatudor) has a great demo with a few use cases
for study:
<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/thebabydino/embed/LYdgvLr?height=500&amp;theme-id=light&amp;default-tab=result&amp;editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen LYdgvLr by thebabydino on Codepen">See the Pen &amp;amp;lt;a href="https://codepen.io/thebabydino/embed/LYdgvLr"&amp;amp;gt;Pen LYdgvLr by thebabydino on Codepen&amp;amp;lt;/a&amp;amp;gt;</iframe>

## Debugging color-mix() with DevTools

Chrome DevTools has great support for `color-mix()`. It recognizes and
highlights the syntax, creates a preview of the mix right next to the style in
the Styles pane and allows picking alternative colors.

It will look something like this in the DevTools:

![Chrome DevTools inspecting color-mix syntax.](https://developer.chrome.com/static/docs/css-ui/css-color-mix/image/alttexthere-b423404935431.png)

Happy mixing y'all!