라디오버튼 + 이미지 조합, 모든 브라우저에서 클릭과 정렬맞추기 2007/12/10 09:21
폼을 구성하는 라디오버튼, 셀렉트박스 등은 브라우저마다 다르게 출력되기 때문에, 실제 웹사이트를 만들 때, 이 녀석들의 디자인을 컨트롤 하는 것이 여간 까다로운 것이 아닙니다.
이번에는 라디오버튼과 이미지가 조합되서 클릭되어야 할 때, 발생하는 문제점 몇 가지를 해결한 코딩법을 소개해 드리겠습니다.

다음과 같은 U.I.를 만들어야 됩니다. 세 가지의 옵션 중 하나를 선택하게 하는 UI인데요, 접근성을 높이기 위해서는 다음과 같은 조건이 전제되어야 합니다.
디자인이 들어가는 CSS는 일단 논외로 하겠습니다.
이 코드는 input 과 img 를 라벨로 묶은 기본적인 형태입니다.
하지만, 우리의 일반적인 생각과 달리 이 소스에는 문제가 있습니다.
파 이어폭스에서는 이미지를 클릭하면 label 로 묶어진 라디오버튼 까지 한번에 클릭이 됩니다만, 익스플로러 계열에서는 이 소스 만으로는 이미지를 클릭해서는 라디오버튼이 꿈쩍도 하지 않습니다. 결국 유저에게 그 작은 라디오 버튼을 누르라고 강요하게 되는 것이고, 이것은 웹접근성이 많이 떨어지게 됩니다.
첫 소스보다는 다소 진보된 소스입니다.
input 버튼에 고유 id 값을 주었습니다. 클릭될 이미지를 label로 묶은 다음, 라벨에 for 값을 주어서, 강제로 해당 라디오 버튼을 눌리게 한 것 입니다.
하지만, 이 소스도 문제가 있습니다.
역 시나 파이어폭스에서는 작동을 합니다만, 익스플로러 계열에서는 작동을 하지 않습니다. 만약 label for 옵션을 사용할 때, 이미지 대신 텍스트라면 익스플로러 계열에서도 동작을 합니다만, 이미지를 사용할 경우 라디오 버튼이 꿈쩍도 하지 않습니다. 아이러니한건 이미지에 마우스 over시 라디오버튼이 반응은 보인다는 것 입니다. 뭐 클릭이 안되니까 쓸모는 없지만 말입니다.
바로, 라벨의 for 값으로 라디오 버튼을 클릭하고, 라벨 사이에는 실제로 '텍스트'가 들어가게 하되, CSS로 이 텍스트를 이미지로 치환하는 방법입니다.
이렇게 하니까. IE6, IE7 등 익스플로러 계열에서도 잘 작동하고, 파이어폭스와 다른 브라우저에서도 문제없이 잘 동작하네요.
만약 정렬문제가 귀찮으시다면, 위의 소스처럼 테이블을 나눠서 엘리먼트를 배치하셔도 됩니다~
이번에는 라디오버튼과 이미지가 조합되서 클릭되어야 할 때, 발생하는 문제점 몇 가지를 해결한 코딩법을 소개해 드리겠습니다.
다음과 같은 U.I.를 만들어야 됩니다. 세 가지의 옵션 중 하나를 선택하게 하는 UI인데요, 접근성을 높이기 위해서는 다음과 같은 조건이 전제되어야 합니다.
이미지를 클릭해도, 라디오버튼이 선택 되도록 하는 것네, 이용자가 원하는 옵션의 이미지를 클릭해도, 라디오 버튼이 선택되도록 하는 것이 접근성을 조금 더 높일 수 있는 방법이겠습니다. 그러면 이 UI를 만들기 위해서 어떻게 코딩하시나요?
삽질 1
<label>
<input type="radio" name="blog" checked="checked" />
<img src="http://monoeyes.com/tistory.gif" width="103" height="28" alt="티스토리" />
</label>
<label>
<input type="radio" name="blog" />
<img src="http://monoeyes.com/tattertools.gif" width="119" height="28" alt="태터툴즈" />
</label>
<label>
<input type="radio" name="blog" />
<img src="http://monoeyes.com/textcube.gif" width="113" height="28" alt="텍스트큐브" />
</label>
<label>
<input type="radio" name="blog" checked="checked" />
<img src="http://monoeyes.com/tistory.gif" width="103" height="28" alt="티스토리" />
</label>
<label>
<input type="radio" name="blog" />
<img src="http://monoeyes.com/tattertools.gif" width="119" height="28" alt="태터툴즈" />
</label>
<label>
<input type="radio" name="blog" />
<img src="http://monoeyes.com/textcube.gif" width="113" height="28" alt="텍스트큐브" />
</label>
디자인이 들어가는 CSS는 일단 논외로 하겠습니다.
이 코드는 input 과 img 를 라벨로 묶은 기본적인 형태입니다.
하지만, 우리의 일반적인 생각과 달리 이 소스에는 문제가 있습니다.
파 이어폭스에서는 이미지를 클릭하면 label 로 묶어진 라디오버튼 까지 한번에 클릭이 됩니다만, 익스플로러 계열에서는 이 소스 만으로는 이미지를 클릭해서는 라디오버튼이 꿈쩍도 하지 않습니다. 결국 유저에게 그 작은 라디오 버튼을 누르라고 강요하게 되는 것이고, 이것은 웹접근성이 많이 떨어지게 됩니다.
삽질 2
<input type="radio" name="blog" checked="checked" id="tistory" />
<label for="tistory">
<img src="http://monoeyes.com/tistory.gif" width="103" height="28" alt="티스토리" />
</label>
<input type="radio" name="blog" checked="checked" id="tattertools" />
<label for="tattertools">
<img src="http://monoeyes.com/tattertools.gif" width="119" height="28" alt="태터툴즈" />
</label>
<input type="radio" name="blog" checked="checked" id="textcube" />
<label for="textcube">
<img src="http://monoeyes.com/textcube.gif" width="113" height="28" alt="텍스트큐브" />
</label>
<input type="radio" name="blog" checked="checked" id="tistory" />
<label for="tistory">
<img src="http://monoeyes.com/tistory.gif" width="103" height="28" alt="티스토리" />
</label>
<input type="radio" name="blog" checked="checked" id="tattertools" />
<label for="tattertools">
<img src="http://monoeyes.com/tattertools.gif" width="119" height="28" alt="태터툴즈" />
</label>
<input type="radio" name="blog" checked="checked" id="textcube" />
<label for="textcube">
<img src="http://monoeyes.com/textcube.gif" width="113" height="28" alt="텍스트큐브" />
</label>
첫 소스보다는 다소 진보된 소스입니다.
input 버튼에 고유 id 값을 주었습니다. 클릭될 이미지를 label로 묶은 다음, 라벨에 for 값을 주어서, 강제로 해당 라디오 버튼을 눌리게 한 것 입니다.
하지만, 이 소스도 문제가 있습니다.
역 시나 파이어폭스에서는 작동을 합니다만, 익스플로러 계열에서는 작동을 하지 않습니다. 만약 label for 옵션을 사용할 때, 이미지 대신 텍스트라면 익스플로러 계열에서도 동작을 합니다만, 이미지를 사용할 경우 라디오 버튼이 꿈쩍도 하지 않습니다. 아이러니한건 이미지에 마우스 over시 라디오버튼이 반응은 보인다는 것 입니다. 뭐 클릭이 안되니까 쓸모는 없지만 말입니다.
해법
HTML 코드
<table class="blogtype">
<tr>
<td>
<input type="radio" name="blogtype" checked="checked" id="tistory" />
<label for="tistory">
<span class="tistory"><b>티스토리</b></span>
</label>
</td>
<td>
<input type="radio" name="blogtype" id="tattertools" />
<label for="tattertools">
<span class="tattertools"><b>태터툴즈</b></span>
</label>
</td>
<td>
<input type="radio" name="blogtype" id="textcube" />
<label for="textcube">
<span class="textcube"><b>텍스트큐브</b></span>
</label>
</td>
</tr>
</table>
CSS 코드
.blogtype { margin-bottom: 28px; overflow: visible; }
.blogtype b { display: none; }
.blogtype input { margin-right: 2px; float: left; display: block; margin-top: 9px; }
.blogtype span { margin-right: 7px; }
.blogtype .tistory { background: url(../images/icon_tistory.gif) 0 0 no-repeat; display: block; width: 103px; height: 28px; float: left; }
.blogtype .tattertools { background: url(../images/icon_tattertools.gif) 0 0 no-repeat; display: block; width: 119px; height: 28px; float: left; }
.blogtype .textcube { background: url(../images/icon_textcube.gif) 0 0 no-repeat; display: block; width: 113px; height: 28px; float: left; }
HTML 코드
<table class="blogtype">
<tr>
<td>
<input type="radio" name="blogtype" checked="checked" id="tistory" />
<label for="tistory">
<span class="tistory"><b>티스토리</b></span>
</label>
</td>
<td>
<input type="radio" name="blogtype" id="tattertools" />
<label for="tattertools">
<span class="tattertools"><b>태터툴즈</b></span>
</label>
</td>
<td>
<input type="radio" name="blogtype" id="textcube" />
<label for="textcube">
<span class="textcube"><b>텍스트큐브</b></span>
</label>
</td>
</tr>
</table>
CSS 코드
.blogtype { margin-bottom: 28px; overflow: visible; }
.blogtype b { display: none; }
.blogtype input { margin-right: 2px; float: left; display: block; margin-top: 9px; }
.blogtype span { margin-right: 7px; }
.blogtype .tistory { background: url(../images/icon_tistory.gif) 0 0 no-repeat; display: block; width: 103px; height: 28px; float: left; }
.blogtype .tattertools { background: url(../images/icon_tattertools.gif) 0 0 no-repeat; display: block; width: 119px; height: 28px; float: left; }
.blogtype .textcube { background: url(../images/icon_textcube.gif) 0 0 no-repeat; display: block; width: 113px; height: 28px; float: left; }
바로, 라벨의 for 값으로 라디오 버튼을 클릭하고, 라벨 사이에는 실제로 '텍스트'가 들어가게 하되, CSS로 이 텍스트를 이미지로 치환하는 방법입니다.
이렇게 하니까. IE6, IE7 등 익스플로러 계열에서도 잘 작동하고, 파이어폭스와 다른 브라우저에서도 문제없이 잘 동작하네요.
만약 정렬문제가 귀찮으시다면, 위의 소스처럼 테이블을 나눠서 엘리먼트를 배치하셔도 됩니다~
http://monoeyes.com/trackback/447
-
케인
2008/01/21 16:37하지만 여기서 table 을 사용하면 그 즉시 접근성을 해치는게 되는거 아닌가요?
layout 의 개념을 table 로 처리하는건 좀 바람직하지 않다고 봅니다.
대안은? 찾는중..-
이 예제에서 중요한 것은 테이블이냐 아니냐가 아닙니다.
이미지 + 라디오 버튼 조합에서.
이미지를 클릭해도 모든 플랫폼과 브라우저에서 라디오버튼을 활성화 시키는데 그 의의를 둡니다.
(일반적으로 라벨로 라디오버튼과 이미지를 묶어서 작성해도, 이미지클릭시 일부 플랫폼[IE]에서는 요지부동이기 때문이지요)
핵심은 이거죠.
label for 를 사용하고. 이미지는 텍스트를 치환한다.
이 예제에서 테이블은 중요한 것이 아닙니다.
다른 레이아웃 기법으로 표현하시면 되지요^^
위의 예제는 설명하기 쉽게 하기 위해서 table 을 썼을 뿐입니다.
실무에서 제가 코딩을 한다면
UL LI 를 활용할 것 같습니다
-







