CSS box-shadow 완벽 가이드: 문법부터 실전 예시까지
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
디자이너에게서 받은 Figma 파일에는 그림자가 있는데,
이를 CSS로 옮기다 보면 값을 맞추기가 생각보다 까다롭습니다. box-shadow 속성 하나에 파라미터가 다섯 개나 들어가고,
조금만 값을 바꿔도 결과가 크게 달라집니다. 이 글에서는 box-shadow의 문법과 각 파라미터의 역할을 정리하고,
실무에서 바로 쓸 수 있는 패턴과 도구 활용법을 소개합니다.
box-shadow 기본 문법#
box-shadow: offset-x offset-y blur-radius spread-radius color;
| 파라미터 | 역할 | 기본값 |
|---|---|---|
offset-x | 수평 위치 (양수: 오른쪽, 음수: 왼쪽) | 필수 |
offset-y | 수직 위치 (양수: 아래, 음수: 위) | 필수 |
blur-radius | 흐림 반경(클수록 부드럽게 퍼짐) | 0 |
spread-radius | 그림자 크기 조절 (양수: 확장, 음수: 축소) | 0 |
color | 그림자 색상. 생략 시 현재 색상 상속 | 현재 color |
가장 간단한 형태는 x·y 오프셋만 지정하는 것입니다:
/* 오른쪽 아래로 4px 이동, 흐림 없음 */
box-shadow: 4px 4px #00000040;
흐림과 번짐 반경을 추가하면 자연스러운 그림자가 됩니다:
/* 카드 컴포넌트에 자주 쓰이는 소프트 쉐도우 */
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.12);
실무 패턴 4가지#
1. 카드: 부드러운 입체감#
.card {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.08),
0 4px 16px rgba(0, 0, 0, 0.06);
}
.card:hover {
box-shadow:
0 4px 8px rgba(0, 0, 0, 0.10),
0 12px 32px rgba(0, 0, 0, 0.08);
transition: box-shadow 0.2s ease;
}
두 개의 그림자를 겹치면(레이어드 쉐도우) 훨씬 사실적인 입체감이 나옵니다. 가까운 그림자(어둡고 좁음)와 먼 그림자(연하고 넓음)를 조합하는 것이 핵심입니다.
2. 버튼: 클릭감 표현#
.btn {
box-shadow: 0 2px 6px rgba(37, 99, 235, 0.35);
}
.btn:active {
box-shadow: 0 1px 2px rgba(37, 99, 235, 0.20);
transform: translateY(1px);
}
클릭(:active) 상태에서 그림자를 줄이고
translateY로 살짝 눌리는 느낌을 주면 자연스러운 인터랙션이 됩니다.
3. 인셋 쉐도우: 눌린 효과#
inset 키워드를 앞에 붙이면 그림자가 요소 안쪽으로 들어갑니다:
/* 입력 필드 포커스 상태 */
input:focus {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.08);
outline: none;
}
/* 눌린 버튼 표현 */
.btn-pressed {
box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.15);
}
4. 테두리 대체: spread 활용#
spread-radius를 양수로 지정하면 테두리처럼 사용할 수 있습니다. 일반 border와 달리 레이아웃 크기에 영향을 주지 않기 때문에,
CLS(레이아웃 시프트)를 방지할 때 유용합니다:
/* 포커스 링 — 레이아웃 변경 없이 테두리 추가 */
.card:focus-visible {
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.50);
outline: none;
}
CSS 박스 쉐도우 생성기 →로 슬라이더를 조작하면서
각 값의 변화를 실시간으로 확인해 보세요.
레이어드 쉐도우: 여러 그림자 겹치기#
쉼표로 여러 쉐도우를 나열하면 하나의 요소에 겹쳐서 적용됩니다. 목록에서 먼저 나올수록 위에 렌더링됩니다:
/* 3단 레이어드: 가까운 그림자 → 중간 → 먼 그림자 */
.card-elevated {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.10), /* 가까운 */
0 4px 8px rgba(0, 0, 0, 0.08), /* 중간 */
0 16px 32px rgba(0, 0, 0, 0.05); /* 먼 */
}
단색 그림자보다 훨씬 깊이 있는 결과를 얻을 수 있습니다. 단, 레이어 수가 많아질수록 렌더링 비용이 늘어나므로
3개 이하로 유지하는 것이 좋습니다.
색상 활용: 검정만 쓰지 마세요#
rgba(0,0,0,…) 대신 요소의 배경색에 어울리는 색 그림자를 쓰면
더 세련된 느낌이 납니다.
/* 파란 버튼의 그림자를 파란 계열로 */
.btn-primary {
background: #2563EB;
box-shadow: 0 4px 14px rgba(37, 99, 235, 0.40);
}
/* 카드 위에 빨간 배지 */
.badge-error {
background: #DC2626;
box-shadow: 0 2px 8px rgba(220, 38, 38, 0.35);
}
성능 주의사항#
box-shadow는 GPU 가속을 받지 않기 때문에
애니메이션 처리가 많으면 성능에 영향을 줄 수 있습니다. transition으로 그림자 변화를 줄 때는 다음을 고려하세요:
transition: box-shadow 0.2s ease로 비교적 짧은 duration 사용- 스크롤 이벤트 핸들러 내부에서 실시간으로 값을 바꾸는 것은 피할 것
- 성능이 중요한 경우
filter: drop-shadow()로 대체 검토 (GPU 가속 지원)
CSS 박스 쉐도우 생성기 활용법#
값을 머릿속으로 계산하지 않아도 됩니다. CSS 박스 쉐도우 생성기 →에서 슬라이더로 X·Y 오프셋, blur, spread, 색상을 조절하면 결과 CSS가 즉시 생성됩니다.
- 오프셋 슬라이더: 그림자가 어느 방향으로 얼마나 이동할지 설정
- Blur 슬라이더: 0이면 선명한 경계, 숫자가 클수록 부드럽게 번짐
- Spread 슬라이더: 그림자 전체 크기를 조절 (음수 값으로 오히려 줄일 수도 있음)
- 색상 피커: RGBA 알파 채널로 반투명도 조절
- 코드 복사: 생성된 CSS를 클립보드에 바로 복사
Figma나 디자인 툴에서 그림자 값을 확인한 후
생성기에 입력하면 CSS로 빠르게 변환할 수 있습니다.
CSS 레이아웃 전반이 궁금하다면
CSS Flexbox vs Grid 완벽 정리도 참고하세요.
FAQ#
Q. box-shadow와 filter: drop-shadow()의 차이는 무엇인가요?
box-shadow는 요소의 박스 경계를 기준으로 그림자를 그리기 때문에,
SVG나 투명 배경 PNG처럼 실제 모양이 불규칙한 이미지에는 박스 형태 그림자가 생깁니다. filter: drop-shadow()는 픽셀 알파 채널을 기준으로 실제 모양을 따라 그림자를 그리므로
아이콘·SVG에 더 적합합니다. 단, GPU를 활용하여 렌더링하므로 성능 특성이 다릅니다.
Q. 다크 모드에서 그림자가 잘 보이지 않아요.
어두운 배경 위에서는 rgba(0,0,0,…) 그림자가 거의 보이지 않습니다. 다크 모드에서는 흰색 계열의 미묘한 그림자(rgba(255,255,255,0.05))나
배경보다 살짝 밝은 테두리(border)로 입체감을 표현하는 것이 일반적입니다. 또는 spread-radius만 사용해 테두리 대용으로 구분선을 그리는 방법도 있습니다.
Q. 인터넷 익스플로러(IE)에서도 동작하나요?
IE는 2022년 6월 공식 지원이 종료되었으며,
2026년 현재 모던 브라우저 기준으로만 개발하면 됩니다. box-shadow는 모든 모던 브라우저(Chrome, Firefox, Safari, Edge)에서
완전 지원됩니다.