100 DAYS CSS CHALLENGE #DAY20

everdeer·2025년 7월 15일

100 days CSS challenge

목록 보기
20/22
post-thumbnail

DAY #20

- 문제

👉 문제 바로가기

Send Mail: Surprise your visitors with a nice animation instead of a simple "request sent".

메일 보내기: 간단한 "요청 전송됨" 대신 멋진 애니메이션으로 방문자를 놀라게 하세요.

이제 대충 알것 같다! 라고 생각했지만 다시 봐도 모르겠는 문제...

이번엔 구조 확인부터 해보자.


- 문제 HTML 구조 확인


확인해보면 이제 inputlabel, 그리고 svg가 쓰이는게 보인다.

역시나, 'SEND MAIL' 버튼을 누르면 나오는 모션들은 svg가 사용 되었고,

저 버튼들을 어떻게 처리하나 싶었는데, 이전 문제와 마찬가지로 :checked를 사용해서 체크 됨에 따라 label 이 보였다가, 안보였다가 하게 opacity를 이용한듯 하다.


그럼 이제 어떤식으로 동작하는지 구조를 이해했으니 직접 짜 보도록 하겠다.

.
..
...

라고 확인까지 해놓고 또 같은 실수를 반복하고 말았다..😇

이번에도 input:checkbox가 사용되었으니, input과 요소들이 형제관계에 있어야 동작하는 문제였는데, 직접 짜겠다고 또 요소 정렬만 생각하고 마크업 했다가 대거 수정을 해야 하는 참사가 또다시 발생 ㅠㅠ


퍼블 입장에선 정렬하는게 젤 중요하다보니,,,
사실 잘 배치하고 javascript로 기능은 추가하면 되는 거니까...
자꾸 까먹는것 같다🤣

암튼 다시 대거 수정.. (html만 봐선 대거 수정이라고 할 수 없지만,, CSS를 대거 수정했음 ㅠ)

- 대거 수정 한 코드

문제랑 코드가 거의 똑같아 보이는건 그렇게 하고싶지 않아도..
저렇게 짤수밖에 없는 문제여서😂
(이번엔 input이랑 label을 굳이 붙여놓지 않았다 ㅎㅎ😅)


- 내가 만든 SCSS Code


처음에 했던 마크업 대로 배치했던 바람에 CSS를 수정하는데 고생을 하긴 했지만,
배치보다는 애니메이션 효과✨에 더 포인트를 둔 문제이기 때문에!
배치에 대해서는 따로 설명하지 않고 모션✨ 위주로 설명을 해보겠다!



여기서 사용된 svg 속성은 👉 DAY10 에서도 자세히 다뤄본 적이 있는데!

stroke-dasharraystroke-dashoffset 을 사용해서
선이 지워지고, 그려지는 효과를 줄 것이다!



✨ 지워지고🗑, 그려지는🖍 효과 주기


설정효과
stroke-dasharray: 325 선 325
stroke-dashoffset: 0처음부터 선 보임
stroke-dashoffset: 325전부 밀려서 선이 안 보임

✉ 과 ✈ 에 각각
stroke-dashoffset: 0stroke-dashoffset: 325 을 주어서

처음엔 메일 모양 ✉이 보이고, 비행기 모양 ✈이 안보이게 한 다음!

#btn:checked 이렇게 버튼이 활성화 되면~~

  & ~ .mail {
    stroke-dashoffset: 325; // 선이 안보이게
    transition: stroke-dashoffset 1s ease-in-out;
  }
  & ~ .plane {
    stroke-dashoffset: 0; // 선 보이게
    transition: stroke-dashoffset 1s ease-in-out 0.6s;
    animation: fly 2.4s ease-in-out both; // 이건 비행기 날아가는 애니메이션
  }

transition 을 이용해서 의 선이 (1초동안 스르륵) 안보여지게 밀려나서 지워지는 듯 한 모션이 생길수 있었던것!

마찬가지로 ✈ 도 0.6초 후에 스르륵 그려지는 모션이 생긴다!


복잡행~~😵




비행기✈ 슝🛫 날아가는 모션 만들기

이어서 비행기 날아가는 애니메이션도 설명해보자면

@keyframes fly {
  0%, 50% {
    transform: translate3d(0, 0, 0) scale(1); // 50% 까지 제자리에 잘 있다가
  }
  60% {
    transform: translate3d(-10px, 5px, 0) scale(1.05); //좌측 하단으로 약간 이동하고 약간 커짐
  }
  70% {
    opacity: 1; // 70% 까지는 보였다가
  }
  85% {
    opacity: 0; // 여기서부터 없어짐
  }
  100% {
    transform: translate3d(300px, -150px, 0) scale(0.4); // 우측 상단(화면 밖)으로 이동하면서 작아짐
    opacity: 0; // 없어짐
  }
}

