포인터 이벤트 속성으로 SVG 상호 작용 관리하기

게시 됨: 2022-03-10
요약 요약 ↬ pointer-events 속성을 사용하여 SVG 이미지의 상호 작용을 형성하는 방법, 즉 문서의 어느 부분이 클릭, 터치 또는 탭을 받을 수 있는지 제어하는 ​​방법을 살펴보겠습니다.

아래 SVG 이미지를 클릭하거나 탭해 보세요. 포인터를 올바른 위치(음영 처리된 경로)에 놓으면 새 브라우저 탭에서 Smashing Magazine 홈페이지가 열릴 것입니다. 공백을 클릭하려고 하면 오히려 혼란스러울 수 있습니다.

CodePen에서 Tiffany Brown(@webinista)의 Pen Amethyst를 참조하십시오.

CodePen에서 Tiffany Brown(@webinista)의 Pen Amethyst를 참조하십시오.

이것은 SVG 이미지 내에 링크를 포함하는 최근 프로젝트에서 내가 직면한 딜레마입니다. 가끔 이미지를 클릭하면 링크가 작동했습니다. 다른 시간에는 그렇지 않았습니다. 혼란스럽죠?

어떤 일이 일어날 수 있고 SVG가 수정 사항을 제공하는지 여부에 대해 자세히 알아보기 위해 SVG 사양을 살펴보았습니다. 답: pointer-events .

점프 후 더! 아래에서 계속 읽기 ↓

DOM ( 문서 객체 모델) 포인터 이벤트와 혼동 하지 마십시오. 포인터 pointer-events 는 CSS 속성이자 SVG 요소 속성입니다. 이를 통해 SVG 문서 또는 요소의 어느 부분이 마우스, 트랙패드 또는 손가락과 같은 포인팅 장치에서 이벤트를 수신할 수 있는지 관리할 수 있습니다.

용어에 대한 참고 사항: "포인터 이벤트"는 사용자 입력을 위한 장치에 구애받지 않는 웹 플랫폼 기능의 이름이기도 합니다. 그러나 이 기사에서 - 그리고 pointer-events 속성의 목적을 위해 - "포인터 이벤트"라는 문구에는 마우스 및 터치 이벤트도 포함됩니다.

상자 밖에서: SVG의 "모양 모델"

CSS를 HTML과 함께 사용하면 HTML에 상자 레이아웃 모델이 적용됩니다. 상자 레이아웃 모델에서 모든 요소는 내용 주위에 직사각형을 생성합니다. 그 사각형은 인라인, 인라인 수준, 원자 인라인 수준 또는 블록일 수 있지만 여전히 4개의 직각과 4개의 모서리가 있는 사각형입니다. 요소에 링크나 이벤트 리스너를 추가하면 대화형 영역이 사각형의 크기와 일치합니다.

참고 : 대화형 요소에 clip-path 를 추가하면 대화형 요소의 경계가 변경됩니다. 즉, 육각형 clip-path 경로 a 요소에 추가하면 클리핑 경로 내의 포인트만 클릭할 수 있습니다. 유사하게, 기울이기 변형을 추가하면 직사각형이 마름모꼴로 바뀝니다.

SVG에는 상자 레이아웃 모델이 없습니다. SVG 문서가 HTML 문서에 포함될 때 CSS 레이아웃 내에서 루트 SVG 요소는 상자 레이아웃 모델을 따릅니다. 자식 요소는 그렇지 않습니다. 결과적으로 대부분의 CSS 레이아웃 관련 속성은 SVG에 적용되지 않습니다.

따라서 SVG에는 제가 '모양 모델'이라고 부르는 것이 있습니다. SVG 문서나 요소에 링크나 이벤트 리스너를 추가할 때 대화형 영역이 반드시 직사각형일 필요는 없습니다. SVG 요소 에는 경계 상자가 있습니다. 경계 상자는 다음과 같이 정의됩니다. 요소와 해당 하위 요소를 완전히 둘러싸는 해당 요소의 사용자 좌표계 축과 정렬된 가장 꼭 맞는 직사각형. 그러나 처음에는 SVG 문서의 어떤 부분이 대화형인지 여부가 표시 및/또는 페인팅 되는 부분에 따라 다릅니다.

그려진 요소와 보이는 요소

SVG 요소는 "채워질" 수 있지만 "스트로크"할 수도 있습니다. 채우기 는 모양의 내부를 나타냅니다. 뇌졸중 은 윤곽을 나타냅니다.

