본문 바로가기
> IT 노트/활용

[CSS] 지나가는 전광판 만들기

by 자몽주스 2024. 7. 6.
728x90
참고사이트:

흐르는 텍스트 구현하기 (velog.io)

 

흐르는 텍스트 구현하기

화면상에서 텍스트가 왼쪽으로 무한히 흐르는 것을 구현해보자.호버(hover) 했을 때는 텍스트 색이 진해지면서 흐르던 것이 멈춘다.이 구현은 생각보다 간단한데, html과 css 로만 구현이 가능하다.

velog.io


scss 전광판.zip
0.00MB


HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>css Test</title>
    <link href="main.css" rel="stylesheet" />
  </head>
  <body>
    <!-- 팝업 시작 -->
    <div class="flow-container">
      <div class="flow-text">
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
      </div>
    </div>
  </body>
</html>
CSS
.flow-text {
	  display: flex;
      flex: 0 0 auto;
      white-space: nowrap;
      overflow: hidden;
      transition: 0.3s;
      font-size: 2.5rem;
      font-weight:bold;
      color: #9D9993;
  }
  .flow-text:hover {
    color: #000;
  }
  .flow-text:hover .flow-wrap {
    animation-play-state: paused;
    cursor: pointer;
  }
  .flow-wrap {
    animation: textLoop 10s linear infinite;
    padding-right: 1.4881vw;
  }
  
  @keyframes textLoop {
    0% {
      -webkit-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
    }
    100% {
      -webkit-transform: translate3d(-100%, 0, 0);
      transform: translate3d(-100%, 0, 0);
    }
  }
div.flow-container 로 한 번 더 감싼 이유

저렇게 한번 더 감싼 이유는 텍스트만 호버했을때 흐르는 텍스트가 멈추게 하기 위해

div.flow-container 로 한 번 더 감쌈. 


흐르는 텍스트를 구현하기 위한 중요한 포인트
div.flow-text 의 style 속성
display: flex;
flex: 0 0 auto;
white-space: nowrap;
overflow: hidden;
텍스트를 가로로 나열하기 위해서 display: flex;
화면이 줄어들었을때 항목들의 사이즈가 줄어들지 않게 하기위해 flex: 0 0 auto;
텍스트가 가로로 나열되면서 밑으로 떨어지는 것을 막기위해 white-space: nowrap;
밖으로 넘치는 텍스트 때문에 가로스크롤 생기는 것을 막기위해 overflow: hidden;
중요한 포인트인 이유 

1. display: flex;

역할

display: flex;는 요소를 Flex 컨테이너로 설정하고, 그 안의 자식 요소들을 Flex 아이템으로 만듭니다.

Flexbox 레이아웃을 사용하면 자식 요소들을 가로 또는 세로 방향으로 쉽게 정렬할 수 있습니다.

중요성

전광판 텍스트가 가로로 연속적으로 나열되기 위해 Flexbox 레이아웃을 사용합니다.

Flexbox를 사용하면 자식 요소들이 자연스럽게 가로로 정렬되며, 유연한 레이아웃을 만들 수 있습니다.

2. flex: 0 0 auto;

역할

이 속성은 각 Flex 아이템이 고정된 크기를 유지하도록 설정합니다.

  • flex-grow: 0: 여유 공간이 있어도 아이템이 그 공간을 차지하려고 하지 않습니다.
  • flex-shrink: 0: 공간이 부족해도 아이템이 크기를 줄이지 않습니다.
  • flex-basis: auto: 아이템의 기본 크기를 콘텐츠 크기나 width 속성에 따라 설정합니다.

중요성

전광판 텍스트가 일정한 크기를 유지해야 하는 이유는

화면 크기가 줄어들거나 늘어나더라도 텍스트가 크기를 변화시키지 않고 흐르게 하기 위함입니다.

이렇게 해야 애니메이션이 부드럽게 유지됩니다.

3. white-space: nowrap;

역할

이 속성은 텍스트가 줄 바꿈 없이 한 줄로 표시되도록 합니다.

중요성

전광판 텍스트가 여러 줄로 나뉘지 않고 한 줄로 이어져서 흘러야 합니다.

white-space: nowrap; 속성을 사용하면 텍스트가 줄 바꿈 없이 한 줄로 유지됩니다.

4. overflow: hidden;

