<!--  
  Worklet code here. I can't put this under JS pane anymore since
  I can't do CSS.paintWorklet.addModule('/rrenula/pen/js-code.js'); due to
  cors issue
-->
<script language="worklet">
  if (typeof registerPaint !== 'undefined') {
    class Checkbox {
      static get inputProperties() {
          return ['--checkbox-color', '--edge', '--thickness', '--p1', '--p2'];
      }
      
      paint(ctx, size, props) {
        const color = props.get('--checkbox-color');
        const edge = props.get('--edge').value;
        const p1 = props.get('--p1').value;
        const p2 = props.get('--p2').value;
        const x = edge
        const y = edge
        const finalX = size.width - edge
        const finalY = size.height - edge
        ctx.strokeStyle = color.toString()
        ctx.lineWidth = 5
       
        /* Top left to bottom right*/
        ctx.beginPath()
        ctx.moveTo(x, y)
        ctx.lineTo((p1 / 100) * finalX, (p1 / 100) * finalY)
        
        if (p1 > 0) {
          ctx.stroke()
        }
           
        ctx.beginPath();
        ctx.moveTo(finalX, y);
        ctx.lineTo(finalX, y);
        
        if (p2 > 0) {
          // x is gradually moving to its original point
          ctx.lineTo(finalX - ((p2 / 100) * finalX) + edge, finalY * (p2 / 100));
          ctx.stroke();
        }
      }
    }
    
    registerPaint('checkbox', Checkbox)
  }
</script>

<script type="module">
   CSS.registerProperty({
     name: `--checkbox-color`,
     syntax: '<color>',
     inherits: false,
     initialValue: 'transparent'
   })
      
  CSS.registerProperty({
    name: `--edge`,
    syntax: '<number>',
    inherits: false,
    initialValue: 0
  })
  
  CSS.registerProperty({
    name: `--thickness`,
    syntax: '<number>',
    inherits: false,
    initialValue: 0
  })
  
  CSS.registerProperty({
     name: `--p1`,
     syntax: '<percentage>',
     inherits: false,
     initialValue: '0%'
  })
      
  CSS.registerProperty({
      name: `--p2`,
      syntax: '<percentage>',
      inherits: false,
      initialValue: '0%'
  })
  
  function ready(fn) {
    if (document.readyState != 'loading'){
      fn();
    } else {
      document.addEventListener('DOMContentLoaded', fn);
    }
  }
  
  ready(() => {
    function blobWorklet() {
        const qs = document.querySelector('script[language="worklet"]')
        const src = qs.innerHTML;
        const blob = new Blob([src], {type: 'text/javascript'});
        return URL.createObjectURL(blob);
    }
      
    CSS.paintWorklet.addModule(blobWorklet())
    
    if ('paintWorklet' in CSS)  {
       document.querySelector('.notice').classList.add('hidden')
    }
  })
</script>

<div class="wrapper">
  Write up on this demo can be found <a href="https://aysha.me/019/08/css-houdini-properties-values-and-the-paint-api/" target="_blank">here on my blog</a>
  <div class="notice">
    This demo uses CSS Houdini. If you are seeing this, you need to enable CSS Houdini by navigating to <code>chrome://flags</code> and enable <code>Experimental Web Platform features</code>
  </div>
  <p class="q">Who would you take out on a date?</p>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Lord Voldemort</span></label>
  </div>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Harry Potter</span></label>
  </div>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Margaery Tyrell</span></label>
  </div>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Robb Stark</span></label>
  </div>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Legolas</span></label>
  </div>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Yennefer</span></label>
  </div>
  <div class="checkbox-wrapper">
       <input type="checkbox" class="checkbox">
       <label> <span class="checkbox-label">Geralt</span></label>
  </div>
</div>
/* CSS files add styling rules to your content */

body {
  font-family: "Benton Sans", "Helvetica Neue", helvetica, arial, sans-serif;
  margin: 2em;
  background: #9e4fdb;
  color: #fff;
  font-family: 'Lato', sans-serif;
}

h1 {
  font-style: italic;
  color: #373fff;
}

a,
a:visited {
  color: white;
}

a:hover {
  color: darkblue;
}


.q {
  font-size: 2.5rem;
  font-weight: 300;
}

.wrapper {
  max-width: 960px;
  margin: 20px auto;
}

.checkbox-label {
  font-size: 2rem;
  vertical-align: middle;
  color: #68388e;
}

.checkbox-wrapper {
  margin-bottom: 16px;
}

.checkbox {
  --edge: 5;
  --thickness: 5;
  transition: --checkbox-color 500ms, background-color 500ms;
}

@supports (background: paint(id)) {
 .checkbox {
    -webkit-appearance: none;
    background-image: paint(checkbox);
  }
}

.checkbox:hover {
  --p1: 100%;
  --p2: 100%;
  --checkbox-color: #ccc;
}

.checkbox:checked {
  --checkbox-color: white;
  --p1: 100%;
  --p2: 100%;
  background-color: deeppink;
  animation: draw 500ms ease-in-out;
}

.checkbox:checked + label > .checkbox-label {
  color: #fff;
}

.checkbox {
  --checkbox-color: transparent;
  margin-right: 24px;
  vertical-align: middle;
  width: 50px;
  height: 50px;
  border-radius: 2px;
  border: 3px solid #fff;
  transition: --checkbox-color 500ms, background-color 500ms;
}

.notice {
  background-color: darkred;
  padding: 8px;
  font-size: 20px;
  line-height: 1.5;
}

.hidden {
  display: none;
}

@keyframes draw {
  0% {
    --p1: 0%;
    --p2: 0%;
  }
  
  50% {
    --p1: 100%;
    --p2: 0%;
  }
  
  80% {
    --p1: 100%;
  }
  
  100% {
    --p1: 100%;
    --p2: 100%;
  }
}

// The JS code for this pen is at the top of the HTML

External CSS

  1. https://fonts.googleapis.com/css?family=Lato:300,400&amp;display=swap

External JavaScript

This Pen doesn't use any external JavaScript resources.