코딩쌀롱
[HTML¦CSS] multi range slider 본문
range slider를 유튜브 따라서 만들어봤다! 코드펜 링크🔗
javascript 코드도 들어가지만 input type="range"때문에 HTML¦CSS 카테고리에 글을 쓴다.
먼저 설명하자면,
1. 진짜 슬라이더인 input 2개를 만들고, 가짜 슬라이더 div를 만든다.
2. 진짜 슬라이더를 동작할 때 가짜 슬라이더도 같이 움직이도록 배치를 javascript 코드로 짠다.
3. 진짜 슬라이더를 opacity: 0 으로 투명하게 만들고, 가짜 슬라이더 위에 올린다.
4. 이 때 진짜 슬라이더는 2개지만 겹쳐놓고, thumb 두 개가 모두 활성화되도록 한다.(pointer-event: all)
✱HTML
<div class="middle">
<div class="multi-range-slider">
<!-- 진짜 슬라이더 -->
<input type="range" id="input-left" min="0" max="100" value="25" />
<input type="range" id="input-right" min="0" max="100" value="75" />
<!-- 커스텀 슬라이더 -->
<div class="slider">
<div class="track"></div>
<div class="range"></div>
<div class="thumb left"></div>
<div class="thumb right"></div>
</div>
</div>
</div>
✱CSS
-webkit-, -moz-는 동작 브라우저에 관한 prefix이다.
(webkit은 크롬, 사파리 / moz는 파이어폭스 / ms는 ie)
appearance: none을 해줘야 기본 스타일을 숨길 수 있다.
opacity 속성을 이용해 요소를 숨기면 가시성은 없지만 해당 영역의 이벤트는 동작하게 된다. 이를 강제로 제어하기 위해 pointer-event 속성을 활용한다.
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #e5e5e5;
}
.middle {
position: relative;
width: 50%;
max-width: 500px;
}
.slider {
position: relative;
z-index: 1;
height: 10px;
margin: 0 15px;
}
.slider > .track {
position: absolute;
z-index: 1;
left: 0;
right: 0;
top: 0;
bottom: 0;
border-radius: 5px;
background-color: #c6aee7;
}
.slider > .range {
position: absolute;
z-index: 2;
left: 25%;
right: 25%;
top: 0;
bottom: 0;
border-radius: 5px;
background-color: #6200ee;
}
.slider > .thumb {
position: absolute;
z-index: 3;
width: 30px;
height: 30px;
background-color: #6200ee;
border-radius: 50%;
}
.slider > .thumb.left {
left: 25%;
transform: translate(-15px, -10px);
}
.slider > .thumb.right {
right: 25%;
transform: translate(15px, -10px);
}
input[type="range"] {
position: absolute;
/* opacity로 가린 것을 이벤트도 비활성화하기 위해 */
pointer-events: none;
-webkit-appearance: none;
z-index: 2;
height: 10px;
width: 100%;
opacity: 0;
}
input[type="range"]::-webkit-slider-thumb {
/* 겹쳐진 두 thumb를 모두 활성화 */
pointer-events: all;
width: 30px;
height: 30px;
border-radius: 0;
border: 0 none;
background-color: red;
cursor: pointer;
/* appearance를 해야 위의 스타일들을 볼 수 있음 */
-webkit-appearance: none;
}
✱JavaScript
const inputLeft = document.getElementById("input-left");
const inputRight = document.getElementById("input-right");
const thumbLeft = document.querySelector(".slider > .thumb.left");
const thumbRight = document.querySelector(".slider > .thumb.right");
const range = document.querySelector(".slider > .range");
const setLeftValue = () => {
const _this = inputLeft;
const [min, max] = [parseInt(_this.min), parseInt(_this.max)];
// 교차되지 않게, 1을 빼준 건 완전히 겹치기보다는 어느 정도 간격을 남겨두기 위해.
_this.value = Math.min(parseInt(_this.value), parseInt(inputRight.value) - 1);
// input, thumb 같이 움직이도록
const percent = ((_this.value - min) / (max - min)) * 100;
thumbLeft.style.left = percent + "%";
range.style.left = percent + "%";
};
const setRightValue = () => {
const _this = inputRight;
const [min, max] = [parseInt(_this.min), parseInt(_this.max)];
// 교차되지 않게, 1을 더해준 건 완전히 겹치기보다는 어느 정도 간격을 남겨두기 위해.
_this.value = Math.max(parseInt(_this.value), parseInt(inputLeft.value) + 1);
// input, thumb 같이 움직이도록
const percent = ((_this.value - min) / (max - min)) * 100;
thumbRight.style.right = 100 - percent + "%";
range.style.right = 100 - percent + "%";
};
inputLeft.addEventListener("input", setLeftValue);
inputRight.addEventListener("input", setRightValue);
참고📚
유튜브 - Multi Handle Range Slider
블로그 - CSS 이벤트 제어 pointer-events 속성
'개발공부' 카테고리의 다른 글
[Algorithm] Quick Sort (0) | 2021.06.15 |
---|---|
[Web¦Browser] local, session, cache, cookie (0) | 2021.06.07 |
react와 TypeScript로 canvas 그리기 (0) | 2021.05.31 |
[TS] 타입스크립트 메모2 (0) | 2021.05.21 |
Comments