Files
html-examples/doc/svg/13_반응형 SVG 디자인 패턴.md
2025-03-14 13:00:37 +09:00

192 lines
6.9 KiB
Markdown

### 반응형 SVG 디자인 패턴
반응형 웹 디자인(Responsive Web Design, RWD)은 다양한 화면 크기와 디바이스에 맞춰 콘텐츠를 최적화하는 필수 요소입니다. SVG(Scalable Vector Graphics)는 벡터 기반으로 해상도에 상관없이 선명함을 유지하며, `viewBox`와 CSS를 활용해 반응형 디자인에 이상적입니다. 아래에서는 반응형 SVG 디자인의 핵심 패턴, 구현 방법, 그리고 실무에서의 활용 예시를 설명합니다.
---
### 반응형 SVG의 장점
1. **확장성**: 픽셀 단위가 아닌 벡터로 정의되어 크기 조정 시 품질 저하 없음.
2. **유연성**: `viewBox`로 좌표계를 조정해 콘텐츠 비율 유지.
3. **스타일링**: CSS 미디어 쿼리와 결합해 조건에 따라 스타일 변경 가능.
4. **경량화**: 이미지 파일 대신 SVG로 대체해 로딩 속도 개선.
---
### 반응형 SVG 디자인 패턴
#### 1. `viewBox`를 활용한 비율 유지
`viewBox`는 SVG의 내부 좌표계를 정의하며, 캔버스 크기(`width`, `height`)와 독립적으로 콘텐츠를 스케일링합니다. 이를 통해 반응형 비율을 유지합니다.
- **구현 방법**:
- `viewBox="min-x min-y width height"`로 콘텐츠 영역 설정.
- `width="100%"`로 컨테이너에 맞게 크기 조정.
- **예시**:
```xml
<svg width="100%" height="auto" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue"/>
</svg>
```
- 컨테이너 너비에 따라 원이 비례적으로 크기 조정됨.
#### 2. CSS 미디어 쿼리로 조건부 스타일링
SVG 요소의 스타일을 화면 크기에 따라 다르게 적용합니다.
- **구현 방법**:
- SVG 내부 `<style>` 태그나 외부 CSS 사용.
- 미디어 쿼리로 크기, 색상, 표시 여부 조정.
- **예시**:
```html
<svg width="100%" height="auto" viewBox="0 0 100 100">
<circle class="responsive-circle" cx="50" cy="50" r="40"/>
</svg>
<style>
.responsive-circle {
fill: blue;
}
@media (max-width: 600px) {
.responsive-circle {
fill: red;
r: 20;
}
}
</style>
```
- 화면 너비 600px 이하에서 원이 작아지고 색상이 변경됨.
#### 3. 컨테이너에 맞춘 유동적 크기 조정
SVG를 부모 요소에 종속시켜 반응형 레이아웃을 만듭니다.
- **구현 방법**:
- `width="100%"`와 `height="auto"`로 부모 크기에 맞춤.
- `preserveAspectRatio`로 가로세로 비율 조정.
- **예시**:
```html
<div style="width: 50%; max-width: 400px;">
<svg width="100%" height="auto" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<rect x="10" y="10" width="80" height="80" fill="green"/>
</svg>
</div>
```
- 부모 너비에 따라 사각형 크기가 조정되며, 비율은 유지됨.
#### 4. 동적 콘텐츠 조정
화면 크기에 따라 SVG 내부 요소의 위치나 크기를 동적으로 변경합니다.
- **구현 방법**:
- JavaScript로 `window.resize` 이벤트 감지 후 속성 업데이트.
- **예시**:
```html
<svg id="dynamicSvg" width="100%" height="auto" viewBox="0 0 100 100">
<circle id="dynamicCircle" cx="50" cy="50" r="40" fill="purple"/>
</svg>
<script>
const svg = document.getElementById("dynamicSvg");
const circle = document.getElementById("dynamicCircle");
const resizeHandler = () => {
const width = svg.clientWidth;
circle.setAttribute("r", width < 300 ? "20" : "40");
};
window.addEventListener("resize", resizeHandler);
resizeHandler();
</script>
```
- 창 크기가 300px 미만일 때 원의 반지름이 줄어듦.
#### 5. 복잡한 레이아웃에서의 그룹화
`<g>` 태그로 요소를 그룹화하고, 반응형 조건에 따라 표시/숨김 처리.
- **구현 방법**:
- CSS의 `display` 속성으로 그룹 제어.
- **예시**:
```html
<svg width="100%" height="auto" viewBox="0 0 200 100">
<g class="desktop-view">
<rect x="10" y="10" width="180" height="80" fill="blue"/>
</g>
<g class="mobile-view">
<circle cx="100" cy="50" r="40" fill="red"/>
</g>
</svg>
<style>
.mobile-view { display: none; }
@media (max-width: 600px) {
.desktop-view { display: none; }
.mobile-view { display: block; }
}
</style>
```
- 데스크톱에서는 사각형, 모바일에서는 원 표시.
---
### 실무에서의 활용 예시
#### 1. 반응형 로고
```html
<svg width="100%" height="auto" viewBox="0 0 200 50">
<rect x="0" y="0" width="200" height="50" fill="black"/>
<text x="100" y="35" fill="white" text-anchor="middle" font-size="20">Logo</text>
</svg>
```
- 컨테이너 크기에 따라 로고가 비례적으로 조정됨.
#### 2. 인터랙티브 차트
```html
<svg id="chart" width="100%" height="auto" viewBox="0 0 400 200">
<g id="bars"></g>
</svg>
<script>
const data = [50, 100, 75, 120];
const barsGroup = document.getElementById("bars");
const renderBars = () => {
barsGroup.innerHTML = "";
const width = document.getElementById("chart").clientWidth / 400 * 80; // 비례적 너비
data.forEach((value, i) => {
const bar = document.createElementNS("http://www.w3.org/2000/svg", "rect");
bar.setAttribute("x", i * width * 1.25);
bar.setAttribute("y", 200 - value);
bar.setAttribute("width", width);
bar.setAttribute("height", value);
bar.setAttribute("fill", "teal");
barsGroup.appendChild(bar);
});
};
window.addEventListener("resize", renderBars);
renderBars();
</script>
```
- 창 크기에 따라 막대 너비가 동적으로 조정됨.
#### 3. 아이콘 시스템
```html
<svg style="display: none;">
<symbol id="icon-star" viewBox="0 0 24 24">
<polygon points="12,2 15,9 22,9 17,14 18,21 12,17 6,21 7,14 2,9 9,9" fill="currentColor"/>
</symbol>
</svg>
<div style="width: 100%;">
<svg class="icon" width="100%" height="auto" preserveAspectRatio="xMidYMid meet">
<use href="#icon-star"/>
</svg>
</div>
<style>
.icon { max-width: 48px; }
@media (max-width: 600px) { .icon { max-width: 24px; } }
</style>
```
- 화면 크기에 따라 아이콘 크기 변경.
---
### 주의사항 및 최적화
1. **성능**: 복잡한 SVG는 렌더링 부담을 줄 수 있으므로 경로 최적화(SVGO 사용) 필요.
2. **브라우저 호환성**: `viewBox`와 `preserveAspectRatio` 지원 확인.
3. **접근성**: 텍스트 기반 요소에 `<title>` 추가로 스크린 리더 지원.
---
### 결론
반응형 SVG 디자인 패턴은 `viewBox`로 비율을 유지하고, CSS 미디어 쿼리와 JavaScript로 동적 조정을 통해 다양한 디바이스에 대응합니다. 로고, 차트, 아이콘 등 실무에서 자주 사용되는 요소를 반응형으로 구현하면 사용자 경험과 성능을 동시에 개선할 수 있습니다. 위 패턴을 기반으로 프로젝트의 요구사항에 맞게 조정하면, SVG의 유연성을 최대한 활용한 반응형 UI를 구축할 수 있습니다.