순수 JavaScript + CSS 스크롤 애니메이션 (샘플 코드)

웹 브라우저의 스크롤을 내리면 생동감 있게 나타나는 애니메이션을 구현하는 샘플 코드를 소개합니다. 순수 JavaScript와 CSS로 작성되었습니다. 웹 페이지에서 아래로 스크롤하면, 정해진 타이밍에 HTML 요소가 서서히 나타나는 '페이드 인' 효과는 요즈음 새로 만들어진 웹사이트에서 자주 볼 수 있는 현대적인 디자인입니다.

'스크롤 페이드 인 애니메이션'은 고정적이고 밋밋한 디자인을 과하지 않게 역동적이고 시선을 끄는 디자인으로 변화시킬 수 있습니다. 그런데 보통 jQuery로 코드를 작성하는 사례가 많은 것 같습니다. 하지만 순수한 (바닐라) JavaScript와 CSS만으로도 간단하고 가볍게 구현할 수 있습니다. 본문의 샘플 코드를 참고하고, 더 나아가 응용하면 개성있는 스크롤 애니메이션 웹 페이지를 충분히 만들어 낼 수 있을 거라 생각합니다.

 

🍀버전1~4, 순서대로 읽어 보세요.

JavaScript CSS 스크롤 애니메이션

버전1 (기본형) 스크롤을 내리면 나타나는 애니메이션

[샘플 코드]


[코드 설명]

sa(Scroll Animation) 클래스를 가진 <div> 요소들이 스크롤 애니메이션될 대상들이고, 처음에는 보이지 않는 상태입니다.

그 보이지 않는 상태에서 사용자가 스크롤을 내리면 105행의 'element.getBoundingClientRect().top'이 점점 작아지면서, 해당 요소에 show 클래스를 추가하는 조건이 충족되어 보이게 되는 로직입니다.

그 보이게 될 때의 애니메이션은 8개 클래스로 준비했습니다.
sa-up
sa-down
sa-right
sa-left
sa-rotateL
sa-rotateR
sa-scaleUp
sa-scaleDown

각 클래스들이 어떤 효과를 내는 지는 샘플 코드의 주석을 우선 확인하고, 테스트할 때 30행의 'all .5s ease'을 'all 3s ease'으로 변경하면 이해하기 쉽습니다.
버전1 기본형 샘플 페이지 보기


버전2 표시 타이밍의 기준이 되는 요소를 지정할 수 있게

'버전1 기본형 샘플 페이지'를 확인해 보면, 2·3번째 섹션(<section> 요소)내의 디비전(<div> 요소)들이 표시되는 타이밍이 같지 않는데, 각 섹션마다 표시 타이밍의 기준이 되는 요소를 하나 정해서 그 요소의 타이밍에 맞추도록 하려고 합니다.

디비전 5와 9를 기준으로 정하고, 각각 id 속성을 추가합니다. 그리고 기준이 아닌 요소는 data-sa-trigger 속성을 추가하고, 그 값에 기준 요소의 id를 지정합니다.

그러면 이렇게↓↓↓ 변경됩니다.

그리고 JavaScript에서는 data-sa-trigger 속성을 가진 디비전은 기준 디비전의 위치로 타이밍을 재고, data-sa-trigger 속성이 없는 디비전은 자신의 위치로 타이밍을 재도록 합니다.

그러면 이렇게↓↓↓ 변경됩니다.

변경 내용을 적용해 보세요. 모든 섹션의 자식들이 기준에 따라 같은 타이밍에 일률적으로 페이드 인 애니메이션을 하면서 나타나죠❓
버전2 샘플 페이지 보기


버전3 표시 타이밍을 위치로 조절할 수 있게

1번째 섹션의 디비전들은 모두 표시되는 타이밍이 같습니다. 왜냐하면 화면에 나타나기 전에 대기하고 있는 위치가 모두 같이 때문이죠.

이렇게 위치에 의존해서 표시 타이밍을 결정하는 로직에서 임의로 조정이 가능하도록 하기 위한 것이 바로 'saTriggerMargin'입니다. 현재까지는 값이 고정적으로 300입니다. 이 값을 각 디비전별로 다르게 지정해 보겠습니다.

그러려면, 새 속성 data-sa-margin을 추가합니다. 이렇게↓↓↓

그리고 JavaScript는 이렇게↓↓↓ 변경합니다.

