CSS 그라디언트 기초 — 각도와 색 정지점을 정확히 읽는 법

각도를 넣었는데 방향이 예상과 다르다

linear-gradient(90deg, red, blue)를 썼는데 위아래가 아니라 좌우로 색이 바뀝니다. 각도를 0으로 바꾸면 아래에서 위로 올라갑니다. 시계처럼 12시가 0도인 것 같기도 하고 아닌 것 같기도 합니다.

그라디언트는 값 몇 개만 넣으면 되는 것처럼 보이지만, 각도의 기준과 정지점의 규칙을 모르면 매번 숫자를 바꿔가며 맞춰보게 됩니다. 이 두 가지만 잡으면 원하는 모양을 한 번에 만들 수 있습니다.

그라디언트는 색이 아니라 이미지다

먼저 짚고 갈 것이 있습니다. 그라디언트는 CSS에서 색이 아니라 이미지로 취급됩니다.

/* ✗ 동작하지 않는다 — color 속성은 색만 받는다 */
color: linear-gradient(90deg, red, blue);

/* ✓ background는 이미지를 받는다 */
background: linear-gradient(90deg, red, blue);

그래서 background-image, border-image, mask-image처럼 이미지를 받는 자리에는 들어가지만, color나 border-color에는 쓸 수 없습니다.

이미지라는 사실에서 따라오는 성질이 하나 더 있습니다. 크기가 요소에 맞춰 늘어납니다. background-size로 크기를 정할 수 있고, 지정하지 않으면 요소를 가득 채웁니다. 이 성질이 나중에 줄무늬 패턴을 만들 때 쓰입니다.

linear-gradient — 각도의 기준

각도는 그라디언트가 끝나는 방향을 가리킵니다. 그리고 0도가 위쪽이며 시계 방향으로 돕니다.

각도 방향 같은 표현
0deg 아래 → 위 to top
90deg 왼쪽 → 오른쪽 to right
180deg 위 → 아래 to bottom
270deg 오른쪽 → 왼쪽 to left

헷갈리기 쉬운 지점은 두 가지입니다.

기본값이 180deg입니다. 각도를 생략하면 위에서 아래로 흐릅니다. 수학에서 각도를 다룰 때와 시작점이 다르므로, 삼각함수를 떠올리면 오히려 틀립니다.

각도는 도착점을 가리킵니다. 0deg는 “위에서 시작”이 아니라 “위에서 끝남”입니다. 그래서 첫 번째 색이 아래쪽, 마지막 색이 위쪽에 놓입니다.

방향만 필요하다면 to top, to bottom right 같은 키워드가 읽기 쉽습니다. 다만 키워드는 여덟 방향뿐이라, 그 사이 각도가 필요하면 deg를 씁니다.

색 정지점 — 위치를 적을 때와 비울 때

정지점은 색과 위치의 쌍입니다. 위치는 백분율이나 길이로 적습니다.

linear-gradient(90deg, red 0%, yellow 50%, blue 100%)

위치를 비우면 브라우저가 규칙에 따라 채웁니다.

  • 첫 정지점은 0%, 마지막은 100%
  • 중간 정지점들은 그 사이에 고르게 나뉩니다
/* 아래 둘은 완전히 같다 */
linear-gradient(90deg, red, yellow, blue)
linear-gradient(90deg, red 0%, yellow 50%, blue 100%)

정지점이 넷이면 0%, 33.3%, 66.7%, 100%가 됩니다. 그래서 색을 고르게 배치할 거라면 위치를 아예 쓰지 않는 편이 낫습니다. 나중에 색을 하나 추가해도 간격이 알아서 다시 나뉩니다.

같은 위치에 두 정지점을 두면

이건 알아두면 쓸모가 많습니다. 두 정지점의 위치를 같게 주면 그 지점에서 색이 섞이지 않고 딱 잘립니다.

/* 왼쪽 절반은 빨강, 오른쪽 절반은 파랑 — 경계가 선명하다 */
linear-gradient(90deg, red 50%, blue 50%)

그라디언트인데 그라디언트가 아닌 셈입니다. 이 성질로 줄무늬, 눈금, 진행 막대 같은 것을 이미지 없이 만들 수 있습니다.

위치가 거꾸로 적히면

앞 정지점보다 작은 값을 적으면 무시되지 않고 앞 값으로 올려서 처리됩니다.

linear-gradient(90deg, red 60%, blue 30%)
/* blue의 30%는 60%로 취급된다 → 60%에서 딱 잘린 경계가 된다 */

의도한 게 아니라면 값을 잘못 적은 것이니, 결과가 이상하면 정지점 순서를 먼저 확인하세요.

radial-gradient — 가운데에서 퍼진다

