기록

CSS 연습 - button 05

als982001 2023. 6. 27. 22:53

1. 구현할 것

https://uiverse.io/satyamchaudharydev/curvy-rat-14

 

Button by satyamchaudharydev

This Button was posted by satyamchaudharydev. Made with CSS. You can create your own elements by signing in with GitHub.

uiverse.io

 

 이번에 구현할 버튼이다. 마우스를 올렸을 때, 여러 색이 오른쪽으로 움직이는 애니메이션이 신기해서 이 버튼을 선택하였다. 구현해야 할 것은 다음과 같다.

  • 버튼의 기본 스타일
  • hover일 때의 스타일

 

2. 버튼 구현

2-1. 버튼의 기본 스타일

import styled from "styled-components";
import Container from "../Container";

const MyButton = styled.button`
  width: 150px;
  height: 50px;
  background-color: #41bf57;
  color: white;
  font-size: 20px;
  font-weight: bold;
  border-radius: 10px;
  border: none;
  outline: none;
`;

export default function Button05() {
  return (
    <Container>
      <MyButton>Join now</MyButton>
    </Container>
  );
}

버튼의 기본 모양은 크게 어렵지 않았다. width, height, background-color의 값은 적당히 측정한 값을 이용하였다. 그리고 border, outline을 none으로 설정해 버튼을 감싸는 선을 보이지 않게 했다. 다음은 hover일 때의 버튼이다.

 

2-2. hover일 때의 스타일

import styled from "styled-components";
import Container from "../Container";

const MyButton = styled.button`
  width: 150px;
  height: 50px;
  background-color: #41bf57;
  color: white;
  font-size: 20px;
  font-weight: bold;
  border-radius: 10px;
  border: none;
  outline: none;
  transition: all 0.5s;

  @keyframes movingBg {
    0% {
      background: linear-gradient(
        90deg,
        purple,
        navy,
        blue,
        green,
        yellow,
        orange,
        red
      );
    }
    14% {
      background: linear-gradient(
        90deg,
        red,
        purple,
        navy,
        blue,
        green,
        yellow,
        orange
      );
    }
    28% {
      background: linear-gradient(
        90deg,
        orange,
        red,
        purple,
        navy,
        blue,
        green,
        yellow
      );
    }
    42% {
      background: linear-gradient(
        90deg,
        yellow,
        orange,
        red,
        purple,
        navy,
        blue,
        green
      );
    }
    56% {
      background: linear-gradient(
        90deg,
        green,
        yellow,
        orange,
        red,
        purple,
        navy,
        blue
      );
    }
    70% {
      background: linear-gradient(
        90deg,
        blue,
        green,
        yellow,
        orange,
        red,
        purple,
        navy
      );
    }
    84% {
      background: linear-gradient(
        90deg,
        navy,
        blue,
        green,
        yellow,
        orange,
        red,
        purple
      );
    }
    100% {
      background: linear-gradient(
        90deg,
        purple,
        navy,
        blue,
        green,
        yellow,
        orange,
        red
      );
    }
  }

  &:hover {
    scale: 1.2;
    animation: movingBg 0.5s infinite;
  }
`;

export default function Button05() {
  return (
    <Container>
      <MyButton>Join now</MyButton>
    </Container>
  );
}

 일단 hover일 때의 스타일에서 신경써야 할 부분은 버튼이 조금 커지는 것과 배경의 색을 움직이게 하는 것이다. 버튼이 커지는 것은 scale을 적용하면 된다지만, 배경을 7가지 색(무지개색)으로 나눈 후 오른쪽으로 움직이게 하는 방법은 keyframes를 이용해 각 구간의 색을 일일이 지정해주는  방법밖에 생각이 나지 않았다. 그래서 0%부터 100%까지 7개로 나눈 후, 각 구간마다 색의 위치를 바꿔주었다. 그리고 animation을 이용해 색이 움직이게 했다. 시간은 0.5초로 주었는데 이는 끊겨보이지 않으려고 값을 작게 주었다. 처음에는 2초정도로 설정했었는데 너무 끊겨보였었다. 그리고 infinite를 통해 무한히 색이 움직이도록 했다.

 하지만 이는 만족스럽지 못한 결과이다. 왜냐하면 샘플의 버튼은 색이 정확히 구분되어 있지만, 내가 작성한 코드는 linear-gradient를 이용했기에 색이 정확히 구분되어 있지 않다. 그리고 뭔가 keyframes를 이용하지 않았을 것 같은 느낌이 들었다. 

 

3. 분석

import styled from "styled-components";
import Container from "../Container";

const SampleButton = styled.button`
  --width: 150px;
  --timing: 2s;
  border: 0;
  width: var(--width);
  padding-block: 1em;
  color: #fff;
  font-weight: bold;
  font-size: 1em;
  background: rgb(64, 192, 87);
  transition: all 0.2s;
  border-radius: 3px;

  @keyframes dance6123 {
    to {
      background-position: var(--width);
    }
  }

  &:hover {
    background-image: linear-gradient(
      to right,
      rgb(250, 82, 82),
      rgb(250, 82, 82) 16.65%,
      rgb(190, 75, 219) 16.65%,
      rgb(190, 75, 219) 33.3%,
      rgb(76, 110, 245) 33.3%,
      rgb(76, 110, 245) 49.95%,
      rgb(64, 192, 87) 49.95%,
      rgb(64, 192, 87) 66.6%,
      rgb(250, 176, 5) 66.6%,
      rgb(250, 176, 5) 83.25%,
      rgb(253, 126, 20) 83.25%,
      rgb(253, 126, 20) 100%,
      rgb(250, 82, 82) 100%
    );
    animation: var(--timing) linear dance6123 infinite;
    transform: scale(1.1) translateY(-1px);
  }
`;

export default function Button05() {
  return (
    <>
      <Container>
        <SampleButton>Join now</SampleButton>
      </Container>
    </>
  );
}

 hover일 때, background-image를 통해 7가지 무지개 색을 보여주고 있다. linear-gradient에서 to right를 통해 색이 오른쪽 방향으로 나열되게 하였으며, 같은 색을 두 번씩 적용해 linear-gradient에서 색이 번져보이는 것을 방지한 것으로 보인다. 그리고 animation의 경우, background-position을 통해 오른쪽으로 움직이는 애니메이션을 구현하였다. background-position에 대해 몰랐기에 여러모로 적용하며 무슨 작용을 하는 속성인지 알아보았다. background-position에 값을 설정해주면, 설정해준 값만큼 이동하게 된다. 양수를 입력할 경우는 오른쪽으로, 음수를 입력할 경우는 왼쪽으로 이동하게 된다. 그리고 오른쪽으로 이동해서 범위를 벗어난 경우, 왼쪽에서 모습을 보이게 된다. 그렇기에 이를 응용하면 무한히 움직이는 모습을 구현할 수 있다. 위의 코드에서는 background-position: var(--width); 로 적용을 했는데, 이것만 본다면 버튼의 가로 길이와 같기에 버튼의 원래 모습과 같게 된다. 하지만 이것을 animation을 적용해줌으로서 오른쪽으로 천천히 움직여서 원래 배경으로 돌아오게 했다. 그리고 infinite를 통해 무한히 움직이게 하였다.

 다른 사람의 코드를 보고 분석하는 것만으로도 배우는 것이 많다는 것을 느낀다. 가만히 생각해보니  background-position는 배경의 이미지를 가운데에 고정시키는 데에만 이용했었던 게 떠올랐다.(background-position: center;) 그래서 background-position을 통해 애니메이션을 구현할 수 있다는 것에 감명을 받았다.