Beispiel:Oklch-2.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

<!DOCTYPE html> <html lang="de">

 <head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Farbmodelle vergleichen</title>
   <style>
     body {
       max-width: 75rem;
     }
     h2 {
       margin-top: .2rem;
       margin-bottom: .2rem;
     }
           
     fieldset {
       margin: 0;
       padding: .1rem;
       border: thin solid black;
     }
     
     fieldset:not([id]) {
       border: none;
       margin-top: .1rem;
     }
     
     fieldset[id] legend {
       font-weight: bold;
     }
     
     input {
       display: block;
     }
     input[type=number] { 
       width: 3rem;
     }
     figure {
       margin: 0;
     }
     #farbwaehler {
       display: flex;
       justify-content: space-between;
       flex-wrap: wrap;
       margin-bottom: .5rem
     } 
     
     #links, #rechts {
       border: thin solid black;
       padding: .5rem;
       display: grid;
       grid-template-columns: auto auto auto;
       grid-template-rows: min-content auto auto;
     }
       
     hgroup {
       display: flex;
       justify-content: space-between;
       grid-column: 1 / -1;
     }
     
     #links p, #rechts p {
       margin: 0;
     }
           
     #anzeige_links, #anzeige_rechts {
       border: thin solid transparent;
       border-radius: 1.25rem;
       width: 2.5rem;
       height: 2.5rem;
     }
           
     #anzeige_RGB, #anzeige_HSL, #anzeige_OKLCH {
       border: thin solid black;
       height: 5rem;
       /*filter: grayscale(1);*/
     }
     
     #CSS_RGB, #CSS_HSL, #CSS_OKLCH {
       position: absolute;
       margin-top: 1.9rem;
       margin-left: 1rem;
       padding: .2rem;
       background-color: white;
       font: 1rem/1 sanserif;
     }

