http://jsbin.com/cikuga/edit?html,css,output
IE 호환을 위해 jQuery를 사용했다. 안해도 되지만 이 편이 그래도 좀 읽기 쉽지 않나 싶다.
접히고 펼쳐지는 트리구조를 만드는 데 있어 핵심 아이디어는 같은 깊이에 인접한(sibling ) 요소들끼리는 radio button을 사용하면 된다는 것이다.
가령
<input type="radio" name="group1">
<input type="radio" name="group1">
<input type="radio" name="group1">
이렇게 했을 경우 같은 이름(name)을 가지고 있으므로 셋 중 하나만 radio 버튼이 들어오고
<input type="radio" name="group1">
<input type="radio" name="group2">
<input type="radio" name="group2">
<input type="radio" name="group2">
<input type="radio" name="group1">
<input type="radio" name="group1">
이와 같이 구성하면 group2는 group2끼리 group1은 group1끼리 각각 구성할 수 있다.
따라서 각각의 radio button에 대한 id가
1
1-1
1-2
2
2-1
2-1-1
2-1-2
3
일 경우엔 1,2,3을 top
1-1, 1-2는 1
2-1은 2
2-1-1, 2-1-2는 2-1 같이 name을 지정해주면 된다.
여기서 label의 for와 input의 id를 맞춰주면 label을 클릭해도 radio가 켜지니 같이 묶어주자.
실제 렌더링은 아마도 이럴 것이다.
Label을 눌러도 radio가 잘 작동하는지 꼭 보자.
이제 CSS로 스타일링을 할 시간이다.
Label을 눌러도 되니 radio 버튼은 안봐도 된다.
그리고 대신 + 표시를 달아주자.
상대좌표니까 position을 relative로 하자.
이미지를 넣으려면 content: url(xxx.png) 식으로 지정하면 된다.
닫혀 있을 때 상태는 .tab-content 아래에 넣어서 숨기도록 한다.
다음은 펼친 상태를 구현할 차례인데
"라디오 버튼이 checked 일때 인접한 .tab-content가 보이도록"
하면 된다.
그리고 label:before 에 있던 + 도 - 로 바꿔주면 좋겠다.
마찬가지로,
input이 checked일때 ~ (sibling이면서 뒤쪽 어딘가에 있는) display: none이던 .tab-content도 보이게 하자.
IE 호환을 위해 jQuery를 사용했다. 안해도 되지만 이 편이 그래도 좀 읽기 쉽지 않나 싶다.
접히고 펼쳐지는 트리구조를 만드는 데 있어 핵심 아이디어는 같은 깊이에 인접한(sibling ) 요소들끼리는 radio button을 사용하면 된다는 것이다.
가령
<input type="radio" name="group1">
<input type="radio" name="group1">
<input type="radio" name="group1">
이렇게 했을 경우 같은 이름(name)을 가지고 있으므로 셋 중 하나만 radio 버튼이 들어오고
<input type="radio" name="group1">
<input type="radio" name="group2">
<input type="radio" name="group2">
<input type="radio" name="group2">
<input type="radio" name="group1">
이와 같이 구성하면 group2는 group2끼리 group1은 group1끼리 각각 구성할 수 있다.
따라서 각각의 radio button에 대한 id가
1
1-1
1-2
2
2-1
2-1-1
2-1-2
3
일 경우엔 1,2,3을 top
1-1, 1-2는 1
2-1은 2
2-1-1, 2-1-2는 2-1 같이 name을 지정해주면 된다.
여기서 label의 for와 input의 id를 맞춰주면 label을 클릭해도 radio가 켜지니 같이 묶어주자.
<input type="radio" name="top" id="r1">
<label for="r1">Title of Tab 1</label>
이런 식이면 충분.
전체적으로 구성을 해보자. 하위 아이템도 있고 그게 링크인 경우도 있을 수 있다.
<ol class="acc">
<li>
<input type="radio" name="top" id="r1">
<label for="r1">Title of Tab 1</label>
<ol class="tab-content">
<li>
<input type="radio" name="t-1" id="r1-1">
<label for="r1-1">Title of Tab 1</label>
<div class="tab-content">
cascaded!
</div>
</li>
<li>
<input type="radio" name="t-1" id="r1-2">
<label for="r1-2">Title of Tab 1</label>
<div class="tab-content">
cascaded!
</div>
</li>
</ol>
</li>
<li>
<input type="radio" name="top" id="r2">
<label for="r2">Title of Tab 1</label>
<ol class="tab-content">
<li>
<a href="#">link</a>
</li>
<li>
<a href="#">link</a>
</li>
</ol>
</li>
<li>
<input type="radio" name="top" id="r3">
<label for="r3">Title of Tab 1</label>
<div class="tab-content">
Some content....
</div>
</li>
</ol>
이와 같이 구성해보았다.
실제 렌더링은 아마도 이럴 것이다.
Label을 눌러도 radio가 잘 작동하는지 꼭 보자.
이제 CSS로 스타일링을 할 시간이다.
Label을 눌러도 되니 radio 버튼은 안봐도 된다.
input[type=radio] {숨기자.
display: none;
}
그리고 대신 + 표시를 달아주자.
label:before {label 위치보다 2글자 왼쪽에 content를 사용해서 "+"를 넣어줬다.
content: "+";
position: relative;
left: -2em;
}
상대좌표니까 position을 relative로 하자.
이미지를 넣으려면 content: url(xxx.png) 식으로 지정하면 된다.
닫혀 있을 때 상태는 .tab-content 아래에 넣어서 숨기도록 한다.
.tab-content {
display: none;
}
이걸로 닫힌 상태는 완성.
다음은 펼친 상태를 구현할 차례인데
"라디오 버튼이 checked 일때 인접한 .tab-content가 보이도록"
하면 된다.
그리고 label:before 에 있던 + 도 - 로 바꿔주면 좋겠다.
input:checked + label:before {input이 checked일때 + (바로 뒤에 인접한) label:before 의 content를 - 로 지정한다.
content: "-";
}
마찬가지로,
input이 checked일때 ~ (sibling이면서 뒤쪽 어딘가에 있는) display: none이던 .tab-content도 보이게 하자.
input:checked ~ .tab-content {
display: block;
}
간단?
이것만으로도 OK.
label:before 를 선택할 때 +대신 ~로 써도 되는거 아녀요? 라고 물어보면
그렇다! 라고 말할 수 있다. ~는 +를 포함하니 상관없다.
여기까지만이면 좋겠는데 선택해서 펼쳐진 상태에서 label을 또 클릭하면 닫게 하고 싶을 수 있다.
이건 CSS만으론 어렵고 약간 코드가 필요하다.
var selectedItemId = undefined;
$('input', handler).click(function(e) {
var t=e.target;
if (t.id === selectedItemId) {
t.checked = undefined;
selectedItemId = undefined;
} else {
selectedItemId = t.id;
}
});
radio는 한번 선택을 하면 같은 그룹에서 undefined로 지정하기 전까진 항상 어딘가가 checked인 상태이다.
따라서, 이전에 선택한 radio와 같은 걸 클릭하면 checked를 undefined로 지정한다.
약간 hacky 한 구현이라고 볼 수 있다.
마지막으로 radio 대신 checkbox 로도 바꿔도 보고 어떻게 다른지 관찰하면 더욱 좋겠다.
댓글
댓글 쓰기