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>
		
		<!-- <h1>Farbmodelle vergleichen</h1> -->
		
		<div id="farbwaehler">
      
      <section id="links">

        <hgroup>
          <p id="anzeige_links"></p>
          <h2>Farbe am linken Rand</h2>
        </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>
          <h2>Farbe am rechten Rand</h2>
          <p id="anzeige_rechts"></p>
        </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>

    </div>
    
    <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>
    
    <p>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.</p> 
  </body>

</html>