radial에는 각도가 없습니다. 가운데에서 바깥으로 퍼지는 모양이라 방향이라는 개념이 없기 때문입니다. 대신 모양·크기·중심을 정합니다.

radial-gradient(circle at center, white, black)
radial-gradient(ellipse at top left, white, black)
  • 모양 — circle(정원) 또는 ellipse(타원). 기본은 ellipse라 요소가 가로로 길면 그라디언트도 늘어납니다
  • 중심 — at 뒤에 위치. 기본은 center
  • 크기 — closest-side, farthest-corner 등. 기본은 farthest-corner로, 가장 먼 모서리에서 마지막 색에 도달합니다

정원으로 보이길 원한다면 circle을 명시해야 합니다. 기본값인 ellipse는 요소 비율을 따라가서, 가로로 긴 카드에서는 옆으로 늘어난 타원이 됩니다.

conic-gradient — 원을 따라 돈다

conic은 색이 중심을 기준으로 각도를 따라 바뀝니다. 원뿔을 위에서 내려다본 모양이라 이름이 그렇습니다.

conic-gradient(from 0deg, red, yellow, green, red)
  • 시작 각도 — from 뒤에 적습니다. 기본은 12시 방향
  • 정지점 위치 — 백분율 대신 각도(deg)로도 적을 수 있습니다

파이 차트가 이것으로 만들어집니다. 같은 위치에 정지점을 두 개 두는 기법을 합치면 경계가 뚜렷한 조각이 나옵니다.

/* 40% / 35% / 25% 파이 차트 */
background: conic-gradient(
  #b4480a 0deg 144deg,
  #f5b301 144deg 270deg,
  #1a7f37 270deg 360deg
);
border-radius: 50%;

정지점 하나에 시작·끝 각도를 함께 적는 축약형입니다. 색상환을 만들 때도 같은 방식을 씁니다.

두 색 사이가 탁해지는 이유

그라디언트를 만들었는데 중간에 회색빛 띠가 생긴 경험이 있을 것입니다. 파랑에서 노랑으로 가는 그라디언트가 특히 그렇습니다.

브라우저가 두 색 사이를 채우는 방식은 단순합니다. 양쪽 색의 R·G·B 값을 각각 직선으로 이어서 중간값을 계산합니다.

파랑 rgb(0, 0, 255)  →  노랑 rgb(255, 255, 0)

중간 지점: R=(0+255)/2=128, G=(0+255)/2=128, B=(255+0)/2=128
        → rgb(128, 128, 128) — 회색

중간이 정확히 회색이 됩니다. 두 색을 잇는 직선이 하필 무채색 지점을 지나가기 때문입니다. 보색에 가까운 색끼리 이을수록 이 현상이 뚜렷합니다.

해결책은 중간에 정지점을 하나 더 넣는 것입니다. 채도가 살아 있는 중간색을 직접 골라 넣으면 회색 지대를 피해 갑니다.

/* ✗ 중간이 회색 */
linear-gradient(90deg, #0000ff, #ffff00)

/* ✓ 중간에 초록을 거쳐 간다 */
linear-gradient(90deg, #0000ff, #00b3a4 50%, #ffff00)

어떤 색을 넣을지는 색 변환기로 두 색의 색상(H) 값을 확인하고 그 중간 각도의 색을 골라 보면 감이 잡힙니다.

transparent로 사라지게 만들 때는 사정이 조금 다릅니다. transparent는 사실 투명한 검정(rgba(0, 0, 0, 0))입니다. 예전 브라우저는 이 검정을 그대로 섞어서 흰색에서 transparent로 갈 때 중간이 회색으로 떴습니다. 지금은 브라우저가 알파를 미리 곱해서 계산하기 때문에 이 현상은 나타나지 않습니다. 널리 인용되는 이야기지만 이제는 옛말입니다.

그래도 같은 색의 투명한 버전(rgb(255 255 255 / 0))으로 끝내는 편이 낫습니다. 어떤 색에서 사라지는지가 코드에 그대로 드러나기 때문입니다.

요약

  • 그라디언트는 색이 아니라 이미지다. background에는 되지만 color에는 안 된다
  • linear의 각도는 0도가 위, 시계 방향이고 도착 방향을 가리킨다. 기본값은 180deg
  • 정지점 위치를 비우면 브라우저가 고르게 나눈다. 고르게 둘 거면 아예 쓰지 않는 게 낫다
  • 두 정지점을 같은 위치에 두면 경계가 딱 잘린다. 줄무늬·차트의 원리
  • radial에는 각도가 없다. 정원을 원하면 circle을 명시해야 한다
  • conic은 정지점을 각도로 적을 수 있다. 파이 차트가 여기서 나온다
  • 중간이 탁해지는 것은 RGB를 직선으로 잇기 때문이다. 중간 정지점을 넣어 피한다