역할

이 속성은 요소의 내용이 요소의 크기를 넘어갈 때 넘친 부분을 숨깁니다.

중요성

전광판 텍스트가 화면 밖으로 넘쳐서 스크롤바가 생기는 것을 방지하고,

깔끔하게 흐르는 애니메이션을 만들기 위해 필요합니다.

넘친 텍스트 부분을 숨겨서 가로로 흘러가는 효과를 시각적으로 부드럽게 만듭니다.

전체 조합의 중요성

이 네 가지 속성을 조합하면 다음과 같은 효과를 얻을 수 있습니다:

  • 가로 정렬: display: flex;로
  • 텍스트를 가로로 정렬합니다.
  • 고정 크기 유지: flex: 0 0 auto;로 텍스트 크기를 고정하여 줄어들거나 늘어나지 않게 합니다.
  • 줄 바꿈 방지: white-space: nowrap;로 텍스트가 줄 바꿈 없이 한 줄로 표시됩니다.
  • 넘친 부분 숨기기: overflow: hidden;으로 넘치는 텍스트를 숨겨 깔끔한 전광판 효과를 만듭니다.

flex: 0 0 auto; 속성 이해하기

 

flex는 CSS Flexbox 레이아웃 모듈에서 사용하는 단축 속성입니다.

flex 속성은 세 가지 값을 가질 수 있습니다:

flex-grow, flex-shrink, flex-basis. 이 세 가지 값을 조합해서

자식 요소가 Flex 컨테이너 안에서 어떻게 공간을 차지할지 정의합니다.

flex: 0 0 auto;의 의미

  1. flex-grow: 0:
    • 요소가 컨테이너 안에서 추가적인 공간을 차지하려고 하지 않습니다.
    • 즉, 컨테이너에 여유 공간이 있어도 이 요소는 그 공간을 차지하려고 늘어나지 않습니다.
  2. flex-shrink: 0:
    • 요소가 컨테이너 안에서 공간이 부족해도 자신의 크기를 줄이지 않습니다.
    • 컨테이너가 줄어들더라도 요소의 크기는 그대로 유지됩니다.
  3. flex-basis: auto:
    • 요소의 기본 크기는 auto로 설정됩니다.
    • 이는 요소의 콘텐츠 크기나 width 속성 값에 따라 결정됩니다.

왜 사용하는가?

flex: 0 0 auto;를 사용하면 요소의 크기가 변하지 않고 고정된 상태로 유지됩니다.

특히 텍스트가 가로로 나열될 때 유용합니다.

예를 들어, 화면 크기가 줄어들더라도 각 텍스트 요소의 크기는 그대로 유지되며 줄어들지 않습니다.

이를 통해 다음과 같은 효과를 얻습니다:

  • 텍스트가 가로로 나열됩니다.
  • 각 텍스트 요소는 자신의 크기를 유지하며 줄어들지 않습니다.
  • 텍스트가 컨테이너 밖으로 넘치게 되면
  • overflow: hidden; 속성으로 인해 가로 스크롤이 생기지 않고 숨겨집니다.
만약 flex: 0 0 auto;를 사용하지 않으면 텍스트 요소가 화면 크기에 따라 크기가 변할 수 있으며,
의도하지 않은 레이아웃 문제가 발생할 수 있습니다.
이 속성을 사용함으로써 텍스트 요소의 크기를 고정하고 안정적인 레이아웃을 유지할 수 있습니다.

flex-grow, flex-shrink, flex-basis 속성 알아보기

1. flex-grow

정의

flex-grow는 Flex 컨테이너 내에서 여유 공간이 있을 때,

Flex 아이템이 그 공간을 얼마나 차지할지 결정하는 속성입니다.

기본 값

기본 값은 0입니다. 이는 여유 공간이 있어도 아이템이 그 공간을 차지하려고 하지 않음을 의미합니다.

.item {
  flex-grow: 1; /* 여유 공간을 다른 아이템들과 균등하게 나눔 */
}

여러 아이템이 flex-grow: 1로 설정되어 있으면,

여유 공간을 균등하게 나누어 가지게 됩니다.

만약 한 아이템의 flex-grow 값이 2라면,

다른 아이템에 비해 두 배 더 많은 여유 공간을 차지하게 됩니다.

2. flex-shrink

정의

