Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- web component
- 우아한테크코스
- Docker
- swiper
- AX210
- typescript
- browserslist
- 우아한테크코스 레벨3
- react
- GitHub Pages
- fastify
- Grafana
- RTL8852BE
- webpack
- javascript
- 데모데이
- Shadow DOM
- 무선랜카드 교체
- docker-compose
- scroll-snap
- 터치 스와이프
- Prometheus
- 유한 상태 머신
- react-dom
- live share
- HTML
- custom element
- github Actions
- 우테코
- CSS
Archives
- Today
- Total
IT일상
CSS로 별점 기능 만들기 본문
리뉴얼 된 블로그로 보기: https://solo5star.dev/posts/33/
JavaScript를 최대한 적게 사용하여 별점 기능을 만들어보려고 합니다.
body {
background: rgb(32, 32, 40);
}
.vote {
display: flex;
}
.star { padding: 1px; }
.star::after {
content: '☆';
color: hsl(60, 80%, 50%);
font-size: 20px;
}
<body>
<div class="vote">
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
</body>
별 모양을 표현하는 CSS를 만들어줍니다. 그리고 위의 HTML과 같이 마크업을 합니다.
별 다섯개가 표시될 것입니다. 간단하게 하기 위해 ☆ 특수기호를 사용하였습니다.
:hover
.star:hover::after {
content: '★';
}
마우스를 올릴 때 :hover pseudo class가 활성화될 것입니다.
:has(~ :hover)
갑자기 어려운 쿼리가 나타났습니다. 하나씩 해석해보자면,
:has() 는 괄호 안의 선택자에 해당되는 엘리먼트를 가지고 있을 때 활성화될 것입니다. 기본적으로 자식 요소를 찾습니다.
하지만 괄호 안에서 물결표(~)로 시작한다면, 자신의 뒤에 있는 요소를 찾습니다.
즉 .star:has(~ .star:hover) 는, 자신(.star)의 뒤의 요소에 :hover된 .star가 있다면 활성화됩니다.
.star:has(~ .star:hover)::after {
content: '★';
}
클릭 시 별이 고정되도록 하기
아쉽게도 이 로직은 CSS로 불가능하며, JavaScript가 필요합니다.
document.querySelectorAll('.star').forEach(($star) => {
$star.addEventListener('click', ({ target }) => {
// 모든 .star에서 .active 삭제
document.querySelectorAll('.star').forEach(($star) => {
$star.classList.remove('active');
});
// 클릭한 .star에 .active 추가
target.classList.add('active');
});
});
클릭하였을 때 클릭된 .star에 .active를 추가하는 코드입니다.
.star.active::after,
.star:has(~ .star.active)::after {
content: '★';
}
그리고 :hover에서 했던 것처럼 비슷하게 CSS를 추가하면 됩니다.
호버 중일 때 뒤의 별들은 모두 끄기
위의 Gif를 보고 어색하다고 느꼈을 겁니다. :hover 시 :hover된 .star를 기준으로 뒤의 .star들이 모두 꺼져야 하기 때문입니다.
이 또한 CSS로 간단하게 처리할 수 있습니다.
.star:hover ~ .star::after {
content: '☆';
}
물결표(A ~ B) 선택자는 A 뒤에 있는 B를 선택합니다. 즉 .star:hover ~ .star 는, :hover되어있는 .star 뒤의 .star가 선택됩니다.
전체 소스코드
<!DOCTYPE html>
<html lang="ko">
<head>
<style>
body {
background: rgb(32, 32, 40);
}
.vote {
display: flex;
}
.star { padding: 1px; }
.star::after {
content: '☆';
color: hsl(60, 80%, 50%);
font-size: 20px;
}
.star:hover::after,
.star:has(~ .star:hover)::after,
.star.active::after,
.star:has(~ .star.active)::after {
content: '★';
}
.star:hover ~ .star::after {
content: '☆';
}
</style>
</head>
<body>
<div class="vote">
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
</body>
<script>
document.querySelectorAll('.star').forEach(($star) => {
$star.addEventListener('click', ({ target }) => {
// 모든 .star에서 .active 삭제
document.querySelectorAll('.star').forEach(($star) => {
$star.classList.remove('active');
});
// 클릭한 .star에 .active 추가
target.classList.add('active');
});
});
</script>
</html>
'프론트엔드' 카테고리의 다른 글
GitHub Actions: storybook 배포하기 (4) | 2023.04.23 |
---|---|
GitHub Actions: CRA(Create React App) 빌드 + GitHub Pages 배포 자동화하기 (0) | 2023.04.23 |
타입스크립트 Discriminated Unions (0) | 2023.03.27 |
타입스크립트 템플릿 리터럴 타입 (0) | 2023.03.27 |
[Web Component] 커스텀 폼 컨트롤, form associated 컴포넌트 만들기 (2) | 2023.03.07 |
Comments