아티클

button의 브라우저별 랜더링 비교, 사용방법, 문제점, 해결방법

2009-04-24 11:45:57

안녕하세요. 웹표준화팀 한혜진입니다.

저는 그동안 <button>엘리먼트는 생소하고, 그 기능도 모호한 것 같아서 잘 사용하지 않았었습니다.
그런데 에디터 관련 프로젝트를 진행하던 중, 글편집기 상단에 도구 모음들을 마크업해야 할 일이 생겼고,
<a>와 <button> 중 어떤 태그로 마크업 하는 것이 더 시멘틱 할까를 고민하게 되었습니다.

<a>와 <button>의 쓰임새를 정리해보자면,
<a>
엘리먼트는 앵커(anchor)로써 문서 간의 연결, URI 참조가 주된 목적이고
<button>
엘리먼트는 누를 수 있는 단추로써, 누르거나 눌렀다 놓았을 때 이벤트를 발생시키도록 하는게 주된 목적입니다.

그러므로, 이벤트를 발생시켜야 하지만 Submit 할 것은 아닌,
단순히 UI조작(기능 선택, 레이어 보이기, 숨기기, 삭제 등)을 위한 버튼이라면
<button>엘리먼트를 사용하는 것이 시멘틱할 것 같다는 게 저의 생각이었습니다.

또 개발 담당자분께서 말씀하시길,
도구 모음쪽에 <a> 엘리먼트를 사용할 경우, 도구모음을 클릭하고 편집기에서 글을 쓰면 글이 잘 안써지는 버그가 있는데
<button>엘리먼트를 사용하면 그 버그가 발생하지 않는다고 하셨습니다.
그래서 더욱 힘을 얻고 <button> 엘리먼트로 마크업을 하게 되었습니다.

그런데 <button>엘리먼트로 마크업하면서 생각치 못한 여러가지 문제점들이 발생했습니다.
어떤 문제점 들이 있었는지 <button>의 브라우저별 랜더링 비교, 사용 방법, 문제점, 해결 방법 등을 지금부터 공유합니다.

 


<button>엘리먼트의 브라우저별 랜더링 비교

<button>엘리먼트는 다음과 같이 마크업할 수 있습니다.

<button type="button">글자색</button> 

그러면 IE는 다음과 같이 랜더링합니다.
글자색


다른 브라우저에서도 IE와 동일하게 랜더링할까요? 바로 비교해보겠습니다.


※ 기본 버튼의 브라우저별 랜더링 비교

브라우저별 button 엘리먼트 랜더링 비교

다른 form요소도 그러하듯이, <button>엘리먼트도 각 브라우저가 가진 고유의 스타일로 랜더링 합니다.
넓이도, 높이도, 모양도 다르고, 텍스트의 세로 정렬도 다릅니다.
심지어 텍스트를 왼쪽 정렬시켜도, 각 브라우저마다 여백에 많은 차이가 있는 것을 한눈에 알 수 있습니다.
이 녀석을 어떻게 내 입맛에 맞게 구워 삶으면 좋을까요?



<button> 엘리먼트 사용방법

텍스트를 정렬하기 위한 버튼의 조합이 있습니다.

정렬

세개 버튼중 왼쪽 정렬 버튼은 다음과 같이 마크업할 수 있습니다.

button {width:21px; height:21px; margin:0; padding:0; border:0; background:none; font-size:0; line-height:0; cursor:pointer;} <button type="button"><img src="left.gif" alt="왼쪽정렬" wdith="21" height="21"></button> 

▶ img를 사용한 버튼 보기

이렇게 마크업을 하면 버튼 클릭시 움직임이 있습니다.
더 큰 문제는 FF와 Chrome에서는 button이 기본적으로 여백을 가지고 있다는 것입니다. (아래 표 참고)
FF과 Chrome에서도 그 여백에 차이가 있어 CSS hack으로도 완벽히 동일하게는 처리가 어렵습니다.



※ button에 img를 넣었을 때 브라우저별 랜더링 비교

버튼 비교

 

저는 클릭시 움직임이 없으며, 모든 브라우저에서 동일한 버튼을 만들기 위해 아래와 같이 마크업했습니다.

