CSS · 테두리, 그림자, 트랜지션, 애니메이션
앞에서는 글자·색·배경을 칠했어요. 이번 장은 요소에 입체감과 움직임을 주는 단계입니다. 테두리로 윤곽을 잡고, 그림자로 떠 보이게 하고, 트랜지션·애니메이션으로 부드럽게 변하게 만들어요. CSS? 가 가장 "보여주는 재미"가 큰 영역입니다.
같은 버튼이라도 효과 한 줌으로 인상이 완전히 달라집니다. 왼쪽은 효과 없는 기본 버튼, 오른쪽은 둥근 모서리·그림자·그라데이션·호버 전환을 준 버튼이에요(마우스를 올려보면 부드럽게 변합니다).
이 장의 데모는 실제 HTML? + <style> 을 그대로 실행해요.
마우스를 올리면(hover) 변하고, 회전·맥박 같은 애니메이션도 실제로 돕니다. 코드를 고치고 실행을 눌러 바로 결과를 확인하세요.
1. 테두리와 모서리 — border · border-radius · outline
무엇: 요소 둘레에 선을 두르고(테두리), 모서리를 둥글게 깎습니다(라운드).
border — 굵기 · 스타일 · 색
border 는 세 값을 한 번에 적는 단축 속성입니다: border: 굵기 스타일 색;. 스타일은 solid(실선) 외에도 여러 가지가 있어요.
.box {
border: 2px solid #4f46e5; /* 굵기 2px · 실선 · 색 */
}
/* 한 변만 따로 지정도 가능 */
.box { border-bottom: 3px dashed #dc2626; }
/* 스타일 종류 */
border-style: solid | dashed | dotted | double | groove | ridge | inset | outset | none;border-radius — 둥근 · 원형 · 알약
border-radius 는 모서리를 깎는 반지름이에요. 값을 50% 로 주면 원이 되고, 아주 큰 값(예 9999px)을 주면 양 끝이 둥근 알약(pill) 모양이 됩니다.
outline — 테두리 바깥의 외곽선
outline 은 테두리와 비슷하지만 레이아웃 자리를 차지하지 않습니다(요소를 밀어내지 않아요). 그래서 키보드 포커스 표시에 즐겨 씁니다. outline-offset 으로 요소와의 간격도 줄 수 있어요.
button:focus {
outline: 2px solid #4f46e5; /* 굵기 스타일 색 (border와 같은 순서) */
outline-offset: 3px; /* 요소에서 3px 떨어뜨려 그림 */
}border 는 박스 크기에 포함돼 옆 요소를 밀어냅니다. outline 은 박스 위에 덧그려질 뿐이라 크기에 영향이 없어요. 접근성을 위해 포커스 외곽선은 지우지 말고 보기 좋게 다듬는 것을 권합니다.
2. 그림자 — box-shadow · text-shadow
무엇: 요소 뒤에 그림자를 깔아 떠 있는 느낌(입체감)을 줍니다. 카드·버튼·모달에서 가장 많이 쓰여요.
box-shadow — x y 흐림 번짐 색
값 순서는 box-shadow: x축 y축 흐림(blur) 번짐(spread) 색; 입니다. 맨 앞에 inset 을 붙이면 안쪽 그림자가 되고, 쉼표로 여러 겹을 겹칠 수 있어요.
/* x y blur spread color */
box-shadow: 0 4px 12px 0 rgba(0,0,0,.15); /* 아래로 떨어지는 부드러운 그림자 */
box-shadow: inset 0 2px 6px rgba(0,0,0,.3); /* 안쪽으로 파인 느낌 */
/* 여러 겹 — 쉼표로 나열 */
box-shadow: 0 1px 2px rgba(0,0,0,.1),
0 8px 24px rgba(0,0,0,.15);실제 카드와 버튼 그림자를 비교해 보세요. hover 시 그림자가 커지며 떠오르는 효과까지 동작합니다.
text-shadow — 글자 그림자
글자에 그림자를 줍니다. 순서는 text-shadow: x y 흐림 색; 으로 번짐(spread)·inset 은 없습니다. 가독성을 위해 밝은 배경 위 글자에 살짝 그림자를 주거나, 네온·엠보싱 효과에 씁니다.
3. 투명도와 필터 — opacity · filter
무엇: 요소를 흐리게·밝게·흑백으로 바꾸는 화면 효과입니다.
opacity — 통째로 투명하게
opacity 는 0(완전 투명)부터 1(불투명)까지의 값으로, 요소를 내용까지 전부 투명하게 만듭니다. 색만 반투명하게 하고 싶다면 opacity 대신 rgba(...,.5) 처럼 색의 알파값을 쓰는 게 좋아요.
filter — blur · brightness · grayscale · drop-shadow
filter 는 이미지 보정 필터처럼 요소 전체에 효과를 겁니다. 여러 함수를 띄어쓰기로 나열하면 차례로 적용돼요.
| 함수 | 효과 | 예 |
|---|---|---|
blur() | 흐리게(픽셀 단위) | blur(4px) |
brightness() | 밝기(1 = 원본, >1 밝게) | brightness(1.3) |
contrast() | 대비 | contrast(1.5) |
grayscale() | 흑백(0~1 또는 0~100%) | grayscale(1) |
drop-shadow() | 모양을 따라가는 그림자 | drop-shadow(2px 4px 6px #000) |
filter: drop-shadow() 는 box-shadow 와 달리 박스가 아니라 내용물의 실제 모양(투명 PNG, 둥근 도형 등)을 따라 그림자를 그립니다. 단 번짐(spread) 값은 없어요.
4. 트랜지션 — transition
무엇: 어떤 속성이 바뀔 때 탁 변하지 않고 부드럽게 이어 주는 기능입니다. :hover 와 짝지으면 마우스를 올릴 때 색·크기가 스르륵 변해요.
순서는 transition: 속성 지속시간 가속곡선 지연; 입니다.
.btn {
transition: background-color .3s ease, transform .3s ease;
/* 속성 시간 곡선 (쉼표로 여러 속성) */
}
.btn:hover { background-color:#4f46e5; transform: scale(1.05); }
/* 모든 속성을 한 번에 — all (편하지만 성능상 주의) */
transition: all .25s ease-out .1s; /* 속성 시간 곡선 지연 */가속 곡선(timing-function): linear(일정), ease(기본), ease-in(천천히 시작), ease-out(천천히 끝), ease-in-out, 직접 정의하는 cubic-bezier(...), 계단식 steps(...) 가 있어요.
5. 변형 — transform
무엇: 요소를 이동·확대·회전·기울이기 합니다. 레이아웃을 다시 계산하지 않고 화면에서만 변형해 아주 빠릅니다.
| 함수 | 뜻 | 예 |
|---|---|---|
translate(x, y) | 이동 | translate(10px, -5px) |
scale(n) | 확대/축소 | scale(1.2) · scale(.8) |
rotate(deg) | 회전(도 단위) | rotate(15deg) |
skew(deg) | 기울이기 | skew(10deg, 0) |
여러 변형은 띄어쓰기로 나열해 한 번에 줍니다. transform-origin 으로 변형의 기준점(기본은 가운데)을 바꿀 수 있어요.
transform: translateY(-4px) rotate(8deg) scale(1.1); /* 여러 변형 조합 */ transform-origin: top left; /* 왼쪽 위를 기준으로 회전/확대 */
6. 애니메이션 — @keyframes + animation
무엇: 트랜지션이 "A→B 한 번"이라면, 애니메이션은 여러 단계를 정해 두고 반복할 수 있습니다.
먼저 @keyframes 로 장면들을 정의하고, animation 으로 그 장면을 이름으로 불러 실행해요.
/* 1) 장면 정의: from(=0%) → to(=100%) 또는 % 단계 */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.15); opacity: .6; }
100% { transform: scale(1); opacity: 1; }
}
/* 2) 실행: 이름 시간 곡선 반복횟수 방향 */
.spinner { animation: spin 1s linear infinite; }
.dot { animation: pulse 1.2s ease-in-out infinite; }animation 단축 속성의 주요 값입니다.
| 값 | 뜻 |
|---|---|
이름(name) | @keyframes 에서 정한 이름 |
시간(duration) | 한 바퀴에 걸리는 시간 1s |
곡선(timing-function) | linear · ease-in-out 등 |
반복(iteration-count) | 횟수 또는 infinite(무한) |
방향(direction) | normal · reverse · alternate(왕복) |
회전 스피너, 맥박(pulse), 페이드인을 한꺼번에 실행해 봅니다.
7. 커서와 선택 — cursor · user-select
cursor 는 마우스를 올렸을 때의 커서 모양을 바꿉니다. 버튼엔 pointer(손가락), 비활성엔 not-allowed 등.
user-select 는 사용자가 드래그로 글자를 선택할 수 있는지 정합니다. 버튼 라벨처럼 선택될 필요 없는 텍스트엔 none 을 줘요.
.btn { cursor: pointer; } /* 손가락 */
.disabled { cursor: not-allowed; } /* 금지 */
.draggable { cursor: grab; } /* 잡기 */
.label { user-select: none; } /* 드래그 선택 막기 (auto | text | all | none) */한눈에 — 효과/애니메이션 카탈로그
| 속성 | 용도 | 값 순서 / 주요 값 |
|---|---|---|
border | 테두리 | 굵기 스타일 색 (2px solid #333) |
border-radius | 둥근 모서리 | 길이/% (50%=원, 큰 값=알약) |
outline | 바깥 외곽선(자리 안 차지) | 굵기 스타일 색 + outline-offset |
box-shadow | 박스 그림자 | x y blur spread color, inset, 쉼표로 여러 겹 |
text-shadow | 글자 그림자 | x y blur color (spread·inset 없음) |
opacity | 전체 투명도 | 0~1 |
filter | 화면 효과 | blur · brightness · grayscale · drop-shadow (띄어쓰기로 합성) |
transition | 속성 변화 부드럽게 | 속성 시간 곡선 지연 |
transform | 이동·확대·회전·기울이기 | translate · scale · rotate · skew (띄어쓰기로 조합) |
transform-origin | 변형 기준점 | 기본 center (top left 등) |
@keyframes | 애니메이션 장면 정의 | from/to 또는 0%~100% |
animation | 키프레임 실행 | 이름 시간 곡선 반복(infinite) 방향(alternate) |
cursor | 마우스 커서 모양 | pointer · grab · not-allowed · text |
user-select | 드래그 선택 허용 | auto · text · all · none |
부드러운 애니메이션은 transform 과 opacity 위주로. 이 둘은 브라우저가 GPU로 처리해 가장 매끄럽습니다.
반면 width·top·margin 같은 값을 애니메이션하면 매 프레임마다 레이아웃을 다시 계산해 끊길 수 있어요. 위치를 옮길 땐 top 대신 transform: translate() 를 쓰세요.
또한 일부 사용자는 움직임에 어지럼을 느낍니다. prefers-reduced-motion 미디어 쿼리로 "움직임 줄이기" 설정을 켠 사용자에겐 애니메이션을 멈추거나 약하게 해 주세요.
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}다음 단계
- 화면 크기에 맞춰 레이아웃을 바꾸는 단위·미디어 쿼리 → CSS · 단위, 반응형