및 CSS 미디어 쿼리와 함께 적응 형 SVG 구축 – Smashing Magazine
,,,
그리고 CSS 미디어 쿼리.나는 최근에 정적 그래픽이나 애니메이션으로 사용할 SVG 코드를 준비하고 최적화하는 방법에 대해 많은 글을 썼습니다. 나는 SVG와 함께 일하는 것을 좋아하지만 항상 그들에 대해 나를 괴롭히는 것이있었습니다.
적응 형 SVG를 어떻게 구축하는지 설명하기 위해 에피소드를 선택했습니다. 퀵 드로우 맥그로 쇼 1959 년 첫 방송 “Bow Wow Bandit”이라고 불렀습니다.

그 안에서, 빠른 드로우 맥그로 (McGraw)는 자신의 조수 바바 루이 (Baba Looey)를 구하기 위해 그의 블러드 하운드 스너핑을 입대합니다. 이 시대의 대부분의 Hanna-Barbera 타이틀 카드와 마찬가지로, 작품은 Lawrence (Art) Goble에 의해 만들어졌습니다.

Bow Wow Bandit을 기반으로 한 SVG 장면을 설계했다고 가정 해 봅시다. viewBox
1920 × 1080 크기. 이 SVG는 확장되거나 아래로 확장되므로 (단서의 이름으로), 거대 할 때는 날카 로워 보입니다.

그러나 작은 화면에서는 16 : 9 종횡비 (라이브 데모)가 가장 좋은 형식이 아닐 수 있으며 이미지는 그 영향을 잃습니다. 때로는 3 : 4와 같은 초상화 방향이 화면 크기에 더 적합합니다.

그러나 여기에는 문제가 있습니다. viewBox
. SVG에서는 내부 요소 위치가 원본에서 좌표계에 고정되어 있기 때문입니다. viewBox
따라서 데스크탑과 모바일 사이에서 레이아웃을 쉽게 변경할 수 없습니다. 애니메이션과 상호 작용이 종종 요소 위치에 의존하기 때문에 이것은 문제입니다. viewBox
변화.

나의 도전은 1080 × 1440 버전의 Bow Wow Bandit을 작은 스크린과 다른 화면과 다른 스크린에 제공하는 것이 었습니다. 나는 Quick Draw McGraw와 그의 Dawg 스너플과 같은 내부 요소의 위치와 크기 가이 두 레이아웃에 가장 잘 맞도록 변경하기를 원했습니다. 이를 해결하기 위해 몇 가지 대안을 실험했습니다.
메모: 우리는 왜 단지 사용하지 않는가
외부 SVG와 함께? 그만큼
요소는 반응 형 이미지에 대해 훌륭하지만 래스터 형식 (예 : JPEG 또는 Webp) 및 이미지로 취급 된 외부 SVG 파일에서만 작동합니다. 즉, CSS를 사용하여 내부 요소를 애니메이션하거나 스타일링 할 수는 없습니다.
SVG를 보여주고 숨기기
가장 분명한 선택은 내 마크 업에 두 개의 다른 SVG를 포함하는 것이 었습니다. 하나는 작은 화면 용, 다른 하나는 큰 화면을위한 다음 CSS 및 미디어 쿼리를 사용하여 보여 주거나 숨기는 것이 었습니다.
#svg-small { display: block; }
#svg-large { display: none; }
@media (min-width: 64rem) {
#svg-small { display: none; }
#svg-mobile { display: block; }
}
그러나이 방법을 사용하면 두 SVG 버전이 모두로드되며, 그래픽이 복잡 할 때 많은 불필요한 코드를 다운로드하는 것을 의미합니다.
JavaScript를 사용하여 SVG를 교체합니다
지정된 중단 점에서 더 큰 SVG에서 JavaScript를 사용하는 것에 대해 생각했습니다.
if (window.matchMedia('(min-width: 64rem)').matches) {
svgContainer.innerHTML = desktopSVG;
} else {
svgContainer.innerHTML = mobileSVG;
}
JavaScript가 이제 디자인이 표시되는 방식에 중요하다는 사실을 제외하고, SVG는 일반적으로 어쨌든로드되므로 DOM 복잡성과 불필요한 무게가 추가됩니다. 또한 유지 보수는 이제 유지해야 할 두 가지 버전의 아트 워크가 있기 때문에 문제가됩니다.
솔루션 : 하나의 SVG 심볼 라이브러리 및 다중 용도
내 목표는 다음과 같습니다.
- 작은 화면에 Bow Wow Bandit의 한 버전을 제공하십시오.
- 더 큰 화면에 다른 버전을 제공하고
- 내 작품을 한 번 (건조) 한 번만 정의하십시오
- 요소를 크기를 조정하고 재배치 할 수 있습니다.
나는 그것에 대해 충분히 읽지 않았지만
요소를 사용하면 관리 가능성을 향상시키고 코드 팽창을 줄이기 위해 숨겨져 재사용 할 수있는 재사용 가능한 SVG 요소를 정의 할 수 있습니다. 그것들은 SVG의 구성 요소와 같습니다. 한 번 만들고 필요한 곳마다 사용하십시오.
에이
라이브러리에 캐릭터를 저장하는 것과 같습니다. 코드를 일관되고 가볍게 유지하기 위해 필요한만큼 여러 번 참조 할 수 있습니다. 사용 요소, 동일한 기호를 여러 번, 다른 위치 나 크기로, 심지어 다른 SVG에 삽입 할 수 있습니다.
각
자체가 있어야합니다 viewBox
내부 좌표계를 정의합니다. 즉, Sketch와 같은 앱에서 SVG 요소가 어떻게 내보내는 지에 대한 특별한주의를 기울이는 것을 의미합니다.
개별 뷰 박스에 대한 내보내기
나는 레이어로 요소를 어떻게 내보내서 그들과 함께 일할 수 있는지에 대해 전에 썼습니다. 기호를 만들 때 그 과정은 약간 다릅니다.

