본문 바로가기

HTML_CSS_Sample

원형 그라데이션 테두리 회전(Circle Gradation Border Rotation) 효과

HTMLCSS만을 이용하여, 원형 그라데이션 테두리(Circle Gradation Border)을 표현하고 애니메이션(Animation)을 추가한 효과를 만들어 보자.

결과물 미리 보기

 

HTML 구성

HTML 요소들을 아래와 같이 구성한다.

<div class="container">
  <h1>Circle Gradient Border Rotation</h1>
  <div class="circle"></div>
</div>

HTML 구성 결과 화면
HTML 구성 결과 화면

Flexbox 레이아웃을 이용한 중앙정렬

스타일시트(CSS)의 플렉스박스(Flexbox) 레이아웃(Layout)을 아래와 같이 지정하여 컨테이너 요소(.container)가 중앙정렬(수직 방향과 수평 방향 모두 중앙정렬) 되도록 한다.

body {
  margin: 0;
  padding: 0;
  color: #efefef;
  background-color: #333333;
}

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  height: 100vh;
}

컨테이너 요소가 중앙정렬 된 결과 화면
컨테이너 요소가 중앙정렬 된 결과 화면

타이틀 중앙정렬 및 테두리 추가

타이틀 수직 방향 중앙정렬을 위해 h1 요소에 플렉스박스(Flexbox) 레이아웃(Layout)을 적용하고 타이틀도형이 겹쳐 보이도록 위치(position)를 절대좌표(absolute)로 지정한다. left 속성과 transform 속성을 이용하여 타이틀을 수평 방향으로 중앙정렬한다. .circle 요소의 사이즈(width, height) 및 테두리(border)를 적용한다.

/* ... 생략 ... */

.container h1 {
  display: flex;
  position: absolute;
  left: 50%;
  flex-direction: column;
  justify-content: center;
  width: 24rem;
  height: 24rem;
  margin: 0;
  font: 100 3rem/1.2 "Helvetica Neue", Helvetica, Arial, sans-serif;
  text-align: center;
  transform: translateX(-50%);
}

.circle {
  box-sizing: border-box;
  width: 24rem;
  height: 24rem;
  border: 1px solid;
}

타이틀 중앙정렬 및 테두리 추가 결과 화면
타이틀 중앙정렬 및 테두리 추가 결과 화면

테두리 그라데이션 효과

스타일시트(CSS) image-image 속성의 linear-gradient를 사용할 경우 테두리(border)만 그라데이션(Gradation) 효과가 적용되는 것이 아니라 배경 전체그라데이션(Gradation)이 적용된다. 물론, image-image 속성의 linear-gradient 중첩 사용과 background-clip 속성 및 background-origin 속성들을 이용하여 테두리(border)만 그라데이션(Gradation)이 적용된 것처럼 효과를 낼 수 있지만 내부이나 그라데이션(Gradation)으로 채워지게 된다.

위에서 스타일시트(CSS) .circle 선택자에 적용한 테두리 속성 border 대신, box-shadow 속성의 X offsetY offset을 사용하여 테두리표현한다.

/* ... 생략 ... */

.circle {
  box-sizing: border-box;
  width: 24rem;
  height: 24rem;
  box-shadow:
    0 -1px 0 0 rgba(255, 64, 0, 1), /* Top Border */
    1px 0 0 0 rgba(255, 192, 0, 1), /* Right Border */
    0 1px 0 0 rgba(255, 192, 0, 1), /* Bottom Border */
    -1px 0 0 0 rgba(255, 64, 0, 1); /* Left Border */
}

/* ... 생략 ... */

그림자(box-shadow) 효과를 이용한 테두리가 적용된 결과 화면
그림자(box-shadow) 효과를 이용한 테두리가 적용된 결과 화면

위와 같이 box-shadow 속성의 X offsetY offset을 사용하여 각각의 테두리(Top, Right, Bottom, Left)를 표현할 수도 있으며, 동시(Top+Left, Right+Bottom 또는 Top+Right, Bottom+Left)에 적용할 수도 있다.

 

box-shadow: [<Type>] <X offset> <Y offset> [<Blur Radius>] [<Spread Radius>] [<Color>];

 

