Input range 커스텀 - Input range keoseuteom

++ 추가 사항

<input type="range">태그로 제작한 부분이 모바일에서 터치 이동이 안되는 이슈가 있었습니다.

그래서 어쩔수 없이 <div> 태그를 사용하여 커스텀하는 형식으로 작업했습니다.

기록상 글을 작성합니다. 

글에 IE11이라고 작성된 모든 부분을 Edge로 수정합니다.

++

요구조건

<input type="range"> 태그를 사용, CSS를 통해 아래와 같이 제작해주세요.

아래 이미지는 캡쳐본으로 저 형태로 제작하는 것이 최종 요구조건 이었습니다.

Input range 커스텀 - Input range keoseuteom
요구 조건

기존에 <div>태그를 사용해서 작업했던 결과물을 분석합니다.

부모 태그에 너비를 100% 준 다음 왼쪽(진행 후)과 오른쪽(진행 전)의 영역의 값을 JS로 삽입하는 방식이었습니다.

Input range 커스텀 - Input range keoseuteom
html

이렇게 된 코드를 <input type="range"> 방식으로 변경해보도록 하겠습니다.

지원 브라우저

들어가기전에 생각해야하는 부분은 <input type="range">는 IE10부터 지원합니다.

회사 정책에 IE가 포함되어 있지 않았기 때문에 진행할 수 있었습니다.

만약 하위브라우저를 지원해야한다면 type="range"를 다시 생각해보셔야합니다.

Input range 커스텀 - Input range keoseuteom
ie10 이상 지원, can i use 출처

벤더 프리픽스(Vendor Prefix)

-webkit- : 크롬

-moz- : 파이어폭스

-ms- : IE

브라우저 기본 스타일

Chrome

Input range 커스텀 - Input range keoseuteom
Chrome 기본 스타일

Edge

Input range 커스텀 - Input range keoseuteom
Edge 기본 스타일

Firefox

Input range 커스텀 - Input range keoseuteom
Firefox 기본 스타일

Chrome 브라우저같은 경우는 개발자도구 콘솔창에서 기본 스타일 확인이 가능합니다.

Input range 커스텀 - Input range keoseuteom
user agent style

CSS 코드 수정해보기

기본 스타일 리셋시키기

Chrome(-webkit-)

input[type=range] { width:100%; -webkit-appearance: none; background: transparent; }

appearance는 사용자 운영체제 테마에 기반한 플랫폼 고유 스타일

background:transparent는 부모 배경 색상와 동일하게 하는 속성, 바에 영향을 받습니다.

스타일 적용 후

기본 모양에 있던 바가 감춰진 것이 확인됩니다.

Input range 커스텀 - Input range keoseuteom
appearance, background

이어서 마우스로 포인터를 이동하며 값을 조정할 때 (focus될 때) 보여지는 파란 라인(outline)값을 제거하도록 하겠습니다.

input[type=range]:focus { outline: none; }


스타일 적용 후

Input range 커스텀 - Input range keoseuteom
outline:none

이건 css 포럼에 나와있길래 추가했는데, 차이를 잘 모르겠습니다.

input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; }

Edgd(-ms-)

ie는 개발자도구에서 기본 스타일을 확인하는 방법을 모르겠어서 눈으로 확인하면서 작업했습니다.

input[type=range]::-ms-track { width: 100%; cursor: pointer; background: transparent; border-color: transparent; color: transparent; }

width는 너비값이 지정되었고, cursor는 마우스를 바 위에 올릴 경우(hover) 커서가 손가락으로 바뀌는 것을 제어합니다.

스타일 적용 후

Input range 커스텀 - Input range keoseuteom
input[type=range]::-ms-track { background: transparent; border-color: transparent; color: transparent; }

스타일 적용 후

Input range 커스텀 - Input range keoseuteom
background
Input range 커스텀 - Input range keoseuteom
background + color
Input range 커스텀 - Input range keoseuteom
background+color+border-color

마우스를 바 위에 올릴 경우(hover) 포인터 색상이 바뀌는게 확인됩니다.

Input range 커스텀 - Input range keoseuteom
hover 시

포인터를 잡고 왼쪽에서 오른쪽으로 드래그할 경우 아래와 같이 파란색 배경색상이 칠해지게 됩니다.

Input range 커스텀 - Input range keoseuteom

포인터 스타일

Chrome(-webkit-)

-webkit-appearance를 통해 user agent 값을 (기본테마 속성) none해준 다음에 background 흰색으로 적용하였습니다.

그리고 커서 모양을(cursor) 포인터로 적용하여 마우스 올렸을 때 손가락 모양으로 커서가 바뀌게 해줍니다.