flex-shrink는 Flex 컨테이너의 크기가 줄어들 때, 각 Flex 아이템이 얼마나 줄어들지를 결정하는 속성입니다.

기본 값

기본 값은 1입니다. 이는 컨테이너가 줄어들 때 아이템이 줄어들 수 있음을 의미합니다.

.item {
  flex-shrink: 0; /* 줄어들지 않음 */
}

flex-shrink: 0으로 설정된 아이템은 컨테이너의 크기가 줄어들더라도 자신의 크기를 유지하려고 합니다.

반면, flex-shrink: 1로 설정된 아이템은 줄어들게 됩니다.

3. flex-basis

정의

flex-basis Flex 아이템의 기본 크기를 설정하는 속성입니다.

이 값은 width와 비슷하지만, Flex 컨테이너 내에서 아이템의 초기 크기를 설정하는 데 사용됩니다.

기본 값

기본 값은 auto입니다. 이는 아이템의 콘텐츠 크기나 width 속성에 따라 기본 크기가 결정됨을 의미합니다.

.item {
  flex-basis: 200px; /* 기본 크기를 200px로 설정 */
}

 

flex-basis: 200px으로 설정된 아이템은 기본 크기가 200픽셀이 됩니다.

이 값은 flex-grow와 flex-shrink가 적용되기 전에 아이템의 초기 크기를 결정합니다.

flex 단축 속성

flex 속성은 이 세 가지 속성을 한 번에 설정할 수 있는 단축 속성입니다. 예를 들어:

.item {
  flex: 1 1 200px;
}

이 코드는 다음과 동일합니다:

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 200px;
}

flex: 0 0 auto;의 의미 다시 보기

.item {
  flex: 0 0 auto;
}
  • flex-grow: 0: 아이템이 여유 공간을 차지하지 않습니다.
  • flex-shrink: 0: 아이템이 줄어들지 않습니다.
  • flex-basis: auto: 아이템의 기본 크기는 콘텐츠 크기나 width 속성에 따라 결정됩니다.

이 조합을 통해 아이템의 크기를 고정하고,

여유 공간을 차지하거나 줄어들지 않도록 설정합니다.

이는 화면 크기가 줄어들더라도 각 아이템의 크기를 일정하게 유지하기 위해 사용됩니다.

이제 flex-grow, flex-shrink, flex-basis의 개념을 이해하셨을 것입니다.

이를 바탕으로 flex 속성을 활용하여 유연하고 안정적인 레이아웃을 구성할 수 있습니다.


애니메이션의 대상
div.flow-wrap 살펴보기

 

transform:translate3d(0%) 에서 transform:translate3d(-100%) 로 변화 부여

왼쪽으로 흐르니 -100% 이다.

이때, translate3d 를 translateX 로 바꿔도 된다.

단, translate3d 를 사용하면 하드웨어 과속(GPU)을 이용하므로 좀 더 나은 퍼포먼스를 보여준다.


두 애니메이션의 차이점 비교
<!-- 팝업 시작 -->
    <div class="flow-container">
      <div class="flow-text">
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
        <div class="flow-wrap">💖WIGGLE WIGGLE💖</div>
      </div>
    </div>

첫 번째 애니메이션: @keyframes textLoop

이 애니메이션은 텍스트를 오른쪽에서 왼쪽으로 천천히 이동시키는 방식입니다.

텍스트가 흐르는 것처럼 보이게 합니다.

@keyframes textLoop {
  0% {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
  100% {
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }
}

이 애니메이션은 .flow-wrap 요소에 적용되어,

.flow-text 안에 있는 각 텍스트 블록이 독립적으로 애니메이션됩니다.

두 번째 애니메이션: @keyframes marquee

이 애니메이션은 텍스트를 오른쪽에서 왼쪽으로 이동시키지만,

텍스트가 화면을 벗어나기 전에 갑자기 다시 시작 지점으로 돌아갑니다.

@keyframes marquee {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(-100%);
  }
}
  • 0%에서는 텍스트가 오른쪽 끝에 있습니다.
  • 100%에서는 텍스트가 왼쪽 끝으로 이동합니다.

이 애니메이션은 전체 .flow-text 요소에 적용되어 텍스트 전체가 하나의 블록으로 움직이게 됩니다.

코드 차이와 동작 원리

