++ 추가 사항
<input type="range">태그로 제작한 부분이 모바일에서 터치 이동이 안되는 이슈가 있었습니다.
그래서 어쩔수 없이 <div> 태그를 사용하여 커스텀하는 형식으로 작업했습니다.
기록상 글을 작성합니다.
글에 IE11이라고 작성된 모든 부분을 Edge로 수정합니다.
++
요구조건
<input type="range"> 태그를 사용, CSS를 통해 아래와 같이 제작해주세요.
아래 이미지는 캡쳐본으로 저 형태로 제작하는 것이 최종 요구조건 이었습니다.
기존에 <div>태그를 사용해서 작업했던 결과물을 분석합니다.
부모 태그에 너비를 100% 준 다음 왼쪽(진행 후)과 오른쪽(진행 전)의 영역의 값을 JS로 삽입하는 방식이었습니다.
이렇게 된 코드를 <input type="range"> 방식으로 변경해보도록 하겠습니다.
지원 브라우저
들어가기전에 생각해야하는 부분은 <input type="range">는 IE10부터 지원합니다.
회사 정책에 IE가 포함되어 있지 않았기 때문에 진행할 수 있었습니다.
만약 하위브라우저를 지원해야한다면 type="range"를 다시 생각해보셔야합니다.
벤더 프리픽스(Vendor Prefix)
-webkit- : 크롬
-moz- : 파이어폭스
-ms- : IE
브라우저 기본 스타일
Chrome
Edge
Firefox
Chrome 브라우저같은 경우는 개발자도구 콘솔창에서 기본 스타일 확인이 가능합니다.
CSS 코드 수정해보기
기본 스타일 리셋시키기
Chrome(-webkit-)
input[type=range] {
width:100%;
-webkit-appearance: none;
background: transparent;
}
appearance는 사용자 운영체제 테마에 기반한 플랫폼 고유 스타일
background:transparent는 부모 배경 색상와 동일하게 하는 속성, 바에 영향을 받습니다.
스타일 적용 후
기본 모양에 있던 바가 감춰진 것이 확인됩니다.
이어서 마우스로 포인터를 이동하며 값을 조정할 때 (focus될 때) 보여지는 파란 라인(outline)값을 제거하도록 하겠습니다.
input[type=range]:focus {
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;
}
스타일 적용 후
마우스를 바 위에 올릴 경우(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-radius만 단독으로 사용했을때 변하는 부분을 못찾다가 border-radius + box-shadow 를 같이 적용하니
아래와 같이 그림자에 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;
}
스타일 적용 전과 후
신기한 부분이었는데, border만 적용해도 border-radius가 적용된 모습입니다.
덤으로 바가 사라졌습니다.
width, height를 적용했을땐 변하지 않던 포인터의 크기가 border 나 background 를 적용하면 변하였습니다.
border-radius를 border나 background-color랑 같이 사용했을 때 변하는 모습을 아래와 같습니다.
border-radius는 기본 값이 컸었는지, 오히려 숫자를 작게 했더니 각졌습니다.
여기까지 봤을때, 여러 스타일을 같이 사용해야 적용되는 것들이 존재했습니다.
width, height를 적용할 때 border랑 background 같이 적용하면 되는 줄 알았는데, (한 세트인지 알았습니다.)
나중에 쓰다보니까 background만 적용하려 할때에는 border가 없어도 적용되는 것을 확인했습니다.
width, height를 적용할 때 border-radius를 적용할 경우 border나 background는 없이도 적용되는 부분도 있었습니다.
근데, 브라우저마다 다르게 표현되는 부분들이 있어서 이 정도 학습으로는 아리송합니다..
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;
}
스타일 적용 전과 후
기본 스타일
border를 적용했습니다. border값이 적용됩니다.
width:50px; height:50px;를 적용했을때 width는 무시되나 height 값은 적용됩니다.
box-shadow
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%로 적용될 줄 알았는데, 아무런 크기 변화가 없습니다.
다만 포이터가 쳐지는 것을 확인할 수 있었습니다.
영역을 보면 확인이 됩니다.
보이는 바의 크기가 작아서 height가 적용이 안되나?0 싶어서 테스트를 해보았는데, height 값이 영역에 적용되어 있었습니다.
background를 추가하여 확인해보겠습니다.
다만 height:8.4px를 주었는데 8.39px로 되어있네요.
background-shadow
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 값을 10px로 변경해보니 아래와 같이 이상한 모습이 되었습니다.
이래서 100%를 적용해야하는것인가? 생각했습니다.
height : 바의 높이 값입니다.
뭔가.... 8.4px보다 적용된 게 커보여서, 비교해봤는데, 딱 맞습니다. 머쓱
box-shadow
border + border-radius
border-radius는 border값과 함께 적용해야합니다.
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는 바의 높이 값이 달라집니다.
background:transparent
border-color:transparent
color:transparent;
border-width:16px 0;
위로 16px 너비의 border를 적용하는데 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 마우스로 왼쪽에서 오른쪽으로 드래그하면 지나온 자리에 바 배경 색상이 적용됩니다.
border
border-radius
fill-lower에 대해 좀 더 확인 할 수 있을 듯해서 잠시 -ms-track의 background:transparent, border-color:transparent를 지운 상태입니다. 드래그한 포인터의 값보다 작은 값(진행된 부분)에만 파란색 배경이 적용되고 있습니다.
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[type=range]:focus::-ms-fill-lower {
background: red;
}
input[type=range]:focus::-ms-fill-upper {
background: pink;
}
스타일 적용 후
IE를 제외한 다른 브라우저는 lower, upper를 제공하고 있지 않습니다.
그래서 어떻게 할까 하다가 구글링한 정보입니다.
Firefox는 -moz-range-progress, -moz-range-track 셀렉터가 업데이트되었다고 합니다만....
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해서 영역을 감추는 방식입니다.
그렇다보니 포인터가 바의 크기보다 커질수가 없습니다.
요구조건이 불가능했기 때문에 다른 방식으로 작업해봤습니다.
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 등
'~2022 > FE-HTML, CSS, ...etc' 카테고리의 다른 글
input 태그 타입 checkbox, radio 스타일 커스텀하기 (0) | 2020.05.21 |
---|---|
VSCode extension으로 SASS/SCSS를 사용해보자! (0) | 2020.05.06 |
HTML과 CSS 1도 모르겠지만 테이블만들어보기 (Table Generator) (0) | 2019.12.23 |
<input> autocomplete Attribute , 자동 완성 기능에 대하여 (0) | 2019.11.25 |
메타태그로 브라우저 사용자 페이지 우회시키기(리다이렉션 시키기) (0) | 2019.07.29 |
유튜브 비디오 태그(iframe) css만으로 반응형 비디오 만들기 (0) | 2019.06.26 |
css 선택자 비교 (0) | 2019.06.25 |
CSS 네이밍 케이스, 방법론 (케밥 kebab-case/파스칼 pascalCase/스네이크snake_case/헝가리) (0) | 2019.06.15 |