Salketer
Salketer

Reputation: 15711

CSS applied to SVG group elements but not when used

Basically, I have a little SVG that uses a group to defined a reusable symbole. This group includes a path I want to animate in CSS. The problem I am facing is that only the "original" element gets the CSS applied, the "used" ones do not.

.player_arrow_marker {
  animation-name: player_marker_arrow;
  animation-duration: 1s;
  animation-iteration-count: infinite;
}
@keyframes player_marker_arrow {
  from {
    transform: translate(0px, 0px) scale(1);
  }
  50% {
    transform: translate(0px, 10px) scale(1.1);
  }
  to {
    transform: translate(0px, 0px) scale(1);
  }
}
<svg viewBox="-50 -50 100 100" style="height:120px;">
  <g id="starmap_player_marker_arrow" style="transform: rotate(0deg);">
    <path class="player_arrow_marker" fill="#00AEEF" d="M0,0l-10.971,13.702h5.545L0,20.479l5.425-6.776l5.545,0L0,0z M3.889,12.722L0,17.579l-3.89-4.857h-3.975
	l5.761-7.195L0,8.154l2.104-2.627l5.761,7.195H3.889z"></path>
  </g>
  <use xlink:href="#starmap_player_marker_arrow" style="transform: rotate(90deg);"></use>
  <use xlink:href="#starmap_player_marker_arrow" style="transform: rotate(180deg);"></use>
  <use xlink:href="#starmap_player_marker_arrow" style="transform: rotate(270deg);"></use>

</svg>

As you can see, from the 4 arrows, only the one defined by the is getting targeted by the CSS... How come? And how should one apply CSS rules that would be defined for elements in any instances of a group?

EDIT: Apparently, this is not an issue on all browsers. So my question now becomes more like "What is the cross-browser way to do it?"

Upvotes: 1

Views: 172

Answers (1)

Andy Furniss
Andy Furniss

Reputation: 3914

I've done a bit of Googling and came across this article which was quite insightful: http://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/

I then had a go myself and have come up with the following:

.player_arrow_marker {
  animation-name: player_marker_arrow;
  animation-duration: 1s;
  animation-iteration-count: infinite;
}

@keyframes player_marker_arrow {
  from {
    transform: translate(0px, 0px) scale(1);
  }
  50% {
    transform: translate(0px, 10px) scale(1);
  }
  to {
    transform: translate(0px, 0px) scale(1);
  }
}

.arrow {
    width:45px;
    height:30px;
}
<svg width="0" height="0">
  <symbol id="arrow" width="20" height="20">
    <rect x="0" y="0" width="20" height="20" style="stroke: #000000; fill:none;"/>
  </symbol>
</svg>

<svg class="arrow" viewBox="0 0 45 30">
    <use class="player_arrow_marker" xlink:href="#arrow" x="0" y="0" />
    <use class="player_arrow_marker" xlink:href="#arrow" x="25" y="0" />
</svg>

I tried with your code but I had problems with coordinates or something because half of the arrow kept getting cut off, possibly caused by the path's coordinates. Had a go with just a couple of rectangles as your question was how to get multiple instances animating at the same time.

Hope this helps.

Upvotes: 1

Related Questions