.flow-text {
  display: flex;
  flex: 0 0 auto;
  white-space: nowrap;
  overflow: hidden;
  transition: 0.3s;
  font-size: 2.5rem;
  font-weight: bold;
  color: #9d9993;
}

.flow-wrap {
  animation: textLoop 10s linear infinite;
  padding-right: 1.4881vw;
}
  • .flow-text는 Flex 컨테이너로 설정되어 자식 요소들이 가로로 나열되도록 합니다.
  • .flow-wrap에 textLoop 애니메이션이 적용되어 각 텍스트 블록이 오른쪽에서 왼쪽으로 흐릅니다.

이 설정에서는 .flow-text의 자식 요소 각각에 애니메이션이 적용되므로,

텍스트가 자연스럽게 흐르는 것처럼 보입니다.

@keyframes marquee {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(-100%);
  }
}
  • 이 애니메이션은 .flow-text 요소 전체에 적용되므로,
  • 텍스트가 하나의 블록처럼 움직입니다.
  • 텍스트가 화면을 벗어날 때 갑자기 사라지는 현상이 발생할 수 있습니다.

왜 첫 번째 애니메이션이 더 자연스러운지

  • 첫 번째 애니메이션에서는 .flow-wrap 각각에 textLoop 애니메이션을 적용하여,
  • 텍스트 블록들이 독립적으로 움직입니다.
  • 이로 인해 텍스트가 연속적으로 흘러가는 것처럼 보입니다.
  • 두 번째 애니메이션에서는 전체 텍스트가 하나의 블록으로 움직이기 때문에,
  • 텍스트가 화면을 벗어날 때 갑자기 사라지고 처음 위치로 돌아오는 것처럼 보입니다.

결론

첫 번째 애니메이션 방법 (@keyframes textLoop와 .flow-wrap에 적용된 애니메이션)

각 텍스트 블록이 독립적으로 움직여 자연스러운 흐름을 만들어냅니다.

 

이와 달리 두 번째 방법 (@keyframes marquee와 .flow-text에 적용된 애니메이션)

전체 텍스트가 하나의 블록처럼 움직이기 때문에 갑자기 사라지는 것처럼 보입니다.

 

따라서 전광판 효과를 자연스럽게 만들기 위해서는

각 텍스트 블록에 독립적인 애니메이션을 적용하는 것이 좋습니다.

첫 번째 방법이 더 적합한 이유입니다.


translate3d와 -webkit-transform 속성

 

translate3d 속성

transform: translate3d(x, y, z);

translate3d는 CSS transform 속성의 값으로, 요소를 3D 공간에서 이동시키는 데 사용됩니다.

2D 이동과 달리, translate3d는 X, Y, Z 축을 모두 포함하여 요소를 이동시킵니다.

 

translate3d는 3D 공간에서 요소를 이동시키는 트랜스폼 함수입니다.

이 함수는 세 개의 인수를 받습니다:

  • x: 요소를 수평(가로) 방향으로 이동시키는 거리
  • y: 요소를 수직(세로) 방향으로 이동시키는 거리
  • z: 요소를 z축(깊이) 방향으로 이동시키는 거리
  • translate3d(0, 0, 0)은 요소가 원래 위치에 있는 것을 의미합니다.
  • translate3d(-100%, 0, 0)은 요소를 수평 방향으로 왼쪽으로 100% 이동시키는 것을 의미합니다. 100%는 요소의 너비를 기준으로 합니다.
  • translate3d 함수의 괄호 안에 있는 세 개의 값은 차례로 x축, y축, z축의 이동 거리를 의미합니다.

예제

  • translate3d(0, 0, 0)은 요소를 원래 위치에 그대로 둡니다. 즉, 이동이 없습니다.
  • translate3d(100px, 0, 0)은 요소를 수평 방향으로 100px 오른쪽으로 이동시킵니다.
  • translate3d(0, 50px, 0)은 요소를 수직 방향으로 50px 아래로 이동시킵니다.
  • translate3d(0, 0, 20px)은 요소를 z축 방향으로 20px 앞쪽으로 이동시킵니다 (화면 쪽으로).

-webkit-transform 속성

-webkit-transform은 Webkit 기반의 브라우저(예: Safari, 옛날 버전의 Chrome 등)에서 사용되는

