Post

hexcode에 opacity 작성하기

🎁 color 작업하기

컴포넌트를 제작하다 보면 특정 color에 opacity를 조절해야 하는 상황이 있다.
물론 className을 이용하는 상황이라면, Tailwind CSS 작성 방식대로, 다음과 같이 간편하게 지정해 줄 수 있다.

1
<div className="bg-lime-100/70"></div>

하지만 문제는, 내가 직접 컬러 hex 값을 정의해서 사용하는 상황이다. 예를 들어 나는 chart.js를 사용해 차트를 만들려고 할 때, tailwind.config.js에 정의해둔 동일한 lime 컬러를 사용하고 싶었다.

이때 hex값을 직접 chart 내부에서 작성해도 되지만, 다음과 같은 단점이 있었다.

  • 재사용성이 떨어짐
  • 오타 가능성
  • 디자인 시스템과 색상 불일치 위험

그래서 나는 아예 별도의 색상 정의 파일을 만들고, 필요한 곳에서 불러다 쓰는 방식을 택했다.

1
2
3
4
5
6
7
8
export const lime = {
  50: "#fbffe6",
  100: "#f3ffc8",
  200: "#e7fe98",
  300: "#d2fa5c",
  400: "#c4f244",
  500: "#9dd70b",
}

chart.js 내부에서는 다음과 같이 작성했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const data = {
  labels,
  datasets: [
    {
      label: "CNY",
      data: values,
      fill: "start",
      borderColor: lime["500"],
      borderWidth: 1,
      // tension: 0.3,
      pointRadius: 0,
      pointBackgroundColor: lime["400"],
      backgroundColor: (context: ScriptableContext<"line">) => {
        const chart = context.chart
        const { ctx, chartArea } = chart
        if (!chartArea) return undefined

        const gradient = ctx.createLinearGradient(
          0,
          chartArea.top,
          0,
          chartArea.bottom
        )
        gradient.addColorStop(0, lime["400"]) //❓그라데이션 적용을 어떻게 할까?
        gradient.addColorStop(1, lime["400"]) //❓그라데이션 적용을 어떻게 할까?
        return gradient
      },
    },
  ],
}

🤔 hex코드와 opacity

chart.js에서는 backgroundColor를 지정하면서, 자연스러운 그라디언트 효과를 만들고 싶었는데, color.tstailwind.config.js에 작성한 hex 방식으로 써 두었기 때문에 opacity 조정을 어떻게 하면 좋을지 난감했다.

그냥 내가 직접 rgba()값으로 변경해 바로 작성할까 생각했지만, 기존 hex값이랑 분리되면 관리가 복잡해지고 색상 시스템을 통일하기 어렵기에, hexCode에 opacity 적용이 가능하지 않을까 생각했고, 원래 쓰던 6자리의 hex코드에 두 자리를 더 붙이기만 하면 opacity 지정이 가능한 걸 알게 되었다! 😲

🎨 hex코드에 opacity 추가하기

hex코드에 10 단위로 opacity를 지정하는 방식을 정리해보면 다음과 같다.

alpha 값을 기존 6자리 뒤에 더해주면 된다.

투명도alpha(hex)
100FF
90E6
80CC
70B3
6099
5080
4066
304D
2033
101A
000

이 값을 활용해 아래와 같이 opacity를 적용해주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const data = {
  labels,
  datasets: [
    {
      label: "CNY",
      data: values,
      fill: "start",
      borderColor: lime["500"],
      borderWidth: 1,
      // tension: 0.3,
      pointRadius: 0,
      pointBackgroundColor: lime["400"],
      backgroundColor: (context: ScriptableContext<"line">) => {
        const chart = context.chart
        const { ctx, chartArea } = chart
        if (!chartArea) return undefined

        const gradient = ctx.createLinearGradient(
          0,
          chartArea.top,
          0,
          chartArea.bottom
        )
        gradient.addColorStop(0, lime["400"] + "80") //🌟 opacity 50
        gradient.addColorStop(1, lime["400"] + "00") //🌟 opacity 0
        return gradient
      },
    },
  ],
}

🔄hex to rgba

그럼 rgba로 만들어야 하는 상황이 올 때는 어떻게 할까? 이때는 hex를 rgba로 바꾸는 함수를 사용해보자.

먼저 hex와 rgba의 차이점을 생각해보자.

  • hex: red, green, blue를 16진수로 표현
  • rgb: red, green, blue를 10진수로 표현

즉, hex코드를 두 글자씩 나눈 다음, 각각을 10진수로 변환해서 rgb() 형태로 만들어주면 된다.

1
2
3
4
5
6
export const hexToRgba = (hex: string, alpha: number): string => {
  const r = parseInt(hex.slice(1, 3), 16)
  const g = parseInt(hex.slice(3, 5), 16)
  const b = parseInt(hex.slice(5, 7), 16)
  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

🗂️참고 사이트

This post is licensed under CC BY 4.0 by the author.