본문으로 바로가기

계속해서 이어지는 폼관련 요소들에 대한 이야기입니다. 폼의 각 필드들을 디자인하면서 고민했던 점들과 대안책들을 순차적으로 다루어 봅니다.

label 요소와 placeholder 속성 구분

label 요소는 for 속성과 연결된 필드들(input, select, textarea, checkbox, radio)를 가르키는 요소이다. 즉 입력필드들의 제목과 같은 역할을 하며, 때로는 이 요소를 이용해서 상호작용을 대신할 수 있다.

placeholder 속성은 텍스트 필드에 힌트를 제공하는 예제와 같은 역할을 한다. 이를 label 요소를 대체할 목적으로 작성하는 것은 원칙적으론 잘못된 것이다. 게다가 placeholder 속성은 IE9 이하에서는 지원하지 않기때문에 폴리필(대체방안)을 필요로 하게 된다.

모바일기기의 내장브라우저들중에서는 텍스트 필드의 높이를 변경하면 placeholder가 세로정렬되지 못하는 버그도 존재한다.

텍스트 필드 디자인시 유의점

브라우저 호환을 염두에 둔다면(IE8) 필드 디자인시에 height 속성이나 line-height 속성의 사용을 자제해야 한다. IE8에서는 텍스트 필드요소에 height 값이 적용되면 글자 세로 정렬에 문제가 있어 지정한 height 값보다 약 3~4px 정도 축소한 line-height 값을 지정해야 글자의 세로 가운데 정렬이 되기 때문이다.

height를 이용한 디자인시

되도록 padding 속성을 사용하면서, 글자의 크기에 따라 유동적으로 여백이 확대, 축소 될 수 있도록 em 단위를 사용하는 것을 추천한다.

input[type="text"],
input[type="password"] {
  height: auto;  /* 높이 초기화 */
  line-height: normal;  /* line-height 초기화 */
  padding: .8em .5em;  /* 여백 설정 */
}

label 요소의 포지셔닝

label 요소를 placeholder 처럼 이용하는 방법으로, placeholder 속성은 사용하지 않는다는 전제하에 label 요소를 placeholder가 위치할 자리에 이동시키게 된다.

기본 구조는 아래와 같다.

<div class="textbox">
  <label for="ex_input">아이디</label>
  <input type="text" id="ex_input">
</div>
  • label 요소와 input 요소를 작성
  • 이들을 감싸는 부모 요소를 설정
  • label 요소와 input 요소가 상호작용이 가능하도록(label 요소를 클릭해도 input 요소에 포커스가 되도록) label 요소의 for 속성과 input 요소의 id 속성의 값을 일치시킨다.

CSS 설정은 아래와 같다.

.textbox {position: relative;}

.textbox label {
  position: absolute;
  top: 1px;  /* input 요소의 border-top 설정값 만큼 */
  left: 1px;  /* input 요소의 border-left 설정값 만큼 */
  padding: .8em .5em;  /* input 요소의 padding 값 만큼 */
  color: #999;
  cursor: text;
}

.textbox input[type="text"],
.textbox input[type="password"] {
  width: 100%;  /* 원하는 너비 설정 */ 
  height: auto;  /* 높이값 초기화 */
  line-height : normal;  /* line-height 초기화 */
  padding: .8em .5em; /* 원하는 여백 설정, 상하단 여백으로 높이를 조절 */
  font-family: inherit;  /* 폰트 상속 */
  border: 1px solid #999;
  border-radius: 0;  /* iSO 둥근모서리 제거 */
  outline-style: none;  /* 포커스시 발생하는 효과 제거를 원한다면 */
  -webkit-appearance: none;  /* 브라우저별 기본 스타일링 제거 */
  -moz-appearance: none;
  appearance: none;
}

정확히 일치하는지 input 필드에 직접 값을 입력해 확인해 보도록 하자.

모바일에서도 label 요소의 위치가 정확한지 확인하라. 경우에 따라서는 label 요소에 vertical-align: top을 필요로 할수도 있다.

포커스시 label 숨기기