</style>

   <script>
     // Quelle: http://www.easyrgb.com/en/math.php für hsl
     //         https://bottosson.github.io/posts/oklab/#oklab-implementations für oklab
     "use strict"
     // RGB:   0 ... 255
     // HSL:   0 ... 360,  0 ... 100%,      0 ... 100%
     // OKlab: 0 ... 100&, -125 ... 125, -125 ... 125
     // OKLCH: 0 ... 1,    0 ... 0.4(0.5),  0 ... 360
     //        0 ... 100%, 0 ... 125%,      0 ... 360
     // Siehe auch https://www.w3.org/TR/css-color-4/#specifying-lab-lch
     //            https://www.w3.org/TR/css-color-4/#specifying-oklab-oklch
     function Lab2LCH(Lab) { 
       let L = Lab.L,
           a = Lab.a,
           b = Lab.b;
       let H = Math.atan2( b, a );
       if ( H > 0 ) H = ( H / Math.PI ) * 180;
       else         H = 360 - ( Math.abs( H ) / Math.PI ) * 180;
       let C = Math.sqrt( a*a + b*b );
       return { L:L*100, C:C*250, H:H }; // L in %, C in %
     } // Lab2LCH
     function LCH2Lab(LCH) { // L in %, C in %
       let L = LCH.L/100,
           C = LCH.C/250,
           H = LCH.H;


       let a = Math.cos( ( H / 180 ) * Math.PI ) * C;
       let b = Math.sin( ( H / 180 ) * Math.PI ) * C;
       return { L:L, a:a, b:b };
     } // LCH2Lab
     function RGB2HSL(RGB) {
       let R = ( RGB.R / 255 ),
           G = ( RGB.G / 255 ),
           B = ( RGB.B / 255 );
       let H, S, L;
       let Min = Math.min( R, G, B );    // Min. value of RGB
       let Max = Math.max( R, G, B );    // Max. value of RGB
       let del_Max = Max - Min;          // Delta RGB value
       L = ( Max + Min ) / 2;
       if ( del_Max == 0 ) {             //This is a gray, no chroma...
         H = 0;
         S = 0;
       } 
       else {                            //Chromatic data...
         if ( L < 0.5 ) S = del_Max / ( Max + Min );
         else           S = del_Max / ( 2 - Max - Min );
         let del_R = ( ( ( Max - R ) / 6 ) + ( del_Max / 2 ) ) / del_Max;
         let del_G = ( ( ( Max - G ) / 6 ) + ( del_Max / 2 ) ) / del_Max;
         let del_B = ( ( ( Max - B ) / 6 ) + ( del_Max / 2 ) ) / del_Max;
         if      ( R == Max ) H = del_B - del_G;
         else if ( G == Max ) H = ( 1 / 3 ) + del_R - del_B;
         else if ( B == Max ) H = ( 2 / 3 ) + del_G - del_R;
         if ( H < 0 ) H += 1;
         if ( H > 1 ) H -= 1;
       }
       return { H:H*360, S:S*100, L:L*100 };
     } // RGB2HSL
     function HSL2RGB(HSL) {
       let H = HSL.H / 360,
           S = HSL.S / 100,
           L = HSL.L / 100;
       let R, B, G;
       let v1, v2, v3;
       if ( S == 0 ) {
         R = L * 255;
         G = L * 255;
         B = L * 255;
       }
       else {
         if ( L < 0.5 ) v2 = L * ( 1 + S );
         else           v2 = ( L + S ) - ( S * L );
         v1 = 2 * L - v2;
         R = 255 * Hue_2_RGB( v1, v2, H + ( 1 / 3 ) );
         G = 255 * Hue_2_RGB( v1, v2, H );
         B = 255 * Hue_2_RGB( v1, v2, H - ( 1 / 3 ) );
       }
     //  return { R:Math.round(R), G:Math.round(G), B:Math.round(B) };  
       return { R:R, G:G, B:B };  // nicht runden wegen möhglicher Umrechnung nach oklab
     } // HSL2RGB
     function Hue_2_RGB( v1, v2, vH ) {
       if ( vH < 0 ) vH += 1
       if ( vH > 1 ) vH -= 1
       if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH )
       if ( ( 2 * vH ) < 1 ) return ( v2 )
       if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 )
       return ( v1 )
     } // Hue_2_RGB
     function clamp(num, min, max) {
       min = min || 0;
       max = max || 255;
       return num <= min 
         ? min 
         : num >= max 
           ? max 
           : num;
     } // clamp
     function clampRGB(RGB) {
       let cRGB = {};
       for(let x in RGB) cRGB[x] = clamp(RGB[x],0,255);
       return cRGB;
     } // clampRGB
     function dritteWurzel(x) {
       if(x>=0) 
         return Math.pow(x, 1/3);
       else 
         return -Math.pow(-x, 1/3);
     } // dritteWurzel
     function linRGB2RGB(RGB) {
       let sRGB = {};
       for(let x in RGB) {
         if (RGB[x] >= 0.0031308)
             sRGB[x] = 1.055 * Math.pow(RGB[x], 1.0/2.4) - 0.055;
         else
             sRGB[x] = 12.92 * RGB[x];
       }
       
       return sRGB;
       
     } // linRGB2RGB
     function RGB2linRGB(sRGB) {
       let RGB = {};
       for(let x in sRGB) {
         if (sRGB[x] >= 0.04045)
           RGB[x] = Math.pow((sRGB[x] + 0.055) / 1.055, 2.4);
         else 
           RGB[x] =  sRGB[x] / 12.92;
       }
       return RGB;
       
     } // RGB2linRGB
     function RGB2OKLAB(sRGB) {
       let l, m, s, L, a, b;
       let RGB = {};
       for(let x in sRGB) RGB[x] = sRGB[x]/255;
       RGB = RGB2linRGB(RGB);
       l = 0.4122214708 * RGB.R + 0.5363325363 * RGB.G + 0.0514459929 * RGB.B;
       m = 0.2119034982 * RGB.R + 0.6806995451 * RGB.G + 0.1073969566 * RGB.B;
       s = 0.0883024619 * RGB.R + 0.2817188376 * RGB.G + 0.6299787005 * RGB.B;
       l = dritteWurzel(l);
       m = dritteWurzel(m);
       s = dritteWurzel(s);
       L = 0.2104542553*l + 0.7936177850*m - 0.0040720468*s;
       a = 1.9779984951*l - 2.4285922050*m + 0.4505937099*s;
       b = 0.0259040371*l + 0.7827717662*m - 0.8086757660*s;
       return { L:L, a:a, b:b };  
     } // RGB2OKLAB
     function OKLAB2RGB(OKLAB) {
       let l, m, s, RGB = {};
       l = OKLAB.L + 0.3963377774 * OKLAB.a + 0.2158037573 * OKLAB.b;
       m = OKLAB.L - 0.1055613458 * OKLAB.a - 0.0638541728 * OKLAB.b;
       s = OKLAB.L - 0.0894841775 * OKLAB.a - 1.2914855480 * OKLAB.b;
       l = Math.pow(l, 3);
       m = Math.pow(m, 3);
       s = Math.pow(s, 3);
       RGB.R = +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
       RGB.G = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
       RGB.B = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;
       RGB = linRGB2RGB(RGB);
       for(let x in RGB) RGB[x] *= 255;
       return RGB;
     } // OKLAB2RGB
   </script>
   <script>
     
     "use strict"
     document.addEventListener("DOMContentLoaded", () => {
       
       const rgb_l   = document.querySelector("#rgb_l");
       const hsl_l   = document.querySelector("#hsl_l");
       const oklch_l = document.querySelector("#oklch_l");
       const inputs_rgb_range_l    = rgb_l.querySelectorAll("input[type=range]");
       const inputs_hsl_range_l    = hsl_l.querySelectorAll("input[type=range]");
       const inputs_oklch_range_l  = oklch_l.querySelectorAll("input[type=range]");
       const inputs_rgb_number_l   = rgb_l.querySelectorAll("input[type=number]");
       const inputs_hsl_number_l   = hsl_l.querySelectorAll("input[type=number]");
       const inputs_oklch_number_l = oklch_l.querySelectorAll("input[type=number]");
       const rgb_r   = document.querySelector("#rgb_r");
       const hsl_r   = document.querySelector("#hsl_r");
       const oklch_r = document.querySelector("#oklch_r");
       const inputs_rgb_range_r    = rgb_r.querySelectorAll("input[type=range]");
       const inputs_hsl_range_r    = hsl_r.querySelectorAll("input[type=range]");
       const inputs_oklch_range_r  = oklch_r.querySelectorAll("input[type=range]");
       const inputs_rgb_number_r   = rgb_r.querySelectorAll("input[type=number]");
       const inputs_hsl_number_r   = hsl_r.querySelectorAll("input[type=number]");
       const inputs_oklch_number_r = oklch_r.querySelectorAll("input[type=number]");
       const anzeige_RGB   = document.querySelector("#anzeige_RGB");
       const anzeige_HSL   = document.querySelector("#anzeige_HSL");
       const anzeige_OKLCH = document.querySelector("#anzeige_OKLCH");
       const CSS_RGB   = document.querySelector("#CSS_RGB");
       const CSS_HSL   = document.querySelector("#CSS_HSL");
       const CSS_OKLCH = document.querySelector("#CSS_OKLCH");
       const anzeige_links  = document.querySelector("#anzeige_links");
       const anzeige_rechts = document.querySelector("#anzeige_rechts");
       let RGB_l   = {R:0,G:255,B:0},
           HSL_l   = RGB2HSL(RGB_l),
           OKLab_l = RGB2OKLAB(RGB_l),
           OKLCH_l = Lab2LCH(OKLab_l),
           RGB_r   = {R:255,G:0,B:0},
           HSL_r   = RGB2HSL(RGB_r),
           OKLab_r = RGB2OKLAB(RGB_r),
           OKLCH_r = Lab2LCH(OKLab_r);
         

document.body.addEventListener("input", (event) => {

         rangeEqualNumber();
         
         switch(event.target.parentNode.parentNode.id) {
           case "rgb_l":
             RGB_l   = readRGB(inputs_rgb_number_l);
             HSL_l   = RGB2HSL(clampRGB(RGB_l));
             OKLab_l = RGB2OKLAB(RGB_l);
             OKLCH_l = Lab2LCH(OKLab_l);
             //console.log("RGB_l",RGB_l, HSL_l, OKLCH_l);
             break;
           case "hsl_l":
             HSL_l   = readHSL(inputs_hsl_number_l);
             RGB_l   = HSL2RGB(HSL_l);
             OKLab_l = RGB2OKLAB(RGB_l);
             OKLCH_l = Lab2LCH(OKLab_l);
             //console.log("HSL_l",RGB_l, HSL_l, OKLCH_l);
             break;
           case "oklch_l":
             OKLCH_l   = readOKLCH(inputs_oklch_number_l);
             OKLab_l   = LCH2Lab(OKLCH_l);
             RGB_l     = OKLAB2RGB(OKLab_l);
             HSL_l     = RGB2HSL(clampRGB(RGB_l));
             //console.log("LCH_l",RGB_l, HSL_l, OKLCH_l);
             break;
           case "rgb_r":
             RGB_r   = readRGB(inputs_rgb_number_r);
             HSL_r   = RGB2HSL(clampRGB(RGB_r));
             OKLab_r = RGB2OKLAB(RGB_r);
             OKLCH_r = Lab2LCH(OKLab_r);
             //console.log("RGB_r",RGB_r, HSL_r, OKLCH_r);
             break;
           case "hsl_r":
             HSL_r   = readHSL(inputs_hsl_number_r);
             RGB_r   = HSL2RGB(HSL_r);
             OKLab_r = RGB2OKLAB(RGB_r);
             OKLCH_r = Lab2LCH(OKLab_r);
             //console.log("HSL_r",RGB_r, HSL_r, OKLCH_r);
             break;
           case "oklch_r":
             OKLCH_r   = readOKLCH(inputs_oklch_number_r);
             OKLab_r   = LCH2Lab(OKLCH_r);
             RGB_r     = OKLAB2RGB(OKLab_r);
             HSL_r     = RGB2HSL(clampRGB(RGB_r));
             //console.log("LCH_r",RGB_r, HSL_r, OKLCH_r);
             break;
         }
                     
         updateInputs(event.target.parentNode.parentNode.id);
         updateDisplay();
         
 			});
       function rangeEqualNumber() { 
         if(event.target.type == "range") {
           const input_number = event.target.parentNode.querySelector("[type=number]");
           input_number.value = event.target.value;
         }
         else if(event.target.type == "number") {
           const input_range = event.target.parentNode.querySelector("[type=range]");
           input_range.value = event.target.value;
         }
       }
       
       function myRound(x) {

// return x.toPrecision(4);

         return Math.round(x);
       }
       
       function readRGB(inputs) {
         return { 
           R: Number(inputs[0].value), 
           G: Number(inputs[1].value),
           B: Number(inputs[2].value) 
         }
       }
       
       function readHSL(inputs) {
         return {
           H: Number(inputs[0].value),
           S: Number(inputs[1].value),
           L: Number(inputs[2].value)
         }
       }
       
       function readOKLCH(inputs) {
         return {
           L: Number(inputs[0].value),
           C: Number(inputs[1].value),
           H: Number(inputs[2].value)
         }
       }
       
       function updateDisplay() {
         let r_l = Math.round(clamp(RGB_l.R));
         let g_l = Math.round(clamp(RGB_l.G));
         let b_l = Math.round(clamp(RGB_l.B));
         let r_r = Math.round(clamp(RGB_r.R));
         let g_r = Math.round(clamp(RGB_r.G));
         let b_r = Math.round(clamp(RGB_r.B));
         CSS_RGB.innerText = anzeige_RGB.style.background 
           = `linear-gradient(to right, rgb(${r_l} ${g_l} ${b_l}), rgb(${r_r} ${g_r} ${b_r}))`;
         
         let h_l = myRound(HSL_l.H);
         let s_l = myRound(HSL_l.S);
         let l_l = myRound(HSL_l.L);
         let h_r = myRound(HSL_r.H);
         let s_r = myRound(HSL_r.S);
         let l_r = myRound(HSL_r.L);
         CSS_HSL.innerText = anzeige_HSL.style.background 
           = `linear-gradient(in hsl to right, hsl(${h_l} ${s_l}% ${l_l}%), hsl(${h_r} ${s_r}% ${l_r}%))`;	
                   
             l_l = myRound(OKLCH_l.L);
         let c_l = myRound(OKLCH_l.C);
             h_l = myRound(OKLCH_l.H);
             l_r = myRound(OKLCH_r.L);
         let c_r = myRound(OKLCH_r.C);
             h_r = myRound(OKLCH_r.H);
         CSS_OKLCH.innerText = anzeige_OKLCH.style.background
           = `linear-gradient(in oklch to right, oklch(${l_l}% ${c_l}% ${h_l}), oklch(${l_r}% ${c_r}% ${h_r}))`;
         anzeige_links.style.background  = `oklch(${l_l}% ${c_l}% ${h_l})`
         anzeige_rechts.style.background = `oklch(${l_r}% ${c_r}% ${h_r})`
       }
       
       function updateInputs(bereich) {
         if(bereich != "rgb_l") {
           inputs_rgb_range_l[0].value = inputs_rgb_number_l[0].value = myRound(RGB_l.R);
           inputs_rgb_range_l[1].value = inputs_rgb_number_l[1].value = myRound(RGB_l.G);
           inputs_rgb_range_l[2].value = inputs_rgb_number_l[2].value = myRound(RGB_l.B);
         }
         if(bereich != "hsl_l") {
           inputs_hsl_range_l[0].value = inputs_hsl_number_l[0].value = myRound(HSL_l.H);
           inputs_hsl_range_l[1].value = inputs_hsl_number_l[1].value = myRound(HSL_l.S);
           inputs_hsl_range_l[2].value = inputs_hsl_number_l[2].value = myRound(HSL_l.L);
         }
         if(bereich != "oklch_l") {
           inputs_oklch_range_l[0].value = inputs_oklch_number_l[0].value = myRound(OKLCH_l.L);
           inputs_oklch_range_l[1].value = inputs_oklch_number_l[1].value = myRound(OKLCH_l.C);
           inputs_oklch_range_l[2].value = inputs_oklch_number_l[2].value = myRound(OKLCH_l.H);
         }
         if(bereich != "rgb_r") {
           inputs_rgb_range_r[0].value = inputs_rgb_number_r[0].value = myRound(RGB_r.R);
           inputs_rgb_range_r[1].value = inputs_rgb_number_r[1].value = myRound(RGB_r.G);
           inputs_rgb_range_r[2].value = inputs_rgb_number_r[2].value = myRound(RGB_r.B);
         }
         if(bereich != "hsl_r") {
           inputs_hsl_range_r[0].value = inputs_hsl_number_r[0].value = myRound(HSL_r.H);
           inputs_hsl_range_r[1].value = inputs_hsl_number_r[1].value = myRound(HSL_r.S);
           inputs_hsl_range_r[2].value = inputs_hsl_number_r[2].value = myRound(HSL_r.L);
         }
         if(bereich != "oklch_r") {
           inputs_oklch_range_r[0].value = inputs_oklch_number_r[0].value = myRound(OKLCH_r.L);
           inputs_oklch_range_r[1].value = inputs_oklch_number_r[1].value = myRound(OKLCH_r.C);
           inputs_oklch_range_r[2].value = inputs_oklch_number_r[2].value = myRound(OKLCH_r.H);
         }
       }
       
       updateInputs();
       updateDisplay();
     });
   </script>

