CSS 사용자 정의 속성을 갖춘 멋진 SVG — Smashing Magazine

CSS 사용자 정의 속성을 갖춘 멋진 SVG — Smashing Magazine

최근에 제가 어떻게 사용하는지 설명했어요 , 적응형 SVG라고 부르는 것을 개발하기 위한 CSS 미디어 쿼리도 있습니다. 기호를 사용하면 요소를 한 번 정의한 다음 사용 이를 통해 SVG 애니메이션을 더 쉽게 유지 관리하고 더 효율적이며 가볍게 만들 수 있습니다.

설명을 작성한 이후로 저는 제 웹사이트 전반에 걸쳐 새로운 Magnificent 7 애니메이션 그래픽을 디자인하고 구현했습니다. 그들은 7명의 웅장한 옛 서부 캐릭터를 특징으로 하는 웹 디자인 선구자 테마를 다루고 있습니다.

7명의 웅장한 옛 서부 캐릭터가 등장하는 그래픽
내 웹사이트에서 이 애니메이션 SVG를 보세요. (큰 미리보기)

그리고 캐릭터 디자인을 정의하고 이를 여러 SVG와 페이지에서 재사용하겠습니다. 먼저 캐릭터를 생성하고 각각의 캐릭터를 숨겨진 라이브러리 내부 SVG:

그런 다음 두 개의 다른 SVG에서 해당 기호를 참조했습니다. 하나는 큰 화면용이고 다른 하나는 작은 화면용입니다.



 
 




 
 

우아한. 그런데 화가 났습니다. 캐릭터를 재사용할 수는 있지만 애니메이션을 적용하거나 스타일을 지정할 수는 없었습니다. 에서 참조하는 기호 내의 요소를 대상으로 하는 CSS 규칙을 추가했습니다. 하지만 아무 일도 일어나지 않았습니다. 색상은 동일하게 유지되었고, 움직여야 할 것들은 그대로 유지되었습니다. 보이지 않는 장벽에 부딪힌 것 같았고 그랬습니다.

Shadow DOM 장벽 이해

내용을 참고할 때 symbol ~와 함께 use브라우저는 Shadow DOM에 복사본을 생성합니다. 각 인스턴스는 참조된 인스턴스의 캡슐화된 복사본이 됩니다. 즉, 외부의 CSS는 요소의 스타일을 직접 지정하기 위한 장벽을 뚫을 수 없습니다. 예를 들어, 일반적인 상황에서는 다음과 같습니다. tapping 값은 CSS 애니메이션을 트리거합니다.


.tapping {
  animation: tapping 1s ease-in-out infinite;
}

하지만 동일한 애니메이션이 같은 발의 경우 아무 일도 일어나지 않습니다.


 



.tapping {
  animation: tapping 1s ease-in-out infinite;
}

그 이유는 안에 요소가 보호된 섀도우 트리에 있고 CSS Cascade가 중단되었습니다. 경계. 이 동작은 실망스러울 수 있지만 재사용된 기호 콘텐츠가 일관되고 예측 가능하게 유지되도록 의도적인 것입니다.

적응형 SVG를 개발하는 방법을 배우는 동안 이 동작을 해결하려는 모든 종류의 시도를 발견했지만 대부분은 SVG를 우아하게 만드는 재사용성을 희생했습니다. 나는 단지 다른 시간에 깜박이게 만들기 위해 내 캐릭터를 복제하고 싶지 않았습니다. 나는 싱글을 원했다 고유한 타이밍과 표현이 있는 인스턴스가 있습니다.

단일 SVG 기호 내의 여러 애니메이션 요소
단일 SVG 기호 내의 여러 애니메이션 요소. (큰 미리보기)

구조를 위한 CSS 사용자 정의 속성

나의 선구적인 애니메이션을 작업하면서 나는 다음과 같은 사실을 배웠다. 일반 CSS 값은 경계를 넘어 Shadow DOM으로 들어갈 수 없지만 CSS 사용자 정의 속성은. 그리고 내부 요소의 스타일을 직접 지정할 수는 없지만 사용자 정의 속성 값을 전달할 수 있습니다. 따라서 인라인 스타일에 사용자 정의 속성을 삽입하면 브라우저는 캐스케이드를 확인하고 해당 스타일은 내부 요소에서 사용할 수 있게 됩니다. 참조되고 있습니다.

