CSSだけでチェックボックスにチェックしたらテキストに打ち消し線してチェックした数も表示する

Ads

Result


いわゆるTodoアプリです。
機能的に完成させるのは難しいですが、CSSで出来るところまでやってみた、的なもの
:checkedや:notなどの疑似要素をふんだんに使って実装されていました
これだけだと実用性はないけど単純に凄いなぁと感心したので備忘録

css

/* smart-css todo boilerplate */
#smart-css:checked ~ #todos .dumb-thing { display: none }
#smart-css:checked ~ #todos .smart-thing { display: block }
#smart-css:checked ~ #todos .submit-unchanged { display: none }
#smart-css:checked ~ #todos .todo-item { color: #bbb }
#smart-css:checked ~ #todos .todo-item .faux { pointer-events: none }

/*CSSカウンターでチェックの数を監視。チェック項目数とチェック済み数を隣接表示する*/
#smart-css:checked {
  counter-reset: completed-todos total-todos changed-todos;
}
#smart-css:checked ~ .todo:checked {
  counter-increment: completed-todos total-todos;
}
#smart-css:checked ~ .todo {
  counter-increment: total-todos;
  outline: none;
}
#smart-css:checked ~ #todos h1 small:before {
  content: counter(completed-todos) '/' counter(total-todos);
}

#smart-css:checked ~ #todo0:focus ~ #todos .t0 [type=checkbox],
#smart-css:checked ~ #todo1:focus ~ #todos .t1 [type=checkbox],
#smart-css:checked ~ #todo2:focus ~ #todos .t2 [type=checkbox],
#smart-css:checked ~ #todo3:focus ~ #todos .t3 [type=checkbox],
#smart-css:checked ~ #todo4:focus ~ #todos .t4 [type=checkbox],
#smart-css:checked ~ #todo5:focus ~ #todos .t5 [type=checkbox] {
  outline: 5px auto -webkit-focus-ring-color
}

/*打ち消し線*/
#smart-css:checked ~ #todo0:checked ~ #todos .t0 .todo-label span,
#smart-css:checked ~ #todo1:checked ~ #todos .t1 .todo-label span,
#smart-css:checked ~ #todo2:checked ~ #todos .t2 .todo-label span,
#smart-css:checked ~ #todo3:checked ~ #todos .t3 .todo-label span,
#smart-css:checked ~ #todo4:checked ~ #todos .t4 .todo-label span,
#smart-css:checked ~ #todo5:checked ~ #todos .t5 .todo-label span {
  text-decoration: line-through;
}

/*全てにチェックが入ったらコメントを表示*/
#smart-css:checked ~ #todo0:checked + #todo1:checked + #todo2:checked + #todo3:checked + #todo4:checked + #todo5:checked + #todos h1 small:after {
  content: ' (お疲れ様!)';
  font-weight: bold
}

/*未チェックのアイテムに加える青いカラードット*/
#smart-css:checked ~ #todo0:not(:checked) ~ #todos .t0,
#smart-css:checked ~ #todo1:not(:checked) ~ #todos .t1,
#smart-css:checked ~ #todo2:not(:checked) ~ #todos .t2,
#smart-css:checked ~ #todo3:not(:checked) ~ #todos .t3,
#smart-css:checked ~ #todo4:not(:checked) ~ #todos .t4,
#smart-css:checked ~ #todo5:not(:checked) ~ #todos .t5 {
  color: rgb(0,100,200);
  counter-increment: changed-todos;
}

/* 未チェックの数を監視し、CSSカウンターを使ってテキストを表示 */
#smart-css:checked ~ #todo0:not(:checked) ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:not(:checked) ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked  ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:not(:checked) ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked  ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:not(:checked) ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:not(:checked) ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:not(:checked) ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after,
#smart-css:checked ~ #todo0:checked ~ #todo1:checked ~ #todo2:checked ~ #todo3:checked ~ #todo4:checked ~ #todo5:checked ~ #todos .changed-todos:after {
  content: counter(changed-todos) ' 個のタスクが残ってます';
}

#smart-css:checked ~ #todos .changed-todos:after {
  content: counter(changed-todos) ' 個のタスクが残ってます';
}

/* チェック状態を表示する為の非表示要素 */
#smart-css:checked ~ #todo0:checked       ~ #todos .t0 .nc,
#smart-css:checked ~ #todo0:not(:checked) ~ #todos .t0 .c,
#smart-css:checked ~ #todo1:checked       ~ #todos .t1 .nc,
#smart-css:checked ~ #todo1:not(:checked) ~ #todos .t1 .c,
#smart-css:checked ~ #todo2:checked       ~ #todos .t2 .nc,
#smart-css:checked ~ #todo2:not(:checked) ~ #todos .t2 .c,
#smart-css:checked ~ #todo3:checked       ~ #todos .t3 .nc,
#smart-css:checked ~ #todo3:not(:checked) ~ #todos .t3 .c,
#smart-css:checked ~ #todo4:checked       ~ #todos .t4 .nc,
#smart-css:checked ~ #todo4:not(:checked) ~ #todos .t4 .c,
#smart-css:checked ~ #todo5:checked       ~ #todos .t5 .nc,
#smart-css:checked ~ #todo5:not(:checked) ~ #todos .t5 .c {
  display: none
}
/* すべてチェックされたら残りアイテム数の明示テキストを非表示 */
#smart-css:checked ~ #todo0:checked + #todo1:checked + #todo2:checked + #todo3:checked + #todo4:checked + #todo5:checked + #todos .submit-changed {
  display: none
}
#smart-css:checked ~ #todo0:checked + #todo1:checked + #todo2:checked + #todo3:checked + #todo4:checked + #todo5:checked + #todos .submit-unchanged {
  display: inline-block
}