label 요소와 입력값의 위치가 적당하다면 label 요소를 숨기기 위해 자바스크립트를 사용해야 한다. 필자는 편의를 위해 jQuery를 이용했다.

$(document).ready(function() {
  var placeholderTarget = $('.textbox input[type="text"], .textbox input[type="password"]');
  
  //포커스시
  placeholderTarget.on('focus', function(){
    $(this).siblings('label').fadeOut('fast');
  });

  //포커스아웃시
  placeholderTarget.on('focusout', function(){
    if($(this).val() == ''){
      $(this).siblings('label').fadeIn('fast');
    }
  });
});

실제 동작하는 예를 보도록하자

See the Pen input field design by Douglas Ham (@uzugoer) on CodePen.

일반적인 경우, 위의 코드만으로도 잘 작동하지만, 경우에 따라서는 추가적인 코드를 필요로 할 것이다.

value 값이 이미 설정되어 있는 경우

가령, 회원가입과 정보수정이 한 페이지에서 일어나는 경우가 있을 수 있다. 정보수정 폼의 경우 회원가입시 입력한 값들을 기본값으로 value에 가지고 나타나게 되며, 위에서 작성한 코드는 focus 및 focusout 이벤트를 기준으로 label 요소가 숨겨지기 때문에 페이지 로딩시에 value 값의 유무를 판단해 처리하는 코드가 추가로 필요하게 된다.

placeholderTarget.each(function(){
  if(!($(this).val() == '')){
    $(this).siblings('label').css('display','none');
  }
});
값을 붙여 넣는 경우

가령, input 필드를 감지해서 미리 입력해둔 값이 불러와지거나 이를 붙여넣기 하는 애플리케이션들을 사용하는 경우를 예를 들 수있다. 모든 애플리케이션에서 올바르게 작동할지는 의문이나, 대안책으로 input 이벤트를 사용하는 것을 추천한다. 구형 IE에서 버그 및 미지원의 문제로 플러그인을 사용하여 해결해야 한다.

input 이벤트 감지 크로스브라우징에서 이와 관련된 내용을 다루고 있으며, 해당 플러그인을 사용한다면 아래와 같은 코드를 추가할 수 있게된다.

placeholderTarget.on('textchange', function(){
  $(this).siblings('label').fadeOut('fast');
});
기존의 focus 이벤트는 포커스가 맞춰지는 순간 label이 사라지기 때문에 해당 필드가 어떤 필드였는지 재차확인하려면 입력된 값을 삭제하고 포커스를 아웃시켜야하는 불편함이 있다. 하지만 textchange 합성 이벤트를 사용한다면 실제 값이 입력되기 전까진 사라지지 않기에 필자같이 기억력이 쇠퇴한 사람들에겐 좋은 사용자경험을 선사할 수 있다.
값이 프로그래밍 적으로 입력될때

가령, 주소검색이 포함된 페이지와 같이, 기타 프로그램의 영향으로 값이 입력되게 된다면 해당 이벤트를 잡아내는 것에 한계가 발생한다. 해당 프로그램이 입력필드에 값을 입력시키는 순간에 개입해서 label요소를 숨기게 수정할 수 있어야 한다. 왠만한 프로그램들이라면 해당 프로그램이 완료됬을때를 기준으로 어떤 행동을 추가할 수 있는 콜백 함수를 지원해주니 이를 잘 살펴보아야 한다.

new daum.Postcode({
    oncomplete: function(data) {
        //숨길 코드 작성
    }
});

패스워드 필드의 디자인

패스워드 입력 필드들 또한 위에서 설명한 텍스트 필드와 함께 사용되어진다. 만약에 placeholder 속성을 사용하는 입장이였다면 구형 브라우저들의 크로스브라우징을 위해 플러그인을 사용했을텐데, fake password를 사용하는 플러그인들로 인해 폼 검증이 실패하는 경우가 있었을지도 모르겠다. 그렇다면 차라리 위에서 설명한 기법이 해결책이 될 수 있다.

textarea 필드의 디자인

textarea 요소 또한 위에서 설명한 것과 크게 다를바가 없다. 다만 textarea 요소는 원하는 크기로 설정하기 위해 height 값을 사용해도 된다는 것만 다르다.