나는 추가했다 rotate 인라인 스타일에 적용 콘텐츠:


  

그런 다음 발 두드리기 애니메이션을 정의하고 요소에 적용했습니다.

@keyframes tapping {
  0%, 60%, 100% { --foot-rotate: 0deg; }
  20% { --foot-rotate: -5deg; }
  40% { --foot-rotate: 2deg; }
}

use[data-outlaw="1"] {
  --foot-rotate: 0deg;
  animation: tapping 1s ease-in-out infinite;
}

여러 값을 기호에 전달하기

CSS 사용자 정의 속성을 사용하기 위해 심볼을 설정한 후에는 원하는 만큼 많은 값을 전달할 수 있습니다. 사례. 예를 들어 다음과 같은 변수를 정의할 수 있습니다. fill, opacity또는 transform. 우아한 점은 각각 그러면 인스턴스는 고유한 값 세트를 가질 수 있습니다.


  

use[data-outlaw="1"] {
  --eyelids-colour: #f7bea1; 
  --eyelids-opacity: 1;
}

use[data-outlaw="2"] {
  --eyelids-colour: #ba7e5e; 
  --eyelids-opacity: 0;
}

이와 같은 CSS 사용자 정의 속성 전달에 대한 지원은 확실하며 모든 최신 브라우저는 이 동작을 올바르게 처리합니다. 다양한 색상의 아이콘 시스템을 시작으로 이 기술을 사용해 온 몇 가지 방법을 보여드리겠습니다.

다양한 색상의 아이콘 시스템

아이콘 세트를 유지해야 하는 경우 아이콘을 한 번만 정의하면 됩니다. 그런 다음 사용자 정의 속성을 사용하여 색상과 효과를 적용합니다. 모든 테마에 대해 SVG를 복제할 필요 없이 use 그 자체의 가치를 지닐 수 있습니다.

여러 Bluesky 아이콘의 채우기 색상에 대한 사용자 정의 속성
여러 Bluesky 아이콘의 채우기 색상에 대한 사용자 정의 속성입니다. (큰 미리보기)

예를 들어, 저는 --icon-fill 기본값에 대한 사용자 정의 속성 fill 색상 이 Bluesky 아이콘에서:


  

