본문으로 바로가기

select box CSS

category StyleSheet/CSS 2016. 9. 29. 08:35

CSS effect - Select Box

폼 필드 중에서 가장 커스텀(디자인)하기 까다로운 것 중의 하나가 셀렉트 박스입니다.

네이티브 select box 의 디자인상의 한계로 인해 CSS 로만으로는 해결하기 쉽지 않습니다.

이에 대한 대체방안을 살펴 보도록 하겠습니다.



네이티브 셀렉트 박스의 디자인상 한계로 인해 여러 플러그인에서는 select 박스의 구조를 div 와 ul 요소등으로 치환하여 사용합니다.


하지만 이 플러그인들은 구버전의 IE 지원률이 부족합니다. 


또한, div 와 ul 요소로 치환하는 방법을 사용한 플러그인은 모바일상에서 각각의 기기들이 네이티브로 지원하는 효과를 받을 수 없게 되고 대단히 유쾌하지 못한 사용자 경험을 체험하게 될 것입니다.



아래에서 플러그인의 사용없이 CSS 와 간단한 JS 를 이용한 select box 에 대해 알아봅니다.




Select CSS

국내환경(단계적 기능 향상 철학)에서 구버전 IE 로 인한 제약사항은 잠시 접어두고 우아한 기능 저하 철학을 추구하는 측면(모던 브라우저)에서는 select 박스의 외형 디자인의 변경이 보다 수월합니다.


select 박스의 기본구조는 아래와 같습니다.


<select>
<option selected>셀렉트박스</option>
<option>옵션1</option>
<option>옵션2</option>
<option>옵션3</option>
</select>


네이티브마다 지원하는 셀렉트 박스의 화살표 모양이 제각각이기 때문에 이를 하나로 통일하기 위해서 화살표 모양을 제거하도록 합니다.


새로운 화살표를 추가하는 스타일은 아래와 같습니다.


select {

-webkit-appearance: none; /* 네이티브 외형 감추기 */
-moz-appearance: none;
appearance: none;
background: url(이미지 경로) no-repeat 95% 50%; /* 화살표 모양의 이미지 */
}

/* IE 10, 11의 네이티브 화살표 숨기기 */
select::-ms-expand {
display: none;
}


이후 select 박스의 디자인을 변경하도록 합니다. 

디자인은 select 박스 형태만 변경 가능하고, option 쪽의 변경은 불가능하기 때문에 option 까지 변경을 원한다면 select 박스 관련 플러그인을 사용할 것을 권합니다.



select 박스의 스타일은 아래와 같습니다.


select {

width: 200px; /* 원하는 너비설정 */
padding: .8em .5em; /* 여백으로 높이 설정 */
font-family: inherit; /* 폰트 상속 */
background: url('이미지 경로') no-repeat 95% 50%; /* 네이티브 화살표를 커스텀 화살표로 대체 */
border: 1px solid #999;
border-radius: 0px; /* iOS 둥근모서리 제거 */
-webkit-appearance: none; /* 네이티브 외형 감추기 */
-moz-appearance: none;
appearance: none;
}



See the Pen select 박스 css 디자인 by jaeheekim (@jaehee) on CodePen.





label 을 이용한 select 박스 디자인

label 요소와 select 박스를 감싸고 있는 부모요소를 이용한 디자인 방법입니다.


기본 구조는 아래와 같이 작성하도록 합니다.


<div class="selectbox">
<label for="select">드라마</label>
<select id="select">
<option selected>드라마</option>
<option>육룡이 나뻣샤</option>
<option>그녀는 엿됐다</option>
<option>애인 없어요</option>
</select>

</div>


1. select 요소의 ID 값과 label 요소의 for 속성을 같은 값으로 설정합니다. (상호작용)

2. option 요소 중에 selected 속성을 가진 텍스트와 label 요소의 텍스트를 일치시키도록 합니다.



select 박스의 CSS 는 다음과 같습니다.


.selectbox {

position: relative;
width: 200px; /* 너비설정 */
border: 1px solid #999; /* 테두리 설정 */
z-index: 1;
}

/* 가상 선택자를 활용 화살표 대체 */
.selectbox:before {
content: "";
position: absolute;
top: 50%;
right: 15px;
width: 0;
height: 0;
margin-top: -1px;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #333;
}

.selectbox label {
position: absolute;
top: 1px; /* 위치정렬 */
left: 5px; /* 위치정렬 */
padding: .8em .5em; /* select의 여백 크기 만큼 */
color: #999;
z-index: -1; /* IE8에서 label이 위치한 곳이 클릭되지 않는 것 해결 */
}