button {width:21px; height:21px; margin:0; padding:0; border:0; background:url(http://html.nhndesign.com/img/blog/hhj/img/align_set.gif) no-repeat; cursor:pointer; /* button에 배경삽입 */} button span {overflow:hidden; position:absolute; top:0; left:0; width:0; height:0; visibility:hidden;/* 대체 텍스트 숨김 처리 */} <button type="button" title="왼쪽정렬"><span>왼쪽정렬</span></button> 

▶ 클릭시 움직임이 없는 버튼 보기


이미지는 button에 background로 처리했습니다.
<span>왼쪽정렬</span>은 대체 텍스트와 같은 역할을 위해 넣었으며,
title은 툴팁 효과를 내기 위해 넣었습니다.
이 버튼은 모든 브라우저에서 동일하게 보이며, 클릭시 움직이지 않습니다. (단, IE8에서는 클릭시 움직임이 있습니다.)

이렇게 마크업을 하면, CSS가 깨졌을 경우 다음 처럼 랜더링 됩니다.
CSS가 깨졌을 경우1

만약 <span>왼쪽정렬</span> 을 넣지 않으면 CSS가 깨질 경우 다음 처럼 랜더링됩니다.
CSS가 깨졌을 경우2

그렇기 때문에 대체 텍스트 역할을 할 <span>왼쪽정렬</span> 넣어주고, 눈에 보이지 않도록 스타일을 지정합니다.
display:none 처리를 하지 않은 것은 시각장애인이 스크린리더기를 사용해서 읽을 때도 읽을 수 있도록 하기 위함입니다.

잠시 visibility 속성에 대해 짚고 넘어가자면,
현재 국산 스크린리더기인 센스리더는 visibility:hidden을 display:none과 마찬가지로 읽어주지 않고 있는데 이것은 잘못된 것입니다.
http://trio.co.kr/webrefer/css2/propidx.html 에서 보면
visibility 속성은 미디어 타입이 visual일때 지켜야 하는 사항이라고 나와있습니다.
즉 '미디어 타입이 눈으로 볼 수 있는 TV, 스크린, 프린트 등일때 visibility:hidden이라면 보여주지 말아야 한다' 는 건데요.
스크린리더기는 aural 타입이므로 visibility:hidden으로 되어 있어도 읽을 수 있게 해주어야 합니다.
그래서 센스리더 측에 제안을 했고, 다행히도 다음 버전에서 업데이트 해주신다고 합니다.

이렇게 작업을 해주면 모든 브라우저에서 동일하게 보여지고, 클릭시 움직임도 없습니다.
개발을 붙일 때도 용이하며 CSS가 깨졌을 경우에도 콘텐츠 내용을 알 수 있으므로 접근성도 좋아집니다.
하지만 이미지가 로딩이 안될 경우에는 아무것도 안보이게 되는데요. 이럴 경우는 거의 없다라고 생각하고 넘어가겠습니다.



IE8에서 문제점


여기서 한가지 문제가 있습니다.
위에 제시한 대로 마크업을 하면 버튼을 클릭시에도 오페라, 사파리, 크롬, IE7이하, FF에서 모두 움직임이 없고, 여백도 없이 동일하게 보여집니다.
하지만 IE8에서는 button 자체가 움직이기 때문에 이미지를 배경으로 처리해도 움직이게 됩니다.

브라우저단에서는 클릭시에 움직임을 줌으로써 "이 녀석은 누를 수 있는 '버튼'입니다" 라고 명확하게 알려주고,
사용자로 하여금 풍부한 기능을 체험
하게 해주고 싶었을 겁니다.
그렇기 때문에 움직이면 움직이는 데로 자연스럽게 두는 것이 풍부한 사용자 경험을 위해서는 더 좋을 수 있습니다.
실제로, 제가 진행하는 프로젝트에서는 버튼이 움직이는 것이 크게 나빠보이지 않는다는 의견이 많아
IE8에서 움직이는 현상을 자연스럽게 그대로 두기로 했습니다.

하지만, 클릭시 움직임이 디자이너의 관점에서는 용납이 안되는 경우가 있을 수도 있기 때문에 그 해결 방법을 제시합니다.
ex) 클릭시 움직임으로 인해 전체 그리드가 깨져보이는 경우
툴바


해결 방법

해결방법1

button {width:21px; height:21px; margin:0; padding:0; border:0; background:none; cursor:pointer;} button span {position:relative; display:block; width:21px; height:21px; margin:0; padding:0; background:url(img/align_set.gif) no-repeat;} button span span {overflow:hidden; position:absolute; top:0; left:0; width:0; height:0; margin:0; padding:0; visibility:hidden;} button span, x:-moz-any-link, x:default {margin:-2px 0 0 -3px !important;} /* Mozilla 계열만 인식되는 firefox 핵 */ @media screen and (-webkit-min-device-pixel-ratio:0) { button span{margin:-1px 0 0 -3px !important;} } /* Webkit 엔진계열만 인식하는 safari,chrome 핵 */ <button type="button" title="왼쪽정렬"><span><span>왼쪽정렬</span></span></button>

▶ 해결방법1 로 마크업한 버튼 보기

<span>에 배경이미지를 주고 position을 relative로 주었습니다.
이렇게 하면 IE8에서도 움직이지 않게 됩니다.
하지만 여전히 FF과 Chrome에서 여백이 발생하므로 CSS hack을 사용했습니다.
(단, Opera에서는 클릭시에 움직임이 있습니다. -_-; 여렵다 어려워..)

 

해결 방법2

.left {display:block; width:21px; height:21px; margin:0; padding:0; border:0; font-size:0; background:url(http://html.nhndesign.com/img/blog/hhj/img/align_set.gif) 0 0 no-repeat;} button {width:21px; height:21px; margin:0; padding:0; border:0; background:none; cursor:pointer;} button span {overflow:hidden; position:absolute; top:0; left:0; width:0; height:0; margin:0; padding:0; visibility:hidden;} <span class="left"><button type="button" title="왼쪽정렬"><span>왼쪽정렬</span></button></span>

▶ 모든 브라우저에서 동일하게 보여지는 button 보기

<button>을 <span>으로 감싸고, <span>에 이미지를 배경처리 합니다.
이렇게 처리하면 CSS Hack을 쓰지 않아도, IE8에서도 움직이지 않고, 모든 브라우저에서 동일하게 보여집니다.
하지만 불필요한 태그가 생김으로 해서 CSS스타일도 그만큼 늘어나게 되니,
퍼포먼스와 심미성의 경중을 따져서 결정하시면 될 것 같습니다.

 

<button>엘리먼트에 대해서 많은 자세한 내용을 전달하고 싶은 마음에 글이 너무 길어졌네요.
끝까지 읽어주셔서 감사합니다.



궁금한 점이 있으시면 hyejin.han앳nhncorp.com 으로 문의주세요.

행복한 하루되세요~

댓글 0
댓글을 작성하려면 해주세요.