이전 애니메이션 | 스크롤링 헤드라인
결과물 미리보기
단지 HTML 과 CSS 몇 스푼만 던져주면 구현해볼 수 있는 마키 UI, 같이 구현해 봅시다.
이번에 구현해볼 친구는?
오늘 인프런의 INFCON 을 소개하는 렌딩 페이지에서 아래와 같이 무한으로 흐르는 UI 를 볼 수 있었습니다. 왠지 구현해보면 재밌을 것 같아서, 이 친구가 동작하는 원리를 파악하고 직접 구현해보는 시간을 가져볼까 합니다.
마키 혹은 무한 스크롤 텍스트라 불리는 이 친구
컴베이어 벨트 처럼 무한으로 동작하는 이 친구는 마키 혹은 무한 스크롤 텍스트 라고 불리는 UI 입니다. 해당 UI 가 사용되는 목적은 보통 사용자들의 이목을 집중 시켜 중요한 정보를 지속적으로 표시하기 위해서 사용되는데요. 인프런에서도 인프콘 행사가 열리는 날짜를 부각시키기 위해서 #0078a7 계열의 색상을 사용하여 구현한 것을 볼 수 있습니다.
시작 전에 살펴보는 동작 원리
파란색 막대기는 각 콘텐츠 내용을 담고 있는 요소(.marquee) 입니다. 이 요소를 4개 묶어서 감싸고 있는 요소가 .container 요소가 되구요.
해당 컨테이너의 초기 위치는 마키 요소 2개 사용자의 화면에 보이게 됩니다. @keyframe 을 통해서 우측 좌측(0% -> -200%) 으로 움직이게 되는데, 초기의 마키 요소 2개가 아닌 숨겨져 있던 마키 요소 2개가 보이는 시점이 translate(-200%) 이 되는 지점 입니다. 즉, 해당 위치가 되면, 애니메이션이 종료되고, 다시 초기 위치로 리셋됩니다.
이를 계속 반복되면 사용자는 끊임없이 반복되는 UI 를 볼 수 있게 되는 겁니다.
HTML
아래와 같은 구조가 되도록 마크업을 작성해줍니다. 텍스트는 여러분이 원하는 것으로 바꾸셔도 됩니다. 뭐든 여러 방식을 시도해 봅시다. 참고로 style="--deg:30" 과 같이 되어 있는 것은 css 변수를 추가한 것입니다. 이는 나중에 var(--deg) 형식으로 사용할 수 있습니다.
<div class="container" style="--deg:15">
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
</div>
<div class="container" style="--deg:-15">
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
<div class="marquee">
<span>코딩라이프 </span>
<span>2024.06.29 </span>
<span>커밍순!!! </span>
</div>
</div>
CSS
다음은 CSS 입니다. 큰 틀만 보면 컨테이너 요소와 그 컨테이너 요소 내부에 있는 각 콘텐츠 요소들 그리고 이들을 움직이는 키프레임을 설정하는 것이 전부입니다.
전체 코드(주석 설명)
각 요소에 지정된 속성들의 역할은 주석으로 설명을 적어두었습니다. 이 중 몇 개의 중요한 설정만 따로 뽑아서 부연 설명 형식으로 언급 하겠습니다.
@font-face {
font-family: "양진체";
src: url("https://fastly.jsdelivr.net/gh/supernovice-lab/font@0.9/yangjin.woff")
format("woff");
font-weight: normal;
font-style: normal;
}
/* 브라우저에 적용된 기본 여백을 제거하고, 콘텐츠 영역을 계산시 여백을 포함하도록 해줍니다. */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* body 태그가 차지하는 영역을 뷰포트 100%에 맞추도록 해주고, 자식요소가 body 태그 바깥을
나가더라도 스크롤바가 생기지 않도록 해줍니다.
*/
body {
width: 100%;
height: 100vh;
background: #333;
overflow: hidden; /* 스크롤 바 생성 방지 */
}
/* .marquee 를 감싸고 있는 컨테이너 요소: 마키UI의 최대 높이를 설정하고, 각 UI 를 가로 정렬합니다. */
.container {
--rotate: calc(var(--deg) * 1deg); /* --deg:30 인 경우 1deg * 30 = 30deg 가 됩니다. */
display: flex;
border: 1px solid black;
margin-top: 10rem;
height: 105px;
transform: rotate(var(--rotate));
}
/* 컨테이너 요소를 마우스 호버 하면 모든 marquee 에 적용된 애니메이션 적용을 중지합니다. */
.container:hover {
.marquee {
animation-play-state: paused;
}
}
/* marquee 내부에 구성하고 있는 모든 span 요소들을 가로로 정렬합니다. */
.marquee {
box-shadow: 0 20px 0 rgba(0, 0, 0, 0.9);
padding: 15px 0;
display: flex;
align-items: center;
justify-content: center;
background: white;
width: 100%;
transform: translateX(0%);
animation: marquee 10s linear infinite; /* 10초 동안 진행되는 애니메이션을 일정한 간격으로 무한반복 */
/* 마키 내부에 나열된 콘텐츠 내용입니다.*/
span {
font-family: "양진체";
text-align: center;
font-size: 2.7em;
padding: 10px;
width: 300px;
display: inline-block; /* 인라인 태그를 block 속성 적용이 가능한 인라인 태그로 변경*/
}
}
/* 애니메이션을 적용합니다.*/
@keyframes marquee {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(-200%);
}
}
부연 설명 | .container 요소의 calc 와 var, 변수
여기서 일부만 뜯어보겠습니다. 앞서 .container 요소를 보면 아래와 같이 --rotate 변수를 선언하여 calc(var(--deg) * 1deg) 라는 값을 할당해준 것을 볼 수 있습니다. 그리고 이를 transform:rotate(var(--rotate)) 와 같이 전달하여 각각의 마키 UI에 각도 변화를 주고 있습니다.
이는 앞서 HTML 을 작성하는 과정 중 container 요소의 style 태그에 --deg:30, --deg:60 ,... 등과 같이 전달해 주는 부분하고 연결 됩니다. 즉, --deg:30과 --deg:60 에서 지정한 30과 60이라는 값이 CSS 내에서 --deg 내에 들어간다고 보시면 됩니다.
calc 는 CSS 에서 수학적인 처리를 하는 함수로서 즉, 계산기 같은 친구(이름 철자 부터도 계산기)입니다. --deg 로 전달된 값과 1deg 를 곱해주면 예시로 따지면 30deg, 60deg 가 각각 반환되는데, 이는 각 .container 클래스가 부여된 요소의 각도를 변경해주는데 사용되고 있습니다. 즉, --rotate: calc(var(--deg * 1deg)) 는 --rotate:calc(30 * 1deg) 가 되고, 이는 다시 --rotate:30deg 가 되어 transform:rotate(--rotate) 에 전달됩니다. 다시 말해, transform:rotate(30deg) 이 결과로 남게 됩니다.
결론적으로 transform:rotate(var(--rotate)); 에서는 var(--rotate) 의 자리에 30deg, 60deg 가 남게 되고, 이를 roate 함수가 처리하여 각도의 변환을 아래 이미지와 같이 주고 있다고 정리할 수 있습니다.
구현 결과
전체 코드를 시연하면 아래와 같습니다. 고생하셨습니다.
See the Pen Untitled by youngwan2 (@youngwan2) on CodePen.
다음 애니메이션 | 액자 모양 로고 애니메이션
'UI 디자인 애니메이션 연구소' 카테고리의 다른 글
캐러셀 라이브러리에서 보던 드래그 가능한 슬라이드, 원리 부터 구현까지!! (0) | 2024.07.18 |
---|---|
HTML과 CSS 만으로 이런 것도 가능해?? 액자 모양 로고 애니메이션 (0) | 2024.07.02 |
스크롤링 헤드라인 이라 불리는 뉴스티커 UI, 원리부터 구현 까지 (1) | 2024.06.27 |
HTML, CSS 로 불타는 입력창(Input) 만들기 (0) | 2024.06.20 |
HTML/CSS/JS 를 이용한 스트리밍효과 토글 UI 만들기 (0) | 2024.06.16 |