변경 내용을 적용해 보면, 1번째 섹션의 디비전들이 스크롤이 내려감에 따라 차례대로 나타나는거 보이시나요❓
버전3 샘플 페이지 보기


버전4 표시 타이밍을 시간으로 조절할 수 있게

버전3과 같이 사용자에 의해 스크롤이 계속 내려가야만 순서대로 모두 나타나는 애니메이션도 좋지만, 일반적인 경우에는 스크롤이 일정 위치까지 내려오면 임의의 시간차를 두고 나타나는 것이 더 멋지고 자연스럽게 보인다고 생각합니다.

그러려면, 새 속성 data-sa-delay를 추가합니다. 이렇게↓↓↓

그리고 JavaScript는 요렇게↓↓↓ 변경합니다.

위 코드를 적용 후, 다시 확인해 보세요. 스크롤이 어느 정도 내려가면, 1번째 섹션의 디비전들이 시간차(여기서는 0.2초)를 두고 나타나는거 보이시나요❓
버전4 샘플 페이지 보기
#소프트웨어 개발

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

댓글

  1. 안녕하세요~ 소스 너무 쉽게 알려주셔서 도움이 됩니다. 그런데 사용하다가 IE에서는 노출이안되는데 혹시 IE에서 가능할까요? CSS에 IE버전 소스 추가해봐도 변화가 없어서요. 답변주신다면 너무 감사할거같아요~ 감사합니다~~!!

    답글삭제
    답글
    1. 안녕하세요. IE에서는 테스트해 보지 않았습니다. 지금 해보니 우선 '버전1 기본형 샘플 페이지 보기' 여기부터 IE에서 동작하지 않네요.

      for...of - JavaScript | MDN의 아래쪽에 '브라우저 호환성'에 보면 for...of 문은 IE에서 지원하지 않는다고 합니다.

      IE 콘솔에서도 for...of 문에서 에러가 나오는데, 이 부분 수정해서 사용하시면 될 것 같습니다.

      삭제
    2. 잘 해결되시길 바랍니다!

      삭제
    3. 핡. 찾아보니 구문에서 지원안되는게 있더라구요.ㅎㅎ 답변 감사합니다~~

      삭제
  2. JavaScript 관련 글을 가끔 게시하고 있는데

    IE에서 안 된다는 댓글이 다른 글에도 달리는 걸 보면

    여전히 IE 대응하는 작업이 필요한 것 같아 보이네요.

    답글삭제
  3. 작성자가 댓글을 삭제했습니다.

    답글삭제
    답글
    1. 해결 됐습니다! 스크립트 위치 때문에 안됐던거네요 ㅠㅠㅠ 글 너무 이해하기 쉬워서 제가 원하는 스크롤 애니메이션을 넣을 수 있게되었습니다 ㅠㅠㅠ 정말 감사합니다!!!

      삭제
    2. 안녕하세요. 방문, 감사합니다. 제가 접속할 수 있는 페이지라도 있으면 좋을 텐데, 개발자 도구 열고 차분히 여기저기 디버깅해 보시면 알 수 있을 것 같아요. 본문에 있는 샘플 페이지에는 콘텐츠가 보이고 있는데 만드신 페이지는 무슨 문제일까요..

      삭제
    3. 잘 해결되어 다행이네요^_^ 추석 잘 보내세용~

      삭제
  4. 안녕하세요 소스 알기쉽게 알려주셔서 정말 감사합니다.ㅠ ㅠ
    앞에분에게 알려주신것처럼 저도 구문이라 for (const element of saElementList) 문이 계속 에러가 뜨더라구요 ㅠ
    혹시 수정문 알려주실수있으실까요 ㅠ ㅠ

    답글삭제
    답글
    1. $.each(saElementList, function(index, element)
      그부분에 이렇게 넣어보세요

      삭제
  5. 안녕하세요 제가 계속 찾고 있던 소스네요 ㅠㅠ 혹시 납품용 사이트에 응용해서 사용해도 될까요?!

    답글삭제
  6. 4번째는 IE버전에서도 나오게 하려면 어디를 수정해야 될까요 ㅜㅜ 1번은윗 댓글처럼 $.each(saElementList, function(index, element) 이걸로 바꾸니 모든데서 다 잘나오더라구요 4번은.. 이거만 수정해선 안되는거 같아요 혹시 알수 있을까요 ㅠㅠ

    답글삭제
  7. 알기쉽게 알려주셔서 정말 감사합니다

    답글삭제

댓글 쓰기