</head>

<body>


     <section id="links">
       <hgroup>

Farbe am linken Rand

       </hgroup>
     
       <fieldset id="rgb_l">
         <legend>RGB</legend>
         
         <fieldset>
           <label for="rgb_l_r">Rot</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="255" step="1" value="0">
           <input type="number" id="rgb_l_r" min="0" max="255" step="1" value="0">
         </fieldset>
         
         <fieldset>
           <label for="rgb_l_g">Grün</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="255" step="1" value="0">
           <input type="number" id="rgb_l_g" min="0" max="255" step="1" value="0">
         </fieldset>
         
         <fieldset>
           <label for="rgb_l_b">Blau</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="255" step="1" value="0">
           <input type="number" id="rgb_l_b" min="0" max="255" step="1" value="0">
         </fieldset>
      </fieldset>
       <fieldset id="hsl_l">
         <legend>HSL</legend>
         
         <fieldset>
           <label for="hsl_l_h">Hue (Farbton)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="360" step="1" value="0">
           <input type="number" id="hsl_l_h" min="0" max="360" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="hsl_l_s">Saturation (Sättigung)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="100" step="1" value="0">
           <input type="number" id="hsl_l_s" min="0" max="100" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="hsl_l_l">Lightness (Helligkeit)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="100" step="1" value="0">
           <input type="number" id="hsl_l_l" min="0" max="100" step="1" value="0">
         </fieldset>
       </fieldset>
       <fieldset id="oklch_l">
         <legend>OKLCH</legend>
         
         <fieldset>
           <label for="oklch_l_l">Lightness (Helligkeit)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="100" step="1" value="0">
           <input type="number" id="oklch_l_l" min="0" max="100" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="oklch_l_c">Chroma (Menge an Farbe)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="125" step="1" value="0">
           <input type="number" id="oklch_l_c" min="0" max="125" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="oklch_l_h">Hue (Farbton)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="360" step="1" value="0">
           <input type="number" id="oklch_l_h" min="0" max="360" step="1" value="0">
         </fieldset>
       </fieldset>
     </section>
     
     <section id="rechts">
       <hgroup>