중앙 > 좌측 하단 (약간 커짐) > 흐려지기 시작 > 우측 상단 (화면 밖, 작아짐) > 화면 밖에서 없어짐. 요런 루트이다!



원모양 배경🎯 애니메이션 주기

버튼을 누르면 메일 모양 뒷편에 있는 원 모양 배경에도 애니메이션이 들어간다.

@keyframes circle {
  0% {
    transform: translateX(-50%) scale(1);
  }
  20% {
    transform: translateX(-50%) scale(1.1);
  }
  100% {
    transform: translateX(-50%) scale(0);
  }
}

translateX 는 신경쓰지 마세요 ㅠㅠ 원모양 중앙에 배치하려고 해둔거라 ㅠㅠ
scale : 정사이즈 > 약간 커짐 > 사라짐 순으로 진행됩니다~~


  & ~ .circle {
    animation: circle 1s ease-in-out both;
  }
  & ~ .circle_ring {
    animation: circle 0.8s ease-in-out 0.2s both;
  }

원이 커졌다가, 작아지면서 테두리같은 잔상? 이 남는데 이 원을 .circle_ring 이라고 해둠!

그냥 원이랑 동일한 애니메이션이지만~ 조금더 빠르게(ㅋㅋ) 사라지고, 0.2초 의 시간차를 두어서 잔상처럼 보이게 한것!



버튼📌 애니메이션

<input type="checkbox" id="btn" />
~ ... ~
<label for="btn" class="btn mail">SEND MAIL</label>
<label for="btn" class="btn reset">RESET</label>

처음엔 'SEND MAIL'이 보였다가, 비행기가 날아가고 나면, 버튼이 사라지고 'RESET' 버튼이 나온다.

for="btn" 으로 같은 기능을 하는 label 두개를 따로 만들어 두고, 애니메이션을 따로 주어서 위와 같은 모션을 만들 수 가 있당~

#btn:checked 이렇게 버튼이 활성화 되었을 때,

  & ~ .btn {
    animation: button 1.5s ease-in-out 1.7s both; // 버튼 애니매이션
  }
  & ~ .reset {
    animation: reset 1s ease-in-out 3.7s both; // 3.7초 뒤에 나타나는 모션
  }

'SEND MAIL' 버튼 의 모션이 (1.5초동안 + 1.7초 딜레이 = 3.2초) 동안 진행 되고!

@keyframes button {
  0% {
    transform: translateX(-50%) scale(1); // 변경X
  }
  30% {
    background: #1abc9c; // 배경색 변경
    color: transparent; // 글자 투명
    width: 200px; // 변경X
  }
  50%, 60% {
    width: 40px; // 원 모양으로 변경
    transform: translateX(-50%) scale(1);
  }
  70% {
    transform: translateX(-50%) scale(1.1); // 조금 커졌다가~
  }
  100% {
    width: 40px; // 끝까지 원모양 유지
    background: #1abc9c; // 배경색 변경
    color: transparent; // 글자 투명
    transform: translateX(-50%) scale(0); // ~없어짐
  }
}
// translateX는 가운데 정렬용이라 애니메이션과는 상관이 없으니 무시

'RESET' 버튼은 'SEND MAIL' 버튼이 끝나고 0.5초 (= 3.7초 딜레이 - 진행시간 3.2초) 후에!

@keyframes reset {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

이렇게 숨겨져있다가 나오게 되는 것!
🙌



- 결과물


버튼이 활성화 되었을 때 모션이 시작되고 꺼지면 다시 Reset 되는 구조라
구조를 어떻게 짜야하는지 고민했던 문제인 것 같다.

#btn:checked {
  & ~ .btn {
    animation: button 1.5s ease-in-out 1.7s both;
  }
  & ~ .reset {
    animation: reset 1s ease-in-out 3.7s both;
  }
  & ~ .circle {
    animation: circle 1s ease-in-out both;
  }
  & ~ .circle_ring {
    animation: circle 0.8s ease-in-out 0.2s both;
  }
  & ~ .mail {
    stroke-dashoffset: 325;
    transition: stroke-dashoffset 1s ease-in-out;
  }
  & ~ .plane {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 1s ease-in-out 0.6s;
    animation: fly 2.4s ease-in-out both;
  }
}

위 구조가 젤 중요한 문제였던듯 하다!

label 두개를 이용하여 이런 효과를 낼 생각을 했다니... 문제 낸 사람 정말 머리가 비상하신듯..!


profile
진귀한 웹 퍼블리셔

0개의 댓글