input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; background: #ffffff; cursor: pointer; border: 1px solid #000000; height: 36px; width: 16px; margin-top: -14px; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; border-radius: 3px; }

이렇게 넣었는데, background 속성이 변하는 부분을 찾지는 못했습니다. 

border 값을 추가하니까 포인터의 크기로 적용되었습니다.

width, heigth을 수정해도 커지지 않던 포인터가 border:30px을 줬더니 아래와 같이 커졌습니다.

스타일 적용 후

Input range 커스텀 - Input range keoseuteom
border-width:30px;

border-radius만 단독으로 사용했을때 변하는 부분을 못찾다가 border-radius + box-shadow 를 같이 적용하니

아래와 같이 그림자에 border-radius가 적용되는 것을 확인되었습니다.

스타일 적용 후

Input range 커스텀 - Input range keoseuteom
그림자에 border-radius가 적용됨

margin-top:-14px를 적용한 부분은 포인터의 위치를 -14px만큼 올려주었습니다.

스타일 적용 전과 후 차이

Input range 커스텀 - Input range keoseuteom
적용 전
Input range 커스텀 - Input range keoseuteom
적용 후 

단독으로 margin-top:-14px 사용했을 때와 다르게 user agent를 reset하는 소스들과 같이 사용 했을때에는

margin-top:-14px를 적용하면 전체 영역이 올라갑니다.

Input range 커스텀 - Input range keoseuteom

Firefox(-moz-)

