이콜레모 개발자 위키

파일 업로드 버튼 CSS로 꾸미기


Youngrok Pak at 5 years, 10 months ago.

The Problem#

HTML 폼에서 파일 업로드 버튼만큼은 CSS로 꾸밀 수가 없다. 꾸밀 수 없는 이유는 보안 때문이다. 업로드 버튼을 여러 가지 스타일로 바꿀 수 있게 되면 이걸 이용해서 사용자 PC의 파일을 업로드하게 하는 일종의 피싱을 할 수 있기 때문이다. 그래서, 가급적이면 업로드 버튼은 바꾸지 않는 것이 좋다.

 

그렇지만, 현실적으로 이걸 건드려야 하는 이유가 여러 가지로 존재한다. 디자이너들이 업로드 버튼을 이쁘게 꾸미고 싶어하는 것을 굳이 나무랄 이유는 없다. 파일을 업로드하는 버튼임을 사용자에게 확실히 알려주고 있다면 바꿔도 무방하다.

 

The Answer#

opacity 이용#

CSS 로 파일 업로드 버튼을 바꿀 수 없으니 버튼을 숨기고 다른 태그로 그 위를 덮으면 된다. 아쉽게도 display: hidden, visibility: hidden은 뜻대로 안된다. 아예 화면에 표시하지 않기 때문에 클릭해도 업로드 버튼이 동작하지 않는다. 그래서 불투명도를 0으로 만드는 것이다.

  1. filter:alpha(opacity=0) /* IE */
  2. opacity:0 /* 표준 호환 브라우저 */

 

이렇게 하면 파일 업로드 버튼은 안 보이지만 클릭은 가능하게 된다. 그 아래에 다른 태그로 버튼 모양만 그려놓으면 된다.

 

그런데, 여기서 문제가 하나 더 있다. 그려놓은 버튼과 뒤에 있는 파일 업로드 버튼의 영역이 일치하지 않는다는 것이다. opacity 없이 다음과 같은 코드를 띄워보자.

  1.         <input style="position: absolute; width: 100px; height: 50px;" type="file"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

그럼 아래처럼 나온다.

upload_not_match_button.gif

그러면 input을 가려도 영역이 달라서 안된다. 여기서 또 하나의 문제가 업로드 input의 텍스트필드와 버튼을 따로 컨트롤할 수 없다는 것이다. width, height를 줘 보자.

  1.         <input style="position: absolute; width: 120px; height: 50px;" type="file"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

upload_same_height.gif

다행히 height는 맞춰지지만 width는 안 먹는다. 파이어버그로 보면 영역은 반영이 되었는데 보이기는 다 보인다. 그런데, 먹히는 CSS가 있다. font-size.

  1.         <input style="position: absolute; width: 120px; height: 50px; font-size: 22px;" type="file"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

upload_same_button.gif

이제 텍스트필드만 잘 가리면 되겠다. 텍스트필드를 가리는 방법은 간단치는 않다. 일단 CSS로는 조정이 안되고 input의 size 속성을 이용한다.

  1.         <input style="position: absolute; width: 120px; height: 50px; font-size: 22px; " type="file" size="1"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

upload_small_textfield.gif

이제 최소화된 크기만큼 왼쪽으로 쉬프트를 시키자.

  1.         <input style="position: absolute; width: 120px; height: 50px; font-size: 22px; margin-left: -34px;" type="file" size="1"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

upload_shifted.gif

텍스트 필드 부분이 좀 남는데 이건 div를 그 자리에 엎어서 가린다.

  1.         <div style="position:absolute; width:60px; height: 50px; z-index: 3; margin-left: -60px; background-color: white;"></div>
            <input style="position: absolute; width: 120px; height: 50px; font-size: 22px; margin-left: -34px;" type="file" size="1"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

upload_opacity.gif

가리는 건 디자인에 따라 overflow: hidden을 이용할 수 있는 경우도 있고 다양한 방법들이 있을 것이다. 마지막으로 opacity를 0으로 만들어준다.

  1.         <div style="position:absolute; width:60px; height: 50px; z-index: 3; margin-left: -60px; background-color: white;"></div>
            <input style="position: absolute; width: 120px; height: 50px; font-size: 22px; margin-left: -34px; opacity: 0" type="file" size="1"/>
            <button style="height: 50px;">바뀐 업로드 버튼</button>

upload_complete.gif

여기에 cursor, hover 등을 이용해서 반응성을 좀 넣어주면 된다. IE에서도 거의 동일하게 동작한다.

iframe 이용#

opacity 를 이용한 방법은 사실 논리적인 문제점이 하나 있다. 업로드하는 파일명이 사용자에게 보이지 않는다는 것이다. 그래서 정상적으로 form을 submit하는 경우라면 이 방법을 적용하면 나쁜 설계가 된다. 버튼은 어떻게 바꾸더라도 텍스트필드에 파일명을 보여줘야 접근성을 확보할 수 있다. 그렇다면 이 방법을 써도 되는 건 언제일까? 버튼을 눌러서 파일을 선택하면 submit하지 않고 바로 업로드가 되며, 현재 페이지는 바뀌지 않는, Ajax스러운 업로드를 할 때는 자연스러운 UX다. 오히려 이 경우는 텍스트필드를 안 보여주는 게 더 자연스럽다. 그런데, 위의 방법을 그대로 적용하면 Ajax스러운 업로드가 어렵다. 스크립트로 동적인 iframe을 생성하고 그 안에 폼을 만들어서 submit까지 해야 한다. 그럴 바에야 처음부터 iframe으로 버튼을 넣을 수 있다면 어떨까.

 

버튼을 꾸미는 방법은 위와 같은데, 요는 텍스트필드를 div로 가리지 않고 iframe 안에 업로드버튼을 넣어서 가리는 것이다. 나머지는 똑같다. 그리고 iframe 안에 form을 넣고 input에 onchange="this.form.submit()" 등을 달아서 파일을 선택하면 바로 submit되게 하는 것이다. 그리고 그 결과를 parent에서 받아서 처리한다. 이렇게 하면 별도의 팝업이 뜨거나, 화면이 전환되지 않으면서 파일을 업로드하는 것이 가능하다. 사실은 위의 방법을 이 방법과 결합해서 써야 완전한 UX가 달성되는 것이다.

 

물론, 스크립트로 다 짜서 submit하는 것도 UX 상으로는 문제 없다. 다만 미리 넣어 놓는 방식이 디자인 맞추기가 편할 것이다.

swfupload#

사실 UX 상으로 현재까지 알려진 방식 중 최고의 방법은 위의 방법들이 아니라 플래시를 쓰는 것이다. swfupload가 괜찮은 듯 하다.

 

이 방식은 두 가지 장점이 있다. 하나는 업로드 진행율을 보여줄 수가 있다는 점. 큰 파일을 업로드할 때는 막강한 장점이다. 또 하나는, 한 번에 여러 파일을 업로드할 수 있다는 것. 자주 필요한 기능은 아니지만 역시 아주 막강한 장점이다. 플래시의 보급률이 95%에 달한다는 점을 감안하면 괜찮은 방법이다. 물론, 버튼도 마음대로 꾸밀 수 있다.


Comments


크리에이티브 커먼즈 라이선스
이 저작물은 크리에이티브 커먼즈 저작자표시 3.0 Unported 라이선스에 따라 이용할 수 있습니다.


Wiki at WikiNamu