box-shadow 속성의 X offsetY offset를 이용하여 한 테두리 표현은 아래와 같은 방식으로 지정할 수 있다.

  • box-shadow: 0 -1px 0 0 rgba(255, 0, 0, 0);Top Border
  • box-shadow: 1px 0 0 0 rgba(255, 0, 0, 0);`Right Border
  • box-shadow: 0 1px 0 0 rgba(255, 0, 0, 0);`Bottom Border
  • box-shadow: -1px 0 0 0 rgba(255, 0, 0, 0);`Left Border
  • box-shadow: 1px -1px 0 0 rgba(255, 0, 0, 0);`Top Border, Right Border
  • box-shadow: -1px 1px 0 0 rgba(255, 0, 0, 0);`Bottom Border, Left Border
  • box-shadow: 1px 1px 0 0 rgba(255, 0, 0, 0);`Right Border, Bottom Border
  • box-shadow: -1px -1px 0 0 rgba(255, 0, 0, 0);`Top Border, Left Border

Type의 기본값은 outset이며, inset으로 지정할 경우 위 방향과 반대 방향으로 테두리가 그려지게 된다.

아래의 스타일시트(CSS)는 box-shadow색상투명도(rgba의 Alpha 값)를 적용하고 모든 경우의 테두리를 사용한 경우이다.

/* ... 생략 ... */

.circle {
  box-sizing: border-box;
  width: 24rem;
  height: 24rem;
  box-shadow:
    0 -1px 0 0 rgba(255, 64, 0, 0.25), /* Top Border */
    1px 0 0 0 rgba(255, 192, 0, 0.25), /* Right Border */
    0 1px 0 0 rgba(255, 192, 0, 0.25), /* Bottom Border */
    -1px 0 0 0 rgba(255, 64, 0, 0.25), /* Left Border */
    1px -1px 0 0 rgba(255, 128, 0, 0.5), /* Top Right Border */
    -1px 1px 0 0 rgba(255, 128, 0, 0.5), /* Bottom Left Border */
    -1px -1px 0 0 rgba(255, 0, 0, 0.75), /* Top Left Border */
    1px 1px 0 0 rgba(255, 255, 0, 0.75); /* Right Bottom Border */
}

/* ... 생략 ... */

그림자(box-shadow) 효과를 이용한 테두리가 적용된 결과 화면
그림자(box-shadow) 효과를 이용한 테두리가 적용된 결과 화면

원형 테두리로 변경

스타일시트(CSS)의 border-radius 속성을 이용하여 원형으로 변경한다.

/* ... 생략 ... */

.circle {
  box-sizing: border-box;
  width: 24rem;
  height: 24rem;
  border-radius: 50%;
  box-shadow:
    0 -1px 0 0 rgba(255, 64, 0, 0.25),
    1px 0 0 0 rgba(255, 192, 0, 0.25),
    0 1px 0 0 rgba(255, 192, 0, 0.25),
    -1px 0 0 0 rgba(255, 64, 0, 0.25),
    1px -1px 0 0 rgba(255, 128, 0, 0.5),
    -1px 1px 0 0 rgba(255, 128, 0, 0.5),
    -1px -1px 0 0 rgba(255, 0, 0, 0.75),
    1px 1px 0 0 rgba(255, 255, 0, 0.75);
}

/* ... 생략 ... */

border-radius 속성을 이용하여 원형으로 변경된 결과 화면
border-radius 속성을 이용하여 원형으로 변경된 결과 화면

회전 애니메이션 적용

스타일시트(CSS)의 @keyframes 키워드를 이용하여 회전 키프레임들을 생성하고, animation 속성을 이용하여 1초(1s)에 한 바퀴 회전(transform: rotate(360deg))하는 애니메이션을 무한반복(infinite)시킨다.

회전 애니메이션이 적용된 결과 화면
회전 애니메이션이 적용된 결과 화면

원형 테두리 추가 및 각각 다른 색상의 그라데이션 적용

3개의 원형(Circle) 테두리(Border)가 교차되면서 애니메이션(Animation) 되도록 하기 위해 HTML원형 요소(.circle)들을 추가한다.

<div class="container">
  <h1>Circle Gradient Border Rotation</h1>
  <div class="circles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
  </div>
</div>

3개의 원형(Circle) 테두리(Border)에 각각 다른 색상의 그라데이션(Gradation)을 적용한다.

/* ... 생략 ... */

.circles {
  position: relative;
  width: 24rem;
  height: 24rem;
}

.circle {
  position: absolute;
  box-sizing: border-box;
  width: 24rem;
  height: 24rem;
  border-radius: 50%;
  animation: rotation 1s linear infinite;
}

.circle:nth-of-type(1) {
  left: -1rem;
  box-shadow:
    0 -1px 0 0 rgba(255, 64, 0, 0.25),
    1px 0 0 0 rgba(255, 192, 0, 0.25),
    0 1px 0 0 rgba(255, 192, 0, 0.25),
    -1px 0 0 0 rgba(255, 64, 0, 0.25),
    1px -1px 0 0 rgba(255, 128, 0, 0.5),
    -1px 1px 0 0 rgba(255, 128, 0, 0.5),
    -1px -1px 0 0 rgba(255, 0, 0, 0.75),
    1px 1px 0 0 rgba(255, 255, 0, 0.75);
}

.circle:nth-of-type(2) {
  left: 0;
  box-shadow:
    0 -1px 0 0 rgba(165, 181, 222, 0.25),
    1px 0 0 0 rgba(225, 131, 194, 0.25),
    0 1px 0 0 rgba(225, 131, 194, 0.25),
    -1px 0 0 0 rgba(165, 181, 222, 0.25),
    1px -1px 0 0 rgba(195, 156, 208, 0.5),
    -1px 1px 0 0 rgba(195, 156, 208, 0.5),
    -1px -1px 0 0 rgba(135, 206, 235, 0.75),
    1px 1px 0 0 rgba(255, 105, 180, 0.75);
}

.circle:nth-of-type(3) {
  left: 1rem;
  box-shadow:
    0 -1px 0 0 rgba(214, 69, 99, 0.25),
    1px 0 0 0 rgba(192, 63, 153, 0.25),
    0 1px 0 0 rgba(192, 63, 153, 0.25),
    -1px 0 0 0 rgba(214, 69, 99, 0.25),
    1px -1px 0 0 rgba(203, 66, 126, 0.5),
    -1px 1px 0 0 rgba(203, 66, 126, 0.5),
    -1px -1px 0 0 rgba(225, 72, 71, 0.75),
    1px 1px 0 0 rgba(181, 59, 180, 0.75);
}

/* ... 생략 ... */

원형 테두리를 추가하고 각각 다른 그라데이션을 적용한 결과 화면
원형 테두리를 추가하고 각각 다른 그라데이션을 적용한 결과 화면

교차 애니메이션 적용

각각의 원형(Circle) 테두리(Border) 애니메이션(Animation)이 교차되도록 애니메이션 지연 시간(animation-delay)을 다르게 지정하고, 애니메이션 프레임에서 위치(translate)를 변경한다.

/* ... 생략 ... */

.circle:nth-of-type(1) {
  box-shadow:
    /* ... 생략 ... */;
  animation: rotation 2s linear infinite;
}

.circle:nth-of-type(2) {
  box-shadow:
    /* ... 생략 ... */;
  animation: rotation 2s linear 0.1s infinite;
}

.circle:nth-of-type(3) {
  box-shadow:
    /* ... 생략 ... */;
  animation: rotation 2s linear 0.25s infinite;
}

@keyframes rotation {
  0% {
    transform: rotate(0deg) translate(0, 0);
  }
  33% {
    transform: rotate(360deg) translate(0.375rem, 0.375rem);
  }
  66% {
    transform: rotate(720deg) translate(-0.375rem, -0.375rem);
  }
  100% {
    transform: rotate(1080deg) translate(0, 0);
  }
}

/* ... 생략 ... */

3개의 원형 그라데이션 테두리에 교차 애니메이션이 적용된 결과 화면
3개의 원형 그라데이션 테두리에 교차 애니메이션이 적용된 결과 화면