transform 속성의 벤더 프리픽스 버전입니다. 브라우저 호환성을 위해 사용됩니다.

예전에는 브라우저마다 CSS 속성의 구현 방식이 달랐기 때문에,

특정 브라우저에서만 동작하는 CSS 속성에 벤더 프리픽스를 붙여 사용했습니다.

  • -webkit- : Webkit 엔진을 사용하는 브라우저 (예: Safari, Chrome의 초기 버전)
  • -moz- : Mozilla 엔진을 사용하는 브라우저 (예: Firefox)
  • -o- : Opera 브라우저
  • -ms- : Microsoft 브라우저 (예: Internet Explorer)

현대의 대부분의 브라우저는 표준을 잘 준수하기 때문에 벤더 프리픽스가 필요 없지만,

여전히 일부 구형 브라우저 지원을 위해 사용하는 경우가 있습니다.

애니메이션이 시작할 때 요소를 원래 위치에 두고, 끝날 때 요소를 왼쪽으로 100% 이동시킵니다.

-webkit-transform을 추가하여 Webkit 기반 브라우저에서도 동일하게 동작하도록 합니다.

요약

  • transform: translate3d(x, y, z); : 요소를 3D 공간에서 이동시키는 트랜스폼 함수입니다.
  • -webkit-transform : Webkit 기반 브라우저에서 transform 속성을 지원하기 위한 벤더 프리픽스입니다.
  • translate3d(0, 0, 0)은 원래 위치, translate3d(-100%, 0, 0)은 수평으로 왼쪽으로 100% 이동을 의미합니다.

이제 translate3d와 -webkit-transform 속성이 어떤 역할을 하는지 이해하셨을 겁니다. 벤더 프리픽스는 구형 브라우저 호환성을 위해 필요하며, translate3d는 요소를 3D 공간에서 이동시키는 데 사용됩니다.


첫 번째 코드 (textLoop) 와 두 번째 코드 (marquee) 비교

 

두 코드가 동일하게 움직이는 이유는 최종 이동 결과가 동일하기 때문입니다.

두 애니메이션 모두 0%에서는 요소를 원래 위치에 두고,

100%에서는 요소를 왼쪽으로 100% 이동시키기 때문에 결과적으로 동일한 애니메이션 효과를 나타냅니다.

 

코드 비교

첫 번째 코드 (textLoop)

@keyframes textLoop {
  0% {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
  100% {
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }
}

 

  • 0%에서 요소는 원래 위치에 있습니다.
  • 100%에서 요소는 수평으로 왼쪽으로 100% 이동합니다.

두 번째 코드  (marquee)

@keyframes marquee {
  0% {
    transform: translateZ(0); /* 하드웨어 가속을 위해 사용, 요소의 위치 변화 없음 */
  }
  100% {
    transform: translate3d(-100%, 0, 0); /* 요소를 수평으로 왼쪽으로 100% 이동 */
  }
}
  • 0%에서 요소는 이동하지 않고 원래 위치에 있습니다 (translateZ(0)은 위치 변화를 주지 않음).
  • 100%에서 요소는 수평으로 왼쪽으로 100% 이동합니다.

동일한 움직임의 이유

  1. 초기 상태 (0%):
    • 두 코드 모두 요소를 원래 위치에 둡니다. 첫 번째 코드에서는 translate3d(0, 0, 0)을 사용하고,
    • 두 번째 코드에서는 translateZ(0)을 사용하여 요소의 위치를 변화시키지 않습니다.
  2. 최종 상태 (100%):
    • 두 코드 모두 요소를 수평 방향으로 왼쪽으로 100% 이동시킵니다.
    • 첫 번째 코드에서는 translate3d(-100%, 0, 0)을 사용하고,
    • 두 번째 코드에서도 translate3d(-100%, 0, 0)을 사용합니다.

결론

두 애니메이션 모두 동일한 0%와 100% 상태를 가지고 있으며,

최종적으로 요소를 동일하게 이동시키므로 결과적으로 동일한 애니메이션 효과를 갖습니다.

translateZ(0)은 하드웨어 가속을 위해 사용될 뿐,

실제 요소의 위치에는 변화를 주지 않으므로 최종 애니메이션 결과에 영향을 미치지 않습니다.

따라서 두 코드의 애니메이션은 시각적으로 동일하게 보입니다.

728x90