"채우기"와 "획"은 함께 요소를 화면이나 페이지( 캔버스 라고도 함)에 렌더링하는 페인팅 작업 입니다. 칠해진 요소 에 대해 이야기할 때 요소에 채우기 및/또는 획이 있음을 의미합니다. 일반적으로 이는 요소도 표시됨을 의미합니다.

그러나 SVG 요소는 표시되지 않고 칠할 수 있습니다. 이것은 visible 속성 값이나 CSS 속성이 hidden 있거나 displaynone 인 경우 발생할 수 있습니다. 요소는 거기에 있고 이론적 공간을 차지합니다. 우리는 그것을 볼 수 없습니다(그리고 보조 기술이 그것을 감지하지 못할 수도 있습니다).

아마도 더 혼란스럽게도 요소는 페인트되지 않고 표시될 수 있습니다. 즉, 표시되는 visibility 값이 visible 됩니다. 이는 요소에 획과 채우기가 모두 없는 경우에 발생합니다.

참고 : 알파 투명도가 있는 색상 값(예: rgba(0,0,0,0) )은 요소가 그려지거나 표시되는지 여부에 영향을 주지 않습니다. 즉, 요소에 알파 투명 채우기 또는 획이 있으면 볼 수 없어도 칠해집니다.

요소가 그려지거나 표시되거나 둘 다 표시되지 않는 시점을 아는 것은 각 pointer-events 값의 영향을 이해하는 데 중요합니다.

모두 또는 없음 또는 그 사이에 있는 것: 값

pointer-events 는 CSS 속성이자 SVG 요소 속성입니다. 초기 값은 auto 이며, 이는 칠해진 부분과 보이는 부분만 포인터 이벤트를 수신함을 의미합니다. 대부분의 다른 값은 두 그룹으로 나눌 수 있습니다.

  1. 요소가 표시되어야 하는 값. 그리고
  2. 그렇지 않은 값.

painted , fill , strokeall 후자의 범주에 속합니다. 가시성 종속 대응물( visiblePainted , visibleFill , visibleStrokevisible )은 전자에 속합니다.

SVG 2.0 사양은 또한 bounding-box 값을 정의합니다. pointer-events 값이 bounding-box 인 경우 요소 주변의 직사각형 영역도 포인터 이벤트를 수신할 수 있습니다. 이 글을 쓰는 시점에서 Chrome 65+만 bounding-box 지원합니다.

none 도 유효한 값입니다. 요소와 그 자식이 포인터 이벤트를 수신하는 것을 방지합니다. pointer-events CSS 속성은 HTML 요소에도 사용할 수 있습니다. 그러나 HTML과 함께 사용하는 경우 autonone 만 유효한 값입니다.

pointer-events 값은 설명된 것보다 더 잘 설명되어 있으므로 몇 가지 데모를 살펴보겠습니다.

여기에 채우기와 획이 적용된 원이 있습니다. 그것은 칠해져 있고 볼 수 있습니다 . 전체 원은 포인터 이벤트를 받을 수 있지만 원 외부 영역은 받을 수 없습니다.

CodePen에서 Tiffany Brown(@webinista)이 SVG로 그린 Pen Visible vs.를 참조하십시오.

CodePen에서 Tiffany Brown(@webinista)이 SVG로 그린 Pen Visible vs.를 참조하십시오.

값이 none 이 되도록 채우기를 비활성화합니다. 이제 원의 내부를 가리키거나 클릭하거나 탭하려고 해도 아무 일도 일어나지 않습니다. 그러나 획 영역에 대해 동일한 작업을 수행하면 포인터 이벤트가 계속 전달됩니다. fill 값을 none 으로 변경하면 이 영역이 표시 되지만 칠해 지지는 않습니다.

마크업을 약간 변경해 보겠습니다. fill=none 을 유지하면서 pointer-events="visible"circle 요소에 추가할 것입니다.

포인터 이벤트를 추가하는 방법: 모두 CodePen에서 Tiffany Brown(@webinista)의 상호 작용에 영향을 미칩니다.

포인터 이벤트를 추가하는 방법: 모두 CodePen에서 Tiffany Brown(@webinista)의 상호 작용에 영향을 미칩니다.

이제 획으로 둘러싸인 도색되지 않은 영역이 포인터 이벤트를 수신할 수 있습니다.

SVG 이미지의 클릭 가능한 영역 확대

이 기사의 시작 부분에서 이미지로 돌아가 봅시다. 우리의 "자수정"은 각각 strokefill 가 있는 다각형 그룹과 달리 path 요소입니다. 그것은 우리가 단순히 pointer-events="all" 을 추가하고 그것을 하루라고 부를 수 없다는 것을 의미합니다.