input[type=range]::-moz-range-thumb { box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; border: 1px solid #000000; height: 36px; width: 16px; border-radius: 3px; background: #ffffff; cursor: pointer; }

스타일 적용 전과 후

Input range 커스텀 - Input range keoseuteom
기본
Input range 커스텀 - Input range keoseuteom
box-shadow

신기한 부분이었는데, border만 적용해도 border-radius가 적용된 모습입니다.

덤으로 바가 사라졌습니다.

Input range 커스텀 - Input range keoseuteom
border
Input range 커스텀 - Input range keoseuteom
border+box-shadow

width, height를 적용했을땐 변하지 않던 포인터의 크기가 border 나 background 를 적용하면 변하였습니다.

Input range 커스텀 - Input range keoseuteom
border or background

border-radius를 border나 background-color랑 같이 사용했을 때 변하는 모습을 아래와 같습니다.

border-radius는 기본 값이 컸었는지, 오히려 숫자를 작게 했더니 각졌습니다.

Input range 커스텀 - Input range keoseuteom
3px
Input range 커스텀 - Input range keoseuteom
1px
Input range 커스텀 - Input range keoseuteom
background-color
Input range 커스텀 - Input range keoseuteom
background-color

여기까지 봤을때, 여러 스타일을 같이 사용해야 적용되는 것들이 존재했습니다.

width, height를 적용할 때 border랑 background 같이 적용하면 되는 줄 알았는데, (한 세트인지 알았습니다.)

나중에 쓰다보니까 background만 적용하려 할때에는 border가 없어도 적용되는 것을 확인했습니다.

width, height를 적용할 때 border-radius를 적용할 경우 border나 background는 없이도 적용되는 부분도 있었습니다.

근데, 브라우저마다 다르게 표현되는 부분들이 있어서 이 정도 학습으로는 아리송합니다..

user agent를 리셋코드 + 추가 스타일을 적용 후

Input range 커스텀 - Input range keoseuteom
user agent를 리셋하는 것과 함께 스타일을 적용한 후

Edge(-ms-)

nput[type=range]::-ms-thumb { box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; border: 1px solid #000000; height: 36px; width: 16px; border-radius: 3px; background: #ffffff; cursor: pointer; }

스타일 적용 전과 후

기본 스타일

Input range 커스텀 - Input range keoseuteom
user agent 기본 브라우저 스타일

border를 적용했습니다. border값이 적용됩니다.

Input range 커스텀 - Input range keoseuteom
border 값이 적용된다.

width:50px; height:50px;를 적용했을때 width는 무시되나 height 값은 적용됩니다.

Input range 커스텀 - Input range keoseuteom
height만 적용된 것이 확인

box-shadow

Input range 커스텀 - Input range keoseuteom
적용 전
Input range 커스텀 - Input range keoseuteom
적용 후

background:#fff

Input range 커스텀 - Input range keoseuteom
background:#fff

user agent 리셋과 함께 위 예제를 사용했을때

Input range 커스텀 - Input range keoseuteom

바 스타일

Chrome(-webkit-)

:focus를 사용할 수 있습니다.

input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 8.4px; cursor: pointer; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; background: #3071a9; border-radius: 1.3px; border: 0.2px solid #010101; } input[type=range]:focus::-webkit-slider-runnable-track { background: #367ebd; }

스타일 적용 후

width:100%;, height:8.4px;

부모 태그에 width값만큼 100%로 적용될 줄 알았는데, 아무런 크기 변화가 없습니다.

Input range 커스텀 - Input range keoseuteom
width 100%

다만 포이터가 쳐지는 것을 확인할 수 있었습니다.

영역을 보면 확인이 됩니다.

Input range 커스텀 - Input range keoseuteom
포인터가 쳐졌다

보이는 바의 크기가 작아서 height가 적용이 안되나?0 싶어서 테스트를 해보았는데, height 값이 영역에 적용되어 있었습니다.

background를 추가하여 확인해보겠습니다.

Input range 커스텀 - Input range keoseuteom
background:red;

다만 height:8.4px를 주었는데 8.39px로 되어있네요.

Input range 커스텀 - Input range keoseuteom

background-shadow

Input range 커스텀 - Input range keoseuteom
background-shadow

border-radius

Input range 커스텀 - Input range keoseuteom
border-radius

border

Input range 커스텀 - Input range keoseuteom

:focus 전과 후

Input range 커스텀 - Input range keoseuteom
Input range 커스텀 - Input range keoseuteom

최종코드

Input range 커스텀 - Input range keoseuteom
최종코드

Firefox(-moz)-

input[type=range]::-moz-range-track { width: 100%; height: 8.4px; cursor: pointer; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; background: #3071a9; border-radius: 1.3px; border: 0.2px solid #010101; }

스타일 적용 후

width, height를 적용했을때, 단독으로는 안되서 background를 같이 적용해야했습니다.

Input range 커스텀 - Input range keoseuteom
width, height, background

그 후에 width 값을 10px로 변경해보니 아래와 같이 이상한 모습이 되었습니다.

이래서 100%를 적용해야하는것인가? 생각했습니다.

Input range 커스텀 - Input range keoseuteom
width:10px 결과

height : 바의 높이 값입니다.

Input range 커스텀 - Input range keoseuteom
height:1px
Input range 커스텀 - Input range keoseuteom
height:8.4px

뭔가.... 8.4px보다 적용된 게 커보여서, 비교해봤는데, 딱 맞습니다. 머쓱

Input range 커스텀 - Input range keoseuteom
빨간색은 포토샵에서 만들어서 붙였습니다 ㅎ;

box-shadow

Input range 커스텀 - Input range keoseuteom
box-shadow

border + border-radius

border-radius는 border값과 함께 적용해야합니다.

Input range 커스텀 - Input range keoseuteom
border + border-radius

Edge(-ms-)

input[type=range]::-ms-track { width: 100%; height: 8.4px; cursor: pointer; background: transparent; border-color: transparent; border-width: 16px 0; color: transparent; }

스타일 적용 후 

width, height를적용 했을 때 width 확인은 어려웠고 height는 바의 높이 값이 달라집니다.

Input range 커스텀 - Input range keoseuteom
1px
Input range 커스텀 - Input range keoseuteom
8.4px

background:transparent

Input range 커스텀 - Input range keoseuteom
background:transparent

border-color:transparent

Input range 커스텀 - Input range keoseuteom
border-color:transparent

color:transparent;

Input range 커스텀 - Input range keoseuteom
color:transparent;

border-width:16px 0;

Input range 커스텀 - Input range keoseuteom
border-width:16px 0;

위로 16px 너비의 border를 적용하는데 border-color:transparent와 같이 사용하기 때문에

최종적으로는 아래와 같이 보입니다.

Input range 커스텀 - Input range keoseuteom
border-width:16px 0; / border-color:transparent

스타일 추가

여태한 결과에 스타일을 추가해보도록 하겠습니다.

(Edge같은 경우 기본 기능제공을 합니다. https://developer.mozilla.org/en-US/docs/Web/CSS/::-ms-fill-lower

진행 된 부분과 진행되어야하는 부분을 구분할 때 사용합니다.

input[type=range]::-ms-fill-lower { background: #2a6495; border: 0.2px solid #010101; border-radius: 2.6px; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; }

스타일 적용 후 

background 마우스로 왼쪽에서 오른쪽으로 드래그하면 지나온 자리에 바 배경 색상이 적용됩니다.

Input range 커스텀 - Input range keoseuteom
background

border

Input range 커스텀 - Input range keoseuteom
border

border-radius

Input range 커스텀 - Input range keoseuteom
border-radius

fill-lower에 대해 좀 더 확인 할 수 있을 듯해서 잠시 -ms-track의 background:transparent, border-color:transparent를 지운 상태입니다. 드래그한 포인터의 값보다 작은 값(진행된 부분)에만 파란색 배경이 적용되고 있습니다.

box-shadow

Input range 커스텀 - Input range keoseuteom
box-shadow

지나온 영역말고 앞으로 가야할 영역에 대한 스타일도 적용할 수 있는지 찾아봤는데, 있습니다.

지나온 부분은 fill-lower이고 지나가야할 영역은 fill-upper입니다.

input[type=range]::-ms-fill-upper { background: #3071a9; border: 0.2px solid #010101; border-radius: 2.6px; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; }

스타일 적용 후

fill-lower와 똑같은 값을 적용한 후 구분이 될 수 있도록 background 색상을 다르게 적용해줍니다.

Input range 커스텀 - Input range keoseuteom
b ackground

그리고 포커스 이벤트를 아래와 같이 적용합니다.

input[type=range]:focus::-ms-fill-lower { background: red; } input[type=range]:focus::-ms-fill-upper { background: pink; }

스타일 적용 후 

Input range 커스텀 - Input range keoseuteom
focus

IE를 제외한 다른 브라우저는 lower, upper를 제공하고 있지 않습니다.

그래서 어떻게 할까 하다가 구글링한 정보입니다.

Firefox는 -moz-range-progress, -moz-range-track 셀렉터가 업데이트되었다고 합니다만....

mdn 문서를 보면 비표준이라고 뜨므로 업무에 사용하기에는 무리가 있어보입니다.

Input range 커스텀 - Input range keoseuteom
mdn 출처

그래서 더 찾아보다가 코드펜(codepen.io)에서 background-shadow를 사용해서 lower, upper 처럼 스타일을 지정한 사람을 찾았습니다.

(코드 출처  https://codepen.io/noahblon/pen/OyajvN)

저는 IE 배제하여 작업하여서 -ms-는 사용하지 않았습니다.

HTML

<input type="range" value="0">

CSS

input[type=range] { -webkit-appearance: none; overflow: hidden; width: 100%; height: 10px; background: transparent; cursor: pointer; background: #e5e4e3; border-radius: 0; /* iOS */ } input[type=range]:focus { outline: none; } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 10px; height: 10px; background: #fff; box-shadow: -100vw 0 0 100vw dodgerblue; border: 0.1px solid dodgerblue; cursor: pointer; }

스타일 적용 후

Input range 커스텀 - Input range keoseuteom

See the Pen PMpmjp by leeyoonseo (@okayoon) on CodePen.

그런데, 문제가 생겼습니다.

제 처음의 요구조건을 보면 포인터가 바의 크기보다 커야했습니다.

이 방법은 box-shadow로 크게 색칠한 후 overflow:hidden해서 영역을 감추는 방식입니다. 

그렇다보니 포인터가 바의 크기보다 커질수가 없습니다.

Input range 커스텀 - Input range keoseuteom
overflow:hidden을 제거한 모습
Input range 커스텀 - Input range keoseuteom
overflow:hidden

요구조건이 불가능했기 때문에 다른 방식으로 작업해봤습니다.

HTML

<input type="range" value="0">

CSS

input[type=range] { -webkit-appearance: none; width: 100%; height: 6px; background: #d5d4d3; cursor: pointer; border-radius: 0; /* iOS */ transition: background 450ms ease-in; } input[type=range]:focus { outline: none; } input[type=range]::-webkit-slider-thumb{ -webkit-appearance: none; width: 12px; height: 12px; background: #fff; border: 1px solid dodgerblue; border-radius:50%; cursor: pointer; } input[type=range]::-moz-range-thumb{ -webkit-appearance: none; width:10px; height:10px; background: #fff; border: 1px solid dodgerblue; border-radius:50%; cursor: pointer; }

JS

$('input[type=range]').on('input', function(){ var val = $(this).val(); $(this).css('background', 'linear-gradient(to right, dodgerblue 0%, dodgerblue '+ val +'%, #d5d4d3 ' + val + '%, #d5d4d3 100%)'); });

range의 value 값이 증가할 때 (1~100%) 그라디언트로 값을 삽입하는 방식입니다.

See the Pen jquery_range_css by leeyoonseo (@okayoon) on CodePen.

결론으로는..

크로스브라우징 이슈로 <input type="range">에서 <div> 태그로 변경하였습니다만,

CSS에 대해 많은 공부가 된 시간이었습니다.


소스 출처
https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/ 
참고
mdn, can i use, codepen.io 등