Farbe am rechten Rand

       </hgroup>
     
       <fieldset id="rgb_r">
         <legend>RGB</legend>
         
         <fieldset>
           <label for="rgb_r_r">Rot</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="255" step="1" value="0">
           <input type="number" id="rgb_r_r" min="0" max="255" step="1" value="0">
         </fieldset>
         
         <fieldset>
           <label for="rgb_r_g">Grün</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="255" step="1" value="0">
           <input type="number" id="rgb_r_g" min="0" max="255" step="1" value="0">
         </fieldset>
         
         <fieldset>
           <label for="rgb_r_b">Blau</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="255" step="1" value="0">
           <input type="number" id="rgb_r_b" min="0" max="255" step="1" value="0">
         </fieldset>
       </fieldset>
       <fieldset id="hsl_r">
         <legend>HSL</legend>
         
         <fieldset>
           <label for="hsl_r_h">Hue (Farbton)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="360" step="1" value="0">
           <input type="number" id="hsl_r_h" min="0" max="360" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="hsl_r_s">Saturation (Sättigung)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="100" step="1" value="0">
           <input type="number" id="hsl_r_s" min="0" max="100" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="hsl_r_l">Lightness (Helligkeit)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="100" step="1" value="0">
           <input type="number" id="hsl_r_l" min="0" max="100" step="1" value="0">
         </fieldset>
       </fieldset>
       <fieldset id="oklch_r">
         <legend>OKLCH</legend>
         
         <fieldset>
           <label for="oklch_r_l">Lightness (Helligkeit)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="100" step="1" value="0">
           <input type="number" id="oklch_r_l" min="0" max="100" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="oklch_r_c">Chroma (Menge an Farbe)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="125" step="1" value="0">
           <input type="number" id="oklch_r_c" min="0" max="125" step="1" value="0">
         </fieldset>
         <fieldset>
           <label for="oklch_r_h">Hue (Farbton)</label>
           <input type="range" tabindex="-1" aria-hidden="true" min="0" max="360" step="1" value="0">
           <input type="number" id="oklch_r_h" min="0" max="360" step="1" value="0">
         </fieldset>
       </fieldset>
     </section>
   <figure>
     <figure id="CSS_RGB"></figure>
     <figcaption id="anzeige_RGB"></figcaption>
   </figure>
   <figure>
     <figure id="CSS_HSL"></figure>
     <figcaption id="anzeige_HSL"></figcaption>
   </figure>
   <figure>
     <figure id="CSS_OKLCH"></figure>
     <figcaption id="anzeige_OKLCH"></figcaption>
   </figure>
   

Da der oklch-Farbraum größer ist, als der rgb-Farbraum, werden bei der Umrechnung von oklch nach rgb negative Werte und Werte größer als 255 berechnet. Für die Umrechnung nach hsl und für die Anzeige werden diese Werte auf den Bereich 0 bis 255 begrenzt.

Die unteren beiden Verläufe werden (Stand: Januar 2024) von allen Browsern außer dem Firefox dargestellt. Dieser unterstützt die Interpolationssteuerung (in hsl, in oklch) noch nicht.

 </body>

</html>