CSS 그라디언트 실전 — 이미지 없이 만드는 것들
각도 기준과 정지점 규칙은 CSS 그라디언트 기초에서 다뤘습니다. 이번 편은 “그래서 무엇을 만들 수 있느냐”입니다.
그라디언트가 이미지를 대신할 수 있는 곳
그라디언트는 CSS가 그리는 이미지입니다. 그래서 파일을 하나도 요청하지 않고 배경 무늬를 만들 수 있습니다. 요소 크기에 맞춰 늘어나고, 확대해도 깨지지 않으며, 색을 CSS 변수로 바꿀 수 있습니다.
- 잘 맞는 곳 — 줄무늬·격자 같은 규칙적인 무늬, 테두리 장식, 사진 위에 얹는 어두운 막, 구분선, 스켈레톤 로딩의 반짝임
- 안 맞는 곳 — 불규칙한 질감, 사진, 로고. 정지점을 수십 개 쌓아 그림을 그리는 것보다 SVG나 이미지 파일이 낫습니다
저도 처음에는 배경을 이미지로 만들어 넣었습니다. 배경 디자인이 확정되기 전에 화면부터 만들어야 했는데, 수정이 오갈 때마다 이미지를 다시 만들어 교체해야 했습니다. 그걸 본 사수가 이미지로 하지 말고 그라디언트 생성기로 배경을 만들어 넣어 두라고 했고, 그 뒤로는 그렇게 넣어 둡니다. 아직 바뀔 여지가 많은 배경일수록 파일보다 CSS 값으로 두는 편이 고치기 쉽습니다.
실전 1: 줄무늬와 패턴
기초편에서 다룬 “같은 위치에 정지점 두 개” 규칙을 반복하면 줄무늬가 됩니다.
repeating-linear-gradient는 그 반복을 대신해 줍니다.
/* 12px 주황, 12px 노랑이 45도로 반복 */
.stripes {
background: repeating-linear-gradient(
45deg,
#b4480a 0 12px,
#f5b301 12px 24px
);
}
정지점 하나에 시작·끝 위치를 함께 적는 축약형(#b4480a 0 12px)을 쓰면 같은
색을 두 번 적지 않아도 됩니다.
주의할 점은 정지점 위치가 그라디언트 선을 따라 잰 거리라는 것입니다. 45도로 기울여도 줄 두께(줄과 직각으로 잰 거리)는 12px 그대로지만, 가로로 재면 약 17px(12 ÷ cos45°) 간격이 됩니다. 세로줄과 같은 값을 넣었는데 기울인 쪽이 성기게 보이는 이유가 이것입니다. 가로 간격을 맞추고 싶다면 각도에 맞춰 값을 줄여야 합니다.
실전 2: 그라디언트 테두리
border-color는 그라디언트를 받지 못합니다. 대신 배경을 두 겹으로 깔고
각 겹이 차지하는 영역을 다르게 지정하면 테두리만 그라디언트가 됩니다.
.gradient-border {
border: 3px solid transparent;
border-radius: 12px;
background:
linear-gradient(#fff, #fff) padding-box, /* 안쪽 면 */
linear-gradient(90deg, #b4480a, #1a7f37) border-box; /* 테두리까지 */
}
첫 번째 겹은 padding-box라 테두리 안쪽까지만 그려지고, 두 번째 겹은
border-box라 테두리 영역까지 그려집니다. 테두리를 transparent로 비워 뒀기
때문에 그 자리로 아래 겹이 비쳐 보입니다. border-radius도 그대로 따라옵니다.
한계가 하나 있습니다. 안쪽 면을 불투명한 색으로 덮는 방식이라, 배경이
사진이거나 투명해야 하는 곳에서는 쓸 수 없습니다. 그런 경우에는 안쪽 색을
부모 배경색과 같게 맞추거나, mask를 쓰는 다른 방법이 필요합니다.
실전 3: 사진 위 글자를 읽히게 하기
사진 위에 흰 글자를 얹으면 밝은 부분에서 글자가 사라집니다. 사진 전체를 어둡게 하면 사진이 죽습니다. 글자가 있는 쪽만 어둡게 하는 것이 답입니다.
.photo-caption::before {
content: '';
position: absolute;
inset: 0;
/* 위쪽 40%는 손대지 않고, 아래로 갈수록 어두워진다 */
background: linear-gradient(transparent 40%, rgb(0 0 0 / 0.75));
}
사진은 위쪽이 그대로 보이고, 글자가 놓인 아래쪽만 어두워집니다. 어두운 정도는
0.75 부분으로 조절하는데, 흰 글자 기준 대비 4.5:1을 넘기는 값을
대비 검사기로 확인해 두면 안전합니다. 사진마다
밝기가 다르므로 가장 밝은 사진을 기준으로 잡습니다.
이 문제는 메인 슬라이드에서 실제로 겪었습니다. 사진이 깔린 메인 슬라이드 위에 글자를 흰색으로 넣어 달라는 요청이었는데, 배경 사진이 밝은 장에서는 글자가 묻혀 잘 보이지 않았습니다. 슬라이드처럼 사진이 계속 바뀌는 자리는 어두운 사진 한 장만 보고 판단하면 안 됩니다.
실전 4: 글자에 그라디언트
배경을 글자 모양으로 오려내고 글자색을 투명하게 만듭니다.
.gradient-text {
background: linear-gradient(90deg, #b4480a, #f5b301);
-webkit-background-clip: text; /* 접두사만 아는 옛 브라우저용 */
background-clip: text;
color: transparent;
}
글자 자체는 그대로 남아 있어서 선택·복사·검색·낭독이 모두 됩니다. 이미지로 만든 제목과 다른 점입니다.
다만 color: transparent가 위험한 조합이라는 것은 알고 써야 합니다.
배경이 어떤 이유로든 그려지지 않으면 글자가 통째로 사라집니다. 고대비 모드처럼 색을 강제로 바꾸는 환경
(forced-colors)도 따로 챙겨 두는 편이 안전합니다. 큰 제목 한두 개에만 쓰고, 본문이나
버튼 라벨에는 쓰지 마세요.
/* 고대비 모드에서는 평범한 글자로 되돌린다 */
@media (forced-colors: active) {
.gradient-text {
background: none;
color: CanvasText;
}
}
색 조합을 고르는 게 어렵다면 그라디언트 생성기에 정지점을 넣고 각도를 돌려 가며 CSS를 그대로 가져가세요. 중간이 탁해지는지도 미리보기에서 바로 보입니다.
흔한 실수
- 그라디언트에
transition을 걸어 두고 부드럽게 바뀌길 기대하는 것 — 걸리지 않습니다. 2초짜리 전환을 걸고 0.7초 시점에 값을 읽어 보면 이미 최종 그라디언트로 바뀌어 있습니다. 같은 시점에background-color는 아직 중간에 있는 것과 대조됩니다. 부드럽게 바꾸려면 두 겹을 겹쳐 놓고 위 겹의opacity를 전환하세요. 그라디언트에 쓰는 색을@property로 등록한 CSS 변수로 만들면 그 변수는 전환할 수 있지만, 지원하는 브라우저 버전을 확인하고 써야 합니다. - 넓은 면적에 아주 완만한 그라디언트 — 색은 채널당 256단계뿐이라, 색 차이가 작을수록 계단(밴딩)이 눈에 띕니다. 면적을 줄이거나 두 색의 차이를 키우면 덜합니다.
transparent로 끝내면 회색이 낀다고 믿는 것 — 예전 브라우저 이야기입니다. 지금은 나타나지 않습니다. 자세한 이유는 기초편에 적어 뒀습니다.background를 통째로 덮어쓰는 것 — 그라디언트를background단축 속성에 적으면background-color까지 초기화됩니다. 그라디언트가 로드되기 전이나 지원하지 않는 환경에서 배경이 비어 보일 수 있으니, 대체 색을 먼저 적고 그라디언트를 뒤에 적으세요.- 정지점을 색상환 반대편끼리 잇는 것 — 중간이 무채색을 지나며 탁해집니다.
색 변환기로 두 색의
H값을 확인하고, 차이가 크면 중간 정지점을 하나 넣습니다.
요약
- 그라디언트는 파일 요청 없이 그려지는 이미지다. 규칙적인 무늬·테두리·막에 쓴다
- 줄무늬는
repeating-linear-gradient+ 정지점 축약형(색 0 12px). 기울여도 줄 두께는 그대로고 가로 간격만 넓어진다 - 그라디언트 테두리는
padding-box/border-box두 겹. 단, 안쪽이 불투명해야 한다 - 사진 위 글자는 글자 쪽만 어둡게 하고, 가장 밝은 사진 기준으로 대비를 확인한다
- 글자 그라디언트는 글자가 그대로 남아 좋지만,
color: transparent라 고대비 모드 대비가 필요하다 - 그라디언트에는
transition이 걸리지 않는다. 두 겹을 겹치고opacity를 전환한다