HTML & JS
<div class="mode-tog"></div>
<div class="container">
<div class="dark-mode"></div>
</div>
<h1>DARK MODE</h1>
<script>
let modeToggle = document.querySelector('.mode-tog');
let darkMode = document.querySelector('.dark-mode');
modeToggle.addEventListener('click', () => {
darkMode.classList.toggle('active');
modeToggle.classList.toggle('active');
})
</script>
CSS
나중에 프로젝트에 사용하려면 overflow:hidden를 잡아놨기 때문에 250vw/250vw로 늘리는 효과가 가능한 것이다
.container
우측 토글 버튼 위치를 기준으로(position:absolute;) 가운데에 위치하도록
transform: scale(number);
number가 1보다 크면, 확대 1보다 작으면 축소
.dark-mode
.dark-mode에 active 클래스가 붙는 순간 1배 확대하되, 기존에 .dark-mode의 사이즈를 250vw/250vw로 잡아놨기 때문에. 확대효과가 나타난다.
너비가 600px보다 작다면 vw가 아니라 vh로 250vh/250vh로 잡기.
(정사각형에서 원형을 그려야 하므로 vw혹은 vh로 통일한다.)
애초에 container의 위치 자체를 mode-tog에 정확히 일치시켜놨고, 그 다음 dark-mode의 위치를 relative로 잡더라도 container 위치에서 시작한다.
scale(0)으로 잡아놨으므로 요소가 보일 리가 없다.
scale(0)이면 완전 작아져서 사라지는 것이고,
flex-shrink는 0이면 원래 그 위치고, 1이면 줄어든다.
flex : flex-grow, flex-shrink, flex-basis;
flex-basis : flex item의 (공간 배분 전) 기본 너비 설정 (기본값:auto)
flex-shrink : flex item의 감소 너비 비율을 설정 (기본값:1)
flex-grow : flex item의 증가 너비 비율을 설정 (기본값:0)
flex-basis와 width 비교
flex-basis가 width보다 유연하다. width는 강제로 고정
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body,
html {
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: white;
}
.mode-tog {
background-color: black;
position: absolute;
right: 50px;
top: 50px;
cursor: pointer;
width: 20px;
height: 20px;
z-index: 2;
transition: 1000ms;
border-radius: 50%;
}
.mode-tog.active {
background-color: white;
transition: 1000ms;
}
.container {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
right: 50px;
top: 50px;
width: 20px;
height: 20px;
}
.dark-mode {
position: relative;
transform: scale(0);
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 250vw;
height: 250vw;
border-radius: 50%;
background-color: #161616;
transition: 1000ms ease-in-out;
display: flex;
flex: 0 0 auto;
}
.dark-mode.active {
transform: scale(1);
transition: 1000ms ease-in-out;
}
h1 {
color: white;
mix-blend-mode: difference;
position: absolute;
left: 50%;
top: 40%;
transform: translateX(-50%);
}
@media screen and (max-width: 600px) {
.dark-mode {
width: 250vh;
height: 250vh;
}
}
참고
Animated Dark Mode Toggle With HTML / CSS / JavaScript
CSS Flex(Flexible Box) 완벽 가이드