일반적으로 나는 동일한 것을 사용하여 내 모든 요소를 내보낼 것입니다. viewBox
크기. 하지만 내가 만들 때 symbol
나는 고유 한 구체적인 것이 필요합니다 viewBox
.

그래서 나는 각 요소를 개별 크기의 SVG로 내보내는데, 이는 콘텐츠를 symbol
. Quick Draw McGraw ‘s Hat의 SVG를 가져 가자. viewBox
294 × 182의 크기 :
SVG 태그를 교체합니다
SVG 라이브러리에 아트 워크를 추가하십시오.
그런 다음 작품의 남은 모든 요소에 대한 프로세스를 반복합니다. 이제 내 기호를 업데이트 해야하는 경우 사용되는 모든 인스턴스에 변경 사항이 자동으로 적용됩니다.
사용 a
여러 SVG에서
나는 내 요소가 Bow Wow Bandit의 두 버전, 작은 화면을위한 하나의 배열 및 더 큰 것들을위한 대안 배열에 나타나기를 원했습니다. 그래서 저는 두 SVG를 만듭니다.
… 그리고 두 가지 모두에서 내 기호에 대한 링크를 삽입하십시오.
위치 기호
일단 나는 기호를 레이아웃을 사용하여 내 레이아웃에 배치하면 다음 단계는 다른 화면 크기에 대한 대체 레이아웃을 원할 경우 특히 중요합니다. 상징은처럼 행동합니다
그룹, 그래서 나는 같은 속성을 사용하여 확장하고 움직일 수 있습니다. width
,,, height
그리고 transform
:
나는 각각 배치 할 수있다 독립적으로 사용하는 요소
transform
. 이것은 내 SVG 내부의 요소를 재배치하는 대신에 강력합니다. 참조. 내 내부 레이아웃은 깨끗하게 유지되며 아트 워크를 복제하지 않기 때문에 파일 크기는 여전히 작습니다. 브라우저는 한 번만로드하여 대역폭을 줄이고 페이지 렌더링 속도를 높입니다. 그리고 나는 항상 똑같이 참조하기 때문입니다
symbol
그들의 외관은 화면 크기에 관계없이 일관성을 유지합니다.
애니메이션
강요
상황이 까다로워지는 곳이 있습니다. 나는 Quick Draw의 모자 기울기와 다리가 차는 것처럼 내 캐릭터의 일부를 애니메이션하고 싶었습니다. 그러나 내부 요소를 대상으로 CSS 애니메이션을 추가했을 때
아무 일도 일어나지 않았습니다.
팁: 당신은 애니메이션을 할 수 있습니다 요소 자체이지만 내부의 요소는 아닙니다
. 개별 부품이 움직이기를 원한다면 자신의 상징을 만들고 각각 애니메이션 .
당신은 스타일이나 애니메이션을 할 수 없습니다
왜냐하면 쉽게 타겟팅 할 수없는 그림자 돔 클론을 만듭니다. 그래서 나는 몰래 가야했다. 각각 내부
내 도서관 SVG에서 나는 a를 추가했다
내가 애니메이션하고 싶었던 부분 주위의 요소 :
… 그리고 속성 서브 스트링 선택기를 사용하여 href
의 속성 use
요소:
use[href="#quick-draw-hat"] {
animation-delay: 0.5s;
animation-direction: alternate;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-name: hat-rock;
animation-timing-function: ease-in-out;
transform-origin: center bottom;
}
@keyframes hat-rock {
from { transform: rotate(-2deg); }
to { transform: rotate(2deg); } }
두 개의 가시적 인 SVG (작은 화면 용과 큰 화면 용)를 만들면 마지막 단계는 어떤 화면 크기에 어떤 버전을 표시할지 결정하는 것입니다. CSS 미디어 쿼리를 사용하여 한 SVG를 숨기고 다른 SVG를 표시합니다. 기본적으로 작은 화면 SVG를 보여주는 것으로 시작합니다.
.svg-small { display: block; }
.svg-large { display: none; }
그런 다음 a를 사용합니다 min-width
미디어 쿼리 대형 스크린 SVG로 전환합니다 64rem
그리고 위 :
@media (min-width: 64rem) {
.svg-small { display: none; }
.svg-large { display: block; }
}
이것은 한 번에 하나의 SVG 만 보이게하여 내 레이아웃과 DOM에 불필요한 혼란이 없도록합니다. 그리고 모두 가시적 인 SVG는 동일한 숨겨진 것을 참조하기 때문입니다
도서관, 브라우저는 얼마나 많은지에 관계없이 아트 워크를 한 번만 다운로드합니다. 요소는 두 레이아웃에 나타납니다.

마무리
결합하여
,,, CSS 미디어 쿼리 및 구체적인 변환을 구축 할 수 있습니다 적응 형 SVG 이는 콘텐츠를 복제하거나 추가 자산을로드하거나 JavaScript에 의존하지 않고 요소를 재배치합니다. 숨겨진 심볼 라이브러리에서 각 그래픽을 한 번만 정의해야합니다. 그런 다음 몇 가지 가시적 인 SVG 내에서 필요에 따라 해당 그래픽을 재사용 할 수 있습니다. CSS가 레이아웃 전환을 수행하면서 결과는 빠르고 유연합니다.
웹에서 가장 강력한 기술 중 일부는 큰 프레임 워크 나 복잡한 툴링이 필요하지 않다는 것을 상기시켜줍니다. 약간의 SVG 노하우와 기본의 영리한 사용 만 필요합니다.

(GG, YK)
Post Comment