대신 클릭 영역을 확대해야 합니다. 그려진 요소와 보이는 요소에 대해 알고 있는 것을 사용합시다. 아래 예에서는 이미지 마크업에 사각형을 추가했습니다.

CodePen에서 Tiffany Brown(@webinista)의 SVG 이미지의 클릭 영역 확대를 참조하십시오.

CodePen에서 Tiffany Brown(@webinista)의 SVG 이미지의 클릭 영역 확대를 참조하십시오.

이 사각형은 보이지 않지만 여전히 기술적으로 볼 수 있습니다(예: visibility: visible ). 그러나 채우기가 없다는 것은 칠해 지지 않았음을 의미합니다. 우리의 이미지는 똑같아 보입니다. 실제로 여전히 동일하게 작동합니다. 공백을 클릭해도 탐색 작업이 트리거되지 않습니다. 여전히 pointer-events 속성 a 요소에 추가해야 합니다. visible 값 또는 all 값을 사용하면 여기에서 작동합니다.

CodePen에서 Tiffany Brown(@webinista)의 SVG 이미지의 클릭 영역 확대를 참조하십시오.

CodePen에서 Tiffany Brown(@webinista)의 SVG 이미지의 클릭 영역 확대를 참조하십시오.

이제 전체 이미지가 포인터 이벤트를 수신할 수 있습니다.

bounding-box 를 사용하면 팬텀 요소가 필요하지 않습니다. 경계 상자 내의 모든 점은 경로로 둘러싸인 공백을 포함하여 포인터 이벤트를 수신합니다. 하지만 다시: pointer-events="bounding-box" 는 널리 지원되지 않습니다. 그럴 때까지 도색되지 않은 요소를 사용할 수 있습니다.

SVG와 HTML pointer-events 사용하기

pointer-events 가 도움이 될 수 있는 또 다른 경우: HTML 버튼 내부에서 SVG 사용.

CodePen에서 Tiffany Brown(@webinista)의 Pen Ovxmmy를 참조하십시오.

CodePen에서 Tiffany Brown(@webinista)의 Pen Ovxmmy를 참조하십시오.

Firefox와 Internet Explorer 11은 예외입니다. event.target 의 값은 HTML 버튼 대신 SVG 요소가 됩니다. 여는 SVG 태그에 pointer-events="none" 을 추가해 보겠습니다.

CodePen에서 Tiffany Brown(@webinista)이 작성한 Pen How 포인터 이벤트: 없음은 SVG 및 HTML과 함께 사용할 수 없습니다.

CodePen에서 Tiffany Brown(@webinista)이 작성한 Pen How 포인터 이벤트: 없음은 SVG 및 HTML과 함께 사용할 수 없습니다.

이제 사용자가 버튼을 클릭하거나 탭하면 event.targetbutton 을 참조합니다.

DOM과 JavaScript에 정통한 사람들은 화살표 함수 대신 function 키워드를 사용하고 event.target 대신 this 를 사용하면 이 문제가 해결된다는 점에 주목합니다. 그러나 pointer-events="none" (또는 pointer-events: none; CSS에서)을 사용하면 특정 JavaScript 단점을 메모리에 커밋할 필요가 없습니다.

결론

SVG는 HTML에 익숙한 것과 같은 종류의 상호 작용을 지원합니다. 클릭이나 탭에 반응하는 차트를 만드는 데 사용할 수 있습니다. CSS 및 HTML 상자 모델을 준수하지 않는 연결된 영역을 만들 수 있습니다. 또한 pointer-events 를 추가하여 SVG 문서가 사용자 상호 작용에 대한 응답으로 동작하는 방식을 개선할 수 있습니다.

SVG pointer-events 에 대한 브라우저 지원은 강력합니다. SVG를 지원하는 모든 브라우저는 SVG 문서 및 요소에 대한 속성을 지원합니다. HTML 요소와 함께 사용하면 지원이 약간 덜 강력합니다. Internet Explorer 10 또는 이전 버전 또는 모든 버전의 Opera Mini에서는 사용할 수 없습니다.

이 부분에서 pointer-events 의 표면을 긁었습니다. 더 심도 있고 기술적인 처리는 SVG 사양을 읽어보십시오. MDN(Mozilla 개발자 네트워크) Web Docs는 예제와 함께 pointer-events 에 대한 보다 웹 개발자 친화적인 문서를 제공합니다.