I am the author of a collection of animated SVG theme-toggles. I have noticed that any which involve translating a mask are extremely choppy on chromium browsers but are fine on Firefox.
The toggles in question are Classic and Expand
The animations are seemingly throttled possibly due to Chromium thinking the masks is out of view. Whilst the issue seems to persist for the majority of the time, there are a few occasions where they do work on Chromium, I have no explanation as to why they sometimes work.
Any help in solving this issue would be greatly appreciated. I have found a similar issue with Firefox described here but haven't fully figured out the cause of worked out a solution.
.theme-toggle {
font-size: 10rem;
}
<link href="https://cdn.jsdelivr.net/npm/theme-toggles@3.5.1/css/classic.min.css" rel="stylesheet"/>
<label class="theme-toggle">
<input type="checkbox" />
<span class="theme-toggle-sr">Toggle theme</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
stroke-linecap="round"
class="theme-toggle__classic"
viewBox="0 0 32 32"
>
<mask id="theme-toggle__classic__cutout" color="#000">
<path fill="#fff" d="M0 0h32v32H0z" />
<circle cx="34" cy="2" r="8" />
</mask>
<circle
cx="16"
cy="16"
r="9.34"
mask="url(#theme-toggle__classic__cutout)"
/>
<g
stroke="currentColor"
class="theme-toggle__classic__sun-rays"
mask="url(#theme-toggle__classic__cutout)"
>
<path d="M16 5.5v-4" />
<path d="M16 30.5v-4" />
<path d="M1.5 16h4" />
<path d="M26.5 16h4" />
<path d="m23.4 8.6 2.8-2.8" />
<path d="m5.7 26.3 2.9-2.9" />
<path d="m5.8 5.8 2.8 2.8" />
<path d="m23.4 23.4 2.9 2.9" />
</g>
</svg>
</label>
This seems at least to improve performance in Chromium. I have made three changes:
transform
, but the d
path data directly. For both Chrome (99) and Firefox (98) you can now write the CSS syntax d: path('...')
and animate the path data. It doesn't work yet with Safari..theme-toggle.theme-toggle--reversed .theme-toggle__classic {
transform: scale(-1,1)
}
.theme-toggle {
--theme-toggle__classic--duration: 750ms
}
.theme-toggle__classic * {
transition-property: opacity,transform,d;
transition-timing-function: cubic-bezier(0,0,0.15,1.25);
transform-origin: center;
transition-duration: var(--theme-toggle__classic--duration);
transition-delay: calc(var(--theme-toggle__classic--duration) / 5);
}
.theme-toggle__classic #theme-toggle__classic__cutout path {
transition-delay: 0s;
d: path('M0-10h34v4a8 8 0 108 8h1v32h-43z');
}
.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic .theme-toggle__classic__sun-rays *,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic .theme-toggle__classic__sun-rays * {
transform: scale(.5) rotate(45deg);
opacity: 0;
transition-delay: 0s
}
.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic #theme-toggle__classic__cutout path,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic #theme-toggle__classic__cutout path {
d: path('M-11 0h34v4a8 8 0 108 8h1v32h-43z');
transition-delay: calc(var(--theme-toggle__classic--duration) / 5)
}
button.theme-toggle,label.theme-toggle {
border: none;
background: 0 0;
cursor: pointer
}
button.theme-toggle input[type=checkbox],label.theme-toggle input[type=checkbox] {
display: none
}
button.theme-toggle .theme-toggle-sr,label.theme-toggle .theme-toggle-sr {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border-width: 0
}
.theme-toggle {
font-size: 10rem;
}
<label class="theme-toggle">
<input type="checkbox" />
<span class="theme-toggle-sr">Toggle theme</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
stroke-linecap="round"
class="theme-toggle__classic"
viewBox="0 0 32 32"
>
<clipPath id="theme-toggle__classic__cutout">
<path />
</clipPath>
<g clip-path="url(#theme-toggle__classic__cutout)">
<circle cx="16" cy="16" r="9.34" />
<g
stroke="currentColor"
class="theme-toggle__classic__sun-rays"
>
<path d="M16 5.5v-4" />
<path d="M16 30.5v-4" />
<path d="M1.5 16h4" />
<path d="M26.5 16h4" />
<path d="m23.4 8.6 2.8-2.8" />
<path d="m5.7 26.3 2.9-2.9" />
<path d="m5.8 5.8 2.8 2.8" />
<path d="m23.4 23.4 2.9 2.9" />
</g>
</g>
</svg>
</label>