h1 Sudoku without JS
p
  | Cross out hints by clicking on them.
  | Impossible values are hidden automatically to help you play!
input(type="radio", id="showhints", name="layer", checked="checked")
input(type="radio", id="setvals", name="layer")
each block in [1,2,3,4,5,6,7,8,9]
  each cell in [1,2,3,4,5,6,7,8,9]
    each val in [1,2,3,4,5,6,7,8,9]
      input(type="checkbox", id="n"+((block-1)*9+cell)+"v"+val, block=block, cell=cell, val=val, row=(Math.floor((block-1)/3)*3+Math.floor((cell-1)/3)+1), col=(block-1)%3*3+(cell-1)%3+1, num=(block-1)*9+cell)
label.button(for="showhints")
  | Set Hints
label.button(for="setvals")
  | Set Values
.cells.grid
  each block in [1,2,3,4,5,6,7,8,9]
    .block.grid
      each cell in [1,2,3,4,5,6,7,8,9]
        .cell(block=block, cell=cell)
          .hints.grid
            each value in [1,2,3,4,5,6,7,8,9]
              label.hint
                input(type="checkbox")
                .hintv(val=value, block=block, cell=cell, row=(Math.floor((block-1)/3)*3+Math.floor((cell-1)/3)+1), col=(block-1)%3*3+(cell-1)%3+1, num=(block-1)*9+cell)
          .values.grid(block=block, cell=cell, num=(block-1)*9+cell)
            each value in [1,2,3,4,5,6,7,8,9]
              label.value(val=value, for="n"+((block-1)*9+cell)+"v"+value, block=block, cell=cell, row=(Math.floor((block-1)/3)*3+Math.floor((cell-1)/3)+1), col=(block-1)%3*3+(cell-1)%3+1, num=(block-1)*9+cell)
View Compiled
html { font-size: 15px; }
* { box-sizing: border-box; }
input { display: none; }
.grid {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
}
.grid > * {
  position: absolute;
  width: 33.33%;
  height: 33.33%;
}
.grid > :nth-child(3n+1) { left: 0; }
.grid > :nth-child(3n+2) { left: 33.33%; }
.grid > :nth-child(3n+3) { left: 66.67%; right: 100%; }
.grid > :nth-child(-n+3) { top: 0%; }
.grid > :nth-child(n+4):nth-child(-n+6) { top: 33.33%; }
.grid > :nth-child(n+7) { top: 66.66%; bottom: 100%; }

.cells { margin: 2em; width: 36em; height: 36em; border: 2px solid; position: relative; }
.block { border: 1px solid; }
.cell { border: 1px solid; }

/* Hints */
.hint { display: flex; justify-content: center; align-items: center;}
.hintv { flex: 1; text-align: center; }
.hintv::before { content: attr(val); }
// Unchecked hints are possible. Checked hints are ruled out.
.hint { opacity: .4; }
:checked + .hintv { opacity: 0; }
.cell:hover {
  .hint { opacity: 1; }
  :checked + .hintv { opacity: .2; }
}

/* Values */
.values { display: none; }
#setvals:checked ~ .cells .cell:hover .values {
  display: block;
}
.values {
  color: blue;
  background: white;
}
.value { 
  display: flex; 
  justify-content: center; 
  align-items: center; 
}
.value::before {
  content: attr(val);
}
@for $n from 1 through 81 {
  // Once a cell has a value set, perma-show its values block and hide the other values.
  input[num="#{$n}"]:checked ~ .cells [num="#{$n}"]{
    &.value { display: none; }
    &.values { display: flex; }
  } 
  @for $v from 1 through 9 {
    // Style the set value properly to make it big and obvious.
    ##{"n"+$n+"v"+$v}:checked ~ .cells .value[for=#{"n"+$n+"v"+$v}] {
      display: flex;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100%;
      height: 100%;
      font-size: 2.5em;
    }
  }
}
@for $v from 1 through 9 {
  @for $b from 1 through 9 {
    // Hide hints and value selections in a block for an already-selected value.
    input[block="#{$b}"][val="#{$v}"]:checked ~ .cells [block="#{$b}"][val="#{$v}"] {
      &.hintv, &.value {
        display: none;
      }
    }
  }
  // Now do the same for columns.
  @for $col from 1 through 9 {
    input[col="#{$col}"][val="#{$v}"]:checked ~ .cells [col="#{$col}"][val="#{$v}"] {
      &.hintv, &.value {
        display: none;
      }
    }
  }
  // And for rows.
  @for $row from 1 through 9 {
    input[row="#{$row}"][val="#{$v}"]:checked ~ .cells [row="#{$row}"][val="#{$v}"] {
      &.hintv, &.value {
        display: none;
      }
    }
  }
}

/* Buttons */
.button {
  background: silver;
  padding: 2px 5px;
  border: 2px solid black;
  border-radius: 5px;
  cursor:pointer;
  position: relative;
}
.button:active {
  left: 2px; top: 2px;
}
#showhints:checked ~ [for=showhints],
#setvals:checked   ~ [for=setvals] {
  background: #44f;
  color: white;
}
  
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.