++ 추가 사항
<input type="range">태그로 제작한 부분이 모바일에서 터치 이동이 안되는 이슈가 있었습니다.
그래서 어쩔수 없이 <div> 태그를 사용하여 커스텀하는 형식으로 작업했습니다.
기록상 글을 작성합니다.
글에 IE11이라고 작성된 모든 부분을 Edge로 수정합니다.
++
원본 코드 확인 바로가기
요구조건
<input type="range"> 태그를 사용, CSS를 통해 아래와 같이 제작 해주세요.
아래 이미지는 캡쳐본으로 저 형태로 제작하는 것이 최종 요구조건 이었습니다.
요구 조건
기존에 <div>태그를 사용해서 작업했던 결과물을 분석합니다.
부모 태그에 너비를 100% 준 다음 왼쪽(진행 후)과 오른쪽(진행 전)의 영역의 값을 JS로 삽입하는 방식이었습니다.
html
이렇게 된 코드를 <input type="range"> 방식으로 변경 해보도록 하겠습니다.
지원 브라우저
들어가기전에 생각해야하는 부분은 <input type="range">는 IE10부터 지원 합니다.
회사 정책에 IE가 포함되어 있지 않았기 때문에 진행할 수 있었습니다.
만약 하위브라우저를 지원해야한다면 type="range"를 다시 생각 해보셔야합니다.
ie10 이상 지원, can i use 출처
벤더 프리픽스(Vendor Prefix)
-webkit- : 크롬
-moz- : 파이어폭스
-ms- : IE
브라우저 기본 스타일
Chrome
Chrome 기본 스타일
Edge
Edge 기본 스타일
Firefox
Firefox 기본 스타일
Chrome 브라우저같은 경우는 개발자도구 콘솔창에서 기본 스타일 확인이 가능 합니다.
user agent style
CSS 코드 수정해보기
기본 스타일 리셋시키기
Chrome(-webkit-)
input[type=range] {
width:100%;
-webkit-appearance: none;
background: transparent;
}
appearance는 사용자 운영체제 테마에 기반한 플랫폼 고유 스타일
background:transparent는 부모 배경 색상와 동일하게 하는 속성, 바에 영향을 받습니다.
스타일 적용 후
기본 모양에 있던 바가 감춰진 것이 확인됩니다.
appearance, background
이어서 마우스로 포인터를 이동하며 값을 조정할 때 (focus될 때) 보여지는 파란 라인(outline)값을 제거하도록 하겠습니다.
input[type=range]:focus {
outline: none;
}
스타일 적용 후
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[type=range]::-ms-track {
background: transparent;
border-color: transparent;
color: transparent;
}
스타일 적용 후
background
background + color
background+color+border-color
마우스를 바 위에 올릴 경우(hover) 포인터 색상이 바뀌는게 확인됩니다.
hover 시
포인터를 잡고 왼쪽에서 오른쪽으로 드래그할 경우 아래와 같이 파란색 배경색상이 칠해지게 됩니다.
포인터 스타일
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을 줬더니 아래와 같이 커졌습니다.
스타일 적용 후
border-width:30px;
border-radius만 단독으로 사용했을때 변하는 부분을 못찾다가 border-radius + box-shadow 를 같이 적용하니
아래와 같이 그림자에 border-radius가 적용되는 것을 확인되었습니다.
스타일 적용 후
그림자에 border-radius가 적용됨
margin-top:-14px를 적용한 부분은 포인터의 위치를 -14px만큼 올려주었습니다.
스타일 적용 전과 후 차이
적용 전
적용 후
단독으로 margin-top:-14px 사용했을 때와 다르게 user agent를 reset하는 소스들과 같이 사용 했을때에는
margin-top:-14px를 적용하면 전체 영역이 올라갑니다.
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;
}
스타일 적용 전과 후
기본
box-shadow
신기한 부분이었는데, border만 적용해도 border-radius가 적용된 모습입니다.
덤으로 바가 사라졌습니다.
border
border+box-shadow
width, height를 적용했을땐 변하지 않던 포인터의 크기가 border 나 background 를 적용하면 변하였습니다.
border or background
border-radius를 border나 background-color랑 같이 사용했을 때 변하는 모습을 아래 와 같습니다.
border-radius는 기본 값이 컸었는지, 오히려 숫자를 작게 했더니 각졌습니다.
3px
1px
background-color
background-color
여기까지 봤을때, 여러 스타일을 같이 사용해야 적용되는 것들이 존재 했습니다.
width, height를 적용할 때 border랑 background 같이 적용하면 되는 줄 알았는데, (한 세트인지 알았습니다.)
나중에 쓰다보니까 background만 적용하려 할때에는 border가 없어도 적용되는 것을 확인했습니다.
width, height를 적용할 때 border-radius를 적용할 경우 border나 background는 없이도 적용되는 부분도 있었습니다.
근데, 브라우저마다 다르게 표현되는 부분들이 있어서 이 정도 학습으로는 아리송합니다..
user agent를 리셋코드 + 추가 스타일을 적용 후
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;
}
스타일 적용 전과 후
기본 스타일
user agent 기본 브라우저 스타일
border를 적용했습니다. border값이 적용됩니다.
border 값이 적용된다.
width:50px; height:50px;를 적용했을때 width는 무시되나 height 값은 적용됩니다.
height만 적용된 것이 확인
box-shadow
적용 전
적용 후
background:#fff
background:#fff
user agent 리셋과 함께 위 예제를 사용했을때
바 스타일
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%로 적용될 줄 알았는데, 아무런 크기 변화가 없습니다.
width 100%
다만 포이터가 쳐지는 것을 확인할 수 있었습니다.
영역을 보면 확인이 됩니다.
포인터가 쳐졌다
보이는 바의 크기가 작아서 height가 적용이 안되나?0 싶어서 테스트를 해보았는데, height 값이 영역에 적용되어 있었습니다.
background 를 추가하여 확인해보겠습니다.
background:red;
다만 height:8.4px를 주었는데 8.39px로 되어있네요.
background-shadow
background-shadow
border-radius
border-radius
border
:focus 전과 후
전
후
최종코드
최종코드
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를 같이 적용해야했습니다.
width, height, background
그 후에 width 값을 10px 로 변경해보니 아래와 같이 이상한 모습이 되었습니다.
이래서 100%를 적용해야하는것인가? 생각했습니다.
width:10px 결과
height : 바의 높이 값입니다.
height:1px
height:8.4px
뭔가.... 8.4px보다 적용된 게 커보여서, 비교해봤는데, 딱 맞습니다. 머쓱
빨간색은 포토샵에서 만들어서 붙였습니다 ㅎ;
box-shadow
box-shadow
border + border-radius
border-radius는 border값과 함께 적용해야합니다.
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는 바의 높이 값이 달라집니다.
1px
8.4px
background:transparent
background:transparent
border-color:transparent
border-color:transparent
color:transparent;
color:transparent;
border-width:16px 0;
border-width:16px 0;
위로 16px 너비의 border를 적용하는데 border-color:transparent와 같이 사용하기 때문에
최종적으로는 아래와 같이 보입니다.
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 마우스로 왼쪽에서 오른쪽으로 드래그하면 지나온 자리에 바 배경 색상이 적용됩니다.
background
border
border
border-radius
border-radius
fill-lower에 대해 좀 더 확인 할 수 있을 듯해서 잠시 -ms-track의 background:transparent, border-color:transparent를 지운 상태입니다. 드래그한 포인터의 값보다 작은 값(진행된 부분)에만 파란색 배경이 적용되고 있습니다.
box-shadow
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 색상을 다르게 적용해줍니다.
b ackground
그리고 포커스 이벤트 를 아래와 같이 적용합니다.
input[type=range]:focus::-ms-fill-lower {
background: red;
}
input[type=range]:focus::-ms-fill-upper {
background: pink;
}
스타일 적용 후
focus
IE를 제외한 다른 브라우저는 lower, upper를 제공하고 있지 않습니다.
그래서 어떻게 할까 하다가 구글링한 정보입니다.
Firefox는 -moz-range-progress, -moz-range-track 셀렉터가 업데이트되었다고 합니다만....
mdn 문서 를 보면 비표준 이라고 뜨므로 업무에 사용하기에는 무리가 있어보입니다.
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;
}
스타일 적용 후
See the Pen PMpmjp by leeyoonseo (@okayoon ) on CodePen .
그런데, 문제가 생겼습니다.
제 처음의 요구조건을 보면 포인터가 바의 크기보다 커야했습니다.
이 방법은 box-shadow로 크게 색칠한 후 overflow:hidden해서 영역을 감추는 방식입니다.
그렇다보니 포인터가 바의 크기보다 커질수가 없습니다.
overflow:hidden을 제거한 모습
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 등