I am animating some strokes belonging to an arrow icon, which works great in all browsers (including IE11), with exception to Safari. For some reason, Safari is rendering small black flecks when stroke
dashes are set to 0
in a stroke-dasharray
rule. My code is below:
<svg aria-hidden="true" class="icon icon--arrow-right" height="24px" viewbox="0 0 24 24" width="24px">
<g>
<path class="stroke stroke--1" d="M4,12 L19.3,12"></path>
<polyline class="stroke stroke--2" points="15.05 7.76 19.3 12 15.05 16.24"></polyline>
</g>
</svg>
.icon {
stroke: currentColor;
fill: none;
shape-rendering: geometricPrecision;
}
.icon--arrow-right .stroke--1 {
stroke-dasharray: 0 15.29;
transition: stroke-dasharray 250ms ease-in-out;
}
.icon--arrow-right.active .stroke--1 {
stroke-dasharray: 15.29 0;
}
.icon--arrow-right .stroke--2 {
stroke-dasharray: 0 6.5 0 6.5;
transition: stroke-dasharray 250ms ease-in-out 250ms;
}
.icon--arrow-right.active .stroke--2 {
stroke-dasharray: 0 0 13 0;
}
Run the snippet below in Safari to recreate the issue.
var el = document.querySelector('.icon');
el.onclick = function() {
el.classList.toggle('active');
}
.icon {
border: 1px solid currentColor;
stroke: currentColor;
fill: none;
shape-rendering: geometricPrecision;
cursor: pointer;
}
.icon--arrow-right .stroke--1 {
stroke-dasharray: 0 15.29;
transition: stroke-dasharray 250ms ease-in-out;
}
.icon--arrow-right.active .stroke--1 {
stroke-dasharray: 15.29 0;
}
.icon--arrow-right .stroke--2 {
stroke-dasharray: 0 6.5 0 6.5;
transition: stroke-dasharray 250ms ease-in-out 250ms;
}
.icon--arrow-right.active .stroke--2 {
stroke-dasharray: 0 0 13 0;
}
<p>Click the button below to toggle the <code>.active</code> class.</p>
<svg aria-hidden="true" class="icon icon--arrow-right" height="24px" viewbox="0 0 24 24" width="24px">
<g>
<path class="stroke stroke--1" d="M4,12 L19.3,12"></path>
<polyline class="stroke stroke--2" points="15.05 7.76 19.3 12 15.05 16.24"></polyline>
</g>
</svg>
<p>In Safari, you will see black flecks where <code>stroke</code> dash lengths are set to <code>0</code> when the icon is not active.
Does anyone know why this is happening in Safari, and how to resolve it, so that the black flecks are not visible when a stroke-dash
is set to 0
.
Not sure exactly what is the issue here, sounds like Safari doesn't really like all this floating coordinates, but your values also sounds quite weird.
Anyway, using a tiny offset for the first value of the polyline's dash-array then using precise values for others will make Safari happy:
(note that I got these values by using Safari's result from each element's getTotalLength()
)
var el = document.querySelector('.icon');
el.onclick = function() {
el.classList.toggle('active');
}
.icon {
border: 1px solid currentColor;
stroke: currentColor;
fill: none;
shape-rendering: geometricPrecision;
cursor: pointer;
}
.icon--arrow-right .stroke--1 {
stroke-dasharray: 0 15.3;
transition: stroke-dasharray 250ms ease-in-out;
}
.icon--arrow-right.active .stroke--1 {
stroke-dasharray: 15.3 0;
}
.icon--arrow-right .stroke--2 {
stroke-dasharray: 0.0001 6.003 0.0001 6.003;
transition: stroke-dasharray 250ms ease-in-out 250ms;
}
.icon--arrow-right.active .stroke--2 {
stroke-dasharray: 0 0 13 0;
}
<p>Click the button below to toggle the <code>.active</code> class.</p>
<svg aria-hidden="true" class="icon icon--arrow-right" height="240px" viewbox="0 0 24 24" width="240px">
<g>
<path class="stroke stroke--1" d="M4,12 L19.3,12"></path>
<polyline class="stroke stroke--2" points="15.05 7.76 19.3 12 15.05 16.24"></polyline>
</g>
</svg>