.selectbox select {
width: 100%;
height: auto; /* 높이 초기화 */
line-height: normal; /* line-height 초기화 */
font-family: inherit; /* 폰트 상속 */
padding: .8em .5em; /* 여백과 높이 결정 */
border: 0;
opacity: 0; /* 숨기기 */
filter:alpha(opacity=0); /* IE8 숨기기 */
-webkit-appearance: none; /* 네이티브 외형 감추기 */
-moz-appearance: none;
appearance: none;
}


1. .selectbox 가 실제로 외형을 담당하는 부분이며 이 섹션의 CSS 를 원하는 스타일로 변경하면 됩니다.

2. .select:before 부분은 화살표을 나타내고 있지만 원하는 배경을 .selectbox 에 설정하고 가상 선택자를 제거해도 무방합니다.


셀렉트 박스의 option 을 선택할 시 변경된 옵션값을 label 에 반영하도록 합니다.


이는 해당 옵션이 가진 텍스트를 label 에 반영하여 실제 select 요소가 동작,변경되어 select 의 option 요소가 보이는 것처럼 기능을 구현하도록 합니다.


$(function() {
var selectTarget = $('.selectbox select');

selectTarget.change(function(){
var select_name = $(this).children('option:selected').text();
$(this).siblings('label').text(select_name);
});
});


좀 더 나은 사용자 접근성(웹 접근성)을 위해 select 박스에 focus 가 되었을 경우와 focus 를 잃어버렸을 경우(blur)를 처리하도록 하겠습니다.


select 박스에 focus 가 되면  나타나는 CSS 효과를 작성합니다.


.selectbox {

-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}

.selectbox.focus {
border-color: #66afe9;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
}


포커스 효과를 주기 위해서 동적으로 .focus 추가하도록 합니다.


// focus 가 되었을 때와 focus 를 잃었을 때
selectTarget.on({
'focus' : function () {
$(this).parent().addClass('focus');
},
'blur' : function () {
$(this).parent().removeClass('focus');
}
});


다음의 예제에서 완성된 코드를 보실 수 있습니다. 다만, focus 효과는 local 에서 테스트해보시길 바랍니다.


See the Pen 셀렉트 focus by jaeheekim (@jaehee) on CodePen.




IE7 Cross Browsing

IE7 에서는 select 요소에 padding 이 적용되지 않기 때문에 위의 코드는 IE8 까지 적용됩니다.

IE7 까지 지원하기 위해서는 padding 을 select 요소가 이닌 부모요소에 적용하는 방식으로 바꿔보길 바랍니다.

다만, 이때 select 요소의 크기가 변경되지 않아 select 박스를 클릭할 수 있는 영역이 보이는 박스 전체의 크기보다 작아집니다.

또 다른 방법으로는 처음부터 padding 을 이용하지 않고 부모요소, label, select 요소에 같은 크기의 height 와 line-height 값을 지정해주는 것입니다.


IE7 에서는 :before(가상요소)를 지원하지 않기 때문에 배경이미지를 이용하여 화살표를 표시해야 합니다.

가상요소를 이용하려면 IE7 fallback 을 참고바랍니다.


See the Pen select 박스 IE7 by jaeheekim (@jaehee) on CodePen.


참고 링크

셀렉트 박스 플러그인(IE7 지원), 모바일상에서는 네이티브 지원 효과는 받을 수 없음

jQuery Selectbox plugin



Jaehee's WebClub


'StyleSheet > CSS' 카테고리의 다른 글

vertical align & center box(수직 중앙 정렬)  (0) 2016.09.29
Simple dropdown menu 2depth  (0) 2016.09.29
select box CSS  (4) 2016.09.29
CSS Button Transitions  (0) 2016.09.29
Close button Animation  (0) 2016.09.29
CSS3 Custom Checkbox, Radio  (0) 2016.09.29

댓글을 달아 주세요

  1. 이경진 2016.05.13 17:50

    후아.. 정말 고생하다가 겨우 적용하여 성공했습니다!!
    z-index:1, z-index:-1이 중요했군요.
    정말 감사합니다.

  2. 흰별 2017.01.17 15:27

    첫번째 opiton을 선택했을때 label로 값이 출력이 안되는데요.. 이건 어떻게 해결해야되는지요? ㅜㅜ

    • BlogIcon 재희 jaiyah 신고">2017.02.09 17:37 신고

      답변이 늦었네요;; 레이블에 값을 나타내기 위해서 스크립트를 이용해야 하는데요. 맨마지막 예제코드에 소스가 적용되어 있습니다. 참고가 되셨길 바래요~