html

<form id="dumb-css" method="post" onsubmit="alert('これはダミーです。どこにも送信されません');return false">
  <input class="invisible" type="checkbox" id="smart-css" tabindex="-1" checked="checked"/>
  <input class="todo invisible" type="checkbox" id="todo0" name="is_0_done_b" title="仕事"/>
  <input class="todo invisible" type="checkbox" id="todo1" name="is_1_done_b" title="買い物" checked="checked"/>
  <input class="todo invisible" type="checkbox" id="todo2" name="is_2_done_b" title="家事" checked="checked"/>
  <input class="todo invisible" type="checkbox" id="todo3" name="is_3_done_b" title="メールチェック"/>
  <input class="todo invisible" type="checkbox" id="todo4" name="is_4_done_b" title="電話連絡"/>
  <input class="todo invisible" type="checkbox" id="todo5" name="is_5_done_b" title="挨拶周り"/>
  
  <div id="todos">
    <h1>やる事リスト <small style="-webkit-user-select:none;"></small></h1>
    <ul>
      <li class="todo-item t0">
        <label class="todo-label dumb-thing">
          <input class="real" type="checkbox" name="is_0_done_a" checked="checked"/>仕事
        </label>
        <label class="todo-label smart-thing" for="todo0"> 
          <input class="faux nc" type="checkbox" tabindex="-1"/>
          <input class="faux c" type="checkbox" tabindex="-1" checked="checked"/> <span>仕事</span>
        </label>
      </li>
      <li class="todo-item t1">
        <label class="todo-label dumb-thing">
          <input class="real" type="checkbox" name="is_1_done_a" checked="checked"/> 買い物
        </label>
        <label class="todo-label smart-thing" for="todo1"> 
          <input class="faux nc" type="checkbox" tabindex="-1"/>
          <input class="faux c" type="checkbox" tabindex="-1" checked="checked"/> <span>買い物</span>
        </label>
      </li>
      <li class="todo-item t2">
        <label class="todo-label dumb-thing">
          <input class="real" type="checkbox" name="is_2_done_a" checked="checked"/> 家事
        </label>
        <label class="todo-label smart-thing" for="todo2"> 
          <input class="faux nc" type="checkbox" tabindex="-1"/>
          <input class="faux c" type="checkbox" tabindex="-1" checked="checked"/> <span>家事</span>
        </label>
      </li>
      <li class="todo-item t3">
        <label class="todo-label dumb-thing">
          <input class="real" type="checkbox" name="is_3_done_a" checked="checked"/> メールチェック
        </label>
        <label class="todo-label smart-thing" for="todo3"> 
          <input class="faux nc" type="checkbox" tabindex="-1"/>
          <input class="faux c" type="checkbox" tabindex="-1" checked="checked"/> <span>メールチェック</span>
        </label>
      </li>
      <li class="todo-item t4">
        <label class="todo-label dumb-thing">
          <input class="real" type="checkbox" name="is_4_done_a" checked="checked"/> 電話連絡
        </label>
        <label class="todo-label smart-thing" for="todo4"> 
          <input class="faux nc" type="checkbox" tabindex="-1"/>
          <input class="faux c" type="checkbox" tabindex="-1" checked="checked"/> <span>電話連絡</span>
        </label>
      </li>
      <li class="todo-item t5">
        <label class="todo-label dumb-thing">
          <input class="real" type="checkbox" name="is_5_done_a" checked="checked"/> 挨拶周り
        </label>
        <label class="todo-label smart-thing" for="todo5"> 
          <input class="faux nc" type="checkbox" tabindex="-1"/>
          <input class="faux c" type="checkbox" tabindex="-1" checked="checked"/> <span>挨拶周り</span>
        </label>
      </li>
      
    </ul>
    <div>
      <div class="dumb-thing">
        <input class="submit-changed" type="submit" name="save_set_a" value="保存"/>
      </div>
      <div class="smart-thing submit-changed">
        <input type="submit" name="save_set_b" value="保存"/><small class="changed-todos"> </small>
      </div>
      <div class="smart-thing submit-unchanged">
        <input type="submit" name="save_set_b" value="保存" disabled="disabled"/>
      </div>
    </div>
  </div>
</form>

via

CSS-only Todo