jquery 없이 css만으로 on/off 상태를 기억하는 ui 만드는 방법

리스트가 펼쳐졌는지 아닌지를 처리하기위해서 흔하게 사용하는 방법이 addClass('unfolded')와 removeClass('unfolded')를 시키는 것이다.

번거롭기는 하지만, css만으로도 동일한 기능을 구현할 수 있다.
이 방법을 사용하면 script 코드는 짧아지는 대신에 css 코드는 길어진다.




1. HTML이 있다. on/off 상태를 변경시키고 기억하기위한 checkbox와 label, 그리고 checkbox의 상태를 표시해주는 글자들로 구성되어있다.

<label>
  <input type='checkbox'>
  <span class='yes'>Checked</span>
  <span class='no'>Not checked</span>
</label>




2. CSS가 있다.
클릭할 수 있는 범위를 넓게 확보하기위해서 label의 display속성은 block으로 했다.
checkbox의 상태에 따라 어떤 span은 보이고 어떤 span은 안보이게 했다.

<style>
  label { display: block; }
  input { display: none; }
  span { display: none; }
  input:checked ~ .yes { display: inline; }
  input:not(:checked) ~ .no { display: inline; }
</style>



이상의 것들만 있으면 checked인지 아닌지를 보여줄 수 있다.











그런데, CSS selector의 제약때문에 구현이 아주 자유롭지는 못하다. CSS에서는 parent를 선택할 수 없다. 그 이유로, 위의 예에서 checkbox가 checked인 경우에 label의 배경색을 red로 하고싶더라도 그렇게 할 수가 없다. CSS의 selector가 도달할 수 있는 영역은 기껏해야 siblings까지이다. 그러므로 배경색을 바꾸고싶은 대상의 형제레벨까지 checkbox를 옮겨가야 한다.


3. HTML을 수정한다.

<input id='chk1' type='checkbox'>
<label for='chk1'>
  <span class='yes'>Checked</span>
  <span class='no'>Not checked</span>
</label>




4. CSS를 수정한다.

<style>
  input { display: none; }
  label { display: block; }
  #chk1:checked ~ label { background-color: red; }
  span { display: none; }
  input:checked ~ label .yes { display: inline; }
  input:not(:checked) ~ label .no { display: inline; }
</style>





jQuery로 구현했을 때와 비교해보면, CSS로 구현한 것이 더 복잡하고 관리하기 어려운 코드가 나오는것 같다.