2025-03-14T13:00:37
This commit is contained in:
192
doc/svg/13_반응형 SVG 디자인 패턴.md
Normal file
192
doc/svg/13_반응형 SVG 디자인 패턴.md
Normal file
@@ -0,0 +1,192 @@
|
||||
### 반응형 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를 구축할 수 있습니다.
|
||||
Reference in New Issue
Block a user