그런 다음 해당 아이콘의 모양을 변경해야 할 때마다(예:

그리고

— 나는 새로운 것을 통과할 수 있다 fill 각 인스턴스의 색상 값:

이러한 아이콘은 모양은 동일하지만 인라인 스타일로 인해 다르게 보입니다.

CSS 사용자 정의 속성을 사용한 데이터 시각화

우리는 사용할 수 있습니다 그리고 훨씬 더 실용적인 방법으로요. 가벼운 데이터 시각화를 만드는 데도 도움이 되므로 서부의 유명한 보안관 세 명인 Wyatt Earp, Pat Garrett, Bat Masterson에 대한 인포그래픽을 상상해 보세요.

CSS 사용자 정의 속성을 사용한 데이터 시각화
CSS 사용자 정의 속성을 사용한 데이터 시각화. (큰 미리보기)

각 보안관의 프로필은 동일한 SVG 세 가지 기호 집합을 사용합니다. 하나는 보안관의 경력 기간을 나타내는 막대용이고, 다른 하나는 체포된 횟수를 나타내는 막대용이고, 또 다른 하나는 살인 횟수를 나타내는 막대용입니다. 사용자 정의 속성 값을 각각에 전달 인스턴스는 SVG를 복제하지 않고도 막대 길이를 변경하고, 크기를 제한하고, 색상을 없앨 수 있습니다. 먼저 해당 항목에 대한 기호를 만들었습니다.


  
    
  
  
  
    
  
  
  
    
  

각 기호는 하나 이상의 값을 허용합니다.

  • --career-length 조정합니다 width 커리어 바의.
  • --career-colour 변경 fill 그 막대의 색깔.
  • --arrest-scale 체포 배지 크기를 제어합니다.
  • --kill-colour 정의합니다 fill 처치 아이콘의 색상입니다.

나는 이것을 사용하여 각 보안관의 프로필을 개발할 수 있습니다. Wyatt Earp으로 시작하는 다양한 인라인 스타일의 요소.

동일한 기호 요소를 공유하지만 인라인 변수는 색상과 크기를 변경합니다. 이러한 값에 애니메이션을 적용하여 차이점을 강조할 수도 있습니다.

@keyframes pulse {
  0%, 100% { --arrest-scale: 1; }
  50% { --arrest-scale: 1.2; }
}

use[href="#arrests-badge"]:hover {
  animation: pulse 1s ease-in-out infinite;
}

CSS 사용자 정의 속성은 스타일 지정에만 도움이 되는 것이 아닙니다. 또한 HTML과 SVG의 내부 기하학 사이에 데이터를 전달하여 색상, 길이, 규모와 같은 시각적 속성을 체포 횟수, 경력 기간, 살인 횟수와 같은 의미에 바인딩할 수 있습니다.

주변 애니메이션

나는 내 웹 사이트의 Magnificent 7에 대한 애니메이션 그래픽을 만드는 동안 기호 내의 요소에 애니메이션을 적용하는 방법을 배우기 시작했습니다. 복잡성을 줄이고 코드를 더 가볍고 유지 관리하기 쉽게 만들기 위해 각 문자를 한 번 정의하고 SVG에서 재사용해야 했습니다.

내 웹사이트의 Magnificent 7자
내 웹사이트의 Magnificent 7 문자입니다. (큰 미리보기)

하지만 저는 그 캐릭터들이 정적인 상태로 유지되는 것을 원하지 않았습니다. 나는 그것들에 생명을 불어넣을 미묘한 움직임이 필요했습니다. 나는 그들의 눈이 깜박이고, 발이 두드리며, 콧수염 수염이 꿈틀거리기를 원했습니다. 따라서 이러한 세부 사항에 애니메이션을 적용하기 위해 깜박임부터 시작하여 CSS 사용자 정의 속성을 사용하여 해당 기호 내부의 요소에 애니메이션 데이터를 전달합니다.

무법자의 눈 위에 SVG 그룹을 배치한 다음 그 그룹을 변경하여 깜박임 효과를 구현했습니다. opacity.

눈꺼풀의 불투명도에 애니메이션을 적용하여 깜박이는 효과.
눈꺼풀의 불투명도에 애니메이션을 적용하여 깜박이는 효과. (큰 미리보기)

이를 가능하게 하기 위해 CSS 사용자 정의 속성이 포함된 인라인 스타일을 그룹에 추가했습니다.

그런 다음 다음을 변경하여 깜박이는 애니메이션을 정의했습니다. --eyelids-opacity:

@keyframes blink {
  0%, 92% { --eyelids-opacity: 0; }
  93%, 94% { --eyelids-opacity: 1; }
  95%, 97% { --eyelids-opacity: 0.1; }
  98%, 100% { --eyelids-opacity: 0; }
}

…그리고 이를 모든 캐릭터에 적용했습니다.

use[data-outlaw] {
  --blink-duration: 4s;
  --eyelids-opacity: 1;
  animation: blink var(--blink-duration) infinite var(--blink-delay);
}

…각 캐릭터가 동시에 깜박이지 않도록 다른 설정을 했습니다. --blink-delay 모두 깜박이기 전에 다른 사용자 정의 속성을 전달합니다.

use[data-outlaw="1"] { --blink-delay: 1s; }
use[data-outlaw="2"] { --blink-delay: 2s; }

use[data-outlaw="7"] { --blink-delay: 3s; }
발의 회전을 애니메이션화하여 발 태핑 효과
발의 회전을 애니메이션화하여 발 태핑 효과를 제공합니다. (큰 미리보기)

일부 캐릭터가 발을 탭하기 때문에 해당 그룹에도 CSS 사용자 정의 속성이 포함된 인라인 스타일을 추가했습니다.


  

발 두드리기 애니메이션 정의:

@keyframes tapping {
  0%, 60%, 100% { --foot-rotate: 0deg; }
  20% { --foot-rotate: -5deg; }
  40% { --foot-rotate: 2deg; }
}

그리고 캐릭터 선언에 추가 사용자 정의 속성을 추가합니다.

use[data-outlaw] {
  --blink-duration: 4s;
  --eyelids-opacity: 1;
  --foot-rotate: 0deg;
  animation: 
    blink var(--blink-duration) infinite var(--blink-delay),
    tapping 1s ease-in-out infinite;
}
콧수염의 번역에 애니메이션을 적용하여 흔들리는 효과
콧수염의 번역에 애니메이션을 적용하여 흔들리는 효과를 줍니다. (큰 미리보기)

…마지막으로 그의 콧수염이 어떻게 변형되는지 설명하는 CSS 사용자 정의 속성을 사용하여 인라인 스타일을 통해 캐릭터의 수염이 흔들리도록 만들기 전에:


  
    
  

흔들림 애니메이션 정의:

@keyframes jiggle {
  0%, 100% { --jiggle-x: 0px; }
  20% { --jiggle-x: -3px; }
  40% { --jiggle-x: 2px; }
  60% { --jiggle-x: -1px; }
  80% { --jiggle-x: 4px; }
}

그리고 해당 속성을 캐릭터 선언에 추가합니다.

use[data-outlaw] {
  --blink-duration: 4s;
  --eyelids-opacity: 1;
  --foot-rotate: 0deg;
  --jiggle-x: 0px;
  animation: 
    blink var(--blink-duration) infinite var(--blink-delay),
    jiggle 1s ease-in-out infinite,
    tapping 1s ease-in-out infinite;
}

이러한 움직이는 부분을 통해 캐릭터가 생생하게 표현되지만 내 마크업은 눈에 띄게 빈약합니다. 여러 애니메이션을 단일 선언으로 결합함으로써 SVG에 더 많은 요소를 추가하지 않고도 애니메이션의 움직임을 연출할 수 있습니다. 모든 무법자는 동일한 기반을 공유합니다. 그들의 개성은 전적으로 CSS 사용자 정의 속성에서 나옵니다.

함정과 해결책

이 기술은 완벽해 보이지만 피하는 것이 가장 좋은 몇 가지 함정이 있습니다.

  • CSS 사용자 정의 속성은 다음과 같이 참조되는 경우에만 작동합니다. var() 안에 . 그것을 잊어버리면 왜 아무것도 업데이트되지 않는지 궁금할 것입니다. 또한 자연적으로 상속되지 않는 속성은 다음과 같습니다. fill 또는 transform사용해야한다 var() 캐스케이드의 혜택을 누릴 수 있는 가치가 있습니다.
  • 사용자 정의 속성과 함께 대체 값을 포함하는 것이 항상 가장 좋습니다.좋다 opacity: var(--eyelids-opacity, 1); 사용자 정의 속성 값이 적용되지 않은 경우에도 SVG 요소가 올바르게 렌더링되도록 합니다.
  • 인라인 스타일은 다음을 통해 설정됩니다. style 속성이 우선 적용됩니다따라서 인라인 CSS와 외부 CSS를 혼합하는 경우 사용자 정의 속성은 일반적인 계단식 규칙을 따른다는 점을 기억하세요.
  • 언제든지 DevTools를 사용하여 사용자 정의 속성 값을 검사할 수 있습니다. 선택 인스턴스를 만들고 계산된 스타일 패널을 확인하여 어떤 사용자 정의 속성이 활성화되어 있는지 확인하세요.

결론

그만큼 그리고 요소는 SVG의 가장 우아하지만 때로는 실망스러운 측면 중 하나입니다. Shadow DOM 장벽으로 인해 애니메이션이 더 까다로워지지만 CSS 사용자 정의 속성은 브리지 역할을 합니다.. 눈에 보이지 않는 경계를 넘어 색상, 모션, 개성을 전달할 수 있어 더욱 깔끔하고 가벼우며 무엇보다도 재미있는 애니메이션을 만들 수 있습니다.

스매싱 사설
(gg, yk)

출처 참조

Post Comment

당신은 놓쳤을 수도 있습니다