Toggle Group Custom Style
Three different looks built only with CSS on the host elements: a connected pill toolbar, multi-select filter chips with an animated checkmark, and an exclusive group with an animated underline. Non-toggle elements inside the groups, like the dividers here, are ignored by the group’s logic. The pill group is a bar of controls, so it carries role="toolbar".
Pill Left Center Right
Chips HTML CSS JavaScript
UnderlineDay Week Month Year
Code
The following example assumes that you have imported the components and set up the theme.
<div class="toggle-style-container"> <!-- Pill toolbar --> <div class="style-column"> <span id="pill-label">Pill</span>
<sv-toggle-group class="pill" role="toolbar" aria-labelledby="pill-label" exclusive value="left"> <sv-toggle value="left">5 collapsed lines
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M120-120v-80h720v80H120Zm0-160v-80h480v80H120Zm0-160v-80h720v80H120Zm0-160v-80h480v80H120Zm0-160v-80h720v80H120Z" ></path> </svg> Left </sv-toggle>
<span class="divider" aria-hidden="true"></span>
<sv-toggle value="center">5 collapsed lines
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M120-120v-80h720v80H120Zm160-160v-80h400v80H280ZM120-440v-80h720v80H120Zm160-160v-80h400v80H280ZM120-760v-80h720v80H120Z" ></path> </svg> Center </sv-toggle>
<span class="divider" aria-hidden="true"></span>
<sv-toggle value="right">5 collapsed lines
<svg class="icon" aria-hidden="true" viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"> <path d="M120-760v-80h720v80H120Zm240 160v-80h480v80H360ZM120-440v-80h720v80H120Zm240 160v-80h480v80H360ZM120-120v-80h720v80H120Z" ></path> </svg> Right </sv-toggle> </sv-toggle-group> </div>
<!-- Filter chips --> <div class="style-column"> <span id="chips-label">Chips</span>
<sv-toggle-group class="chips" aria-labelledby="chips-label" value="css javascript"> <sv-toggle value="html"> <span class="check" aria-hidden="true">✓</span> HTML </sv-toggle>
<sv-toggle value="css"> <span class="check" aria-hidden="true">✓</span> CSS </sv-toggle>
<sv-toggle value="javascript"> <span class="check" aria-hidden="true">✓</span> JavaScript </sv-toggle> </sv-toggle-group> </div>
<!-- Animated underline --> <div class="style-column"> <span id="underline-label">Underline</span>
<sv-toggle-group class="underline-group" aria-labelledby="underline-label" exclusive value="week"> <sv-toggle value="day">Day</sv-toggle> <span class="divider" aria-hidden="true"></span> <sv-toggle value="week">Week</sv-toggle> <span class="divider" aria-hidden="true"></span> <sv-toggle value="month">Month</sv-toggle> <span class="divider" aria-hidden="true"></span> <sv-toggle value="year">Year</sv-toggle> </sv-toggle-group> </div></div>
<style> .toggle-style-container {9 collapsed lines
display: grid; gap: 2em; justify-content: center;
.divider { inline-size: var(--sv-bdr-sz-sm); block-size: 1.2em; background-color: var(--sv-gray-5); } }
.style-column {4 collapsed lines
display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; }
.pill {4 collapsed lines
align-items: stretch; overflow: clip; background-color: var(--sv-gray-6); border-radius: calc(infinity * 1px);
sv-toggle {20 collapsed lines
--tint: color-mix(in srgb, var(--sv-accent) 15%, transparent);
gap: 0.4em; padding: 0.6em 1.4em; background-color: transparent; background-image: linear-gradient(var(--tint), var(--tint)); background-repeat: no-repeat; background-position: center; background-size: 0% 100%; border: none; border-radius: 0; transition: background-size var(--sv-dur) var(--sv-ease), color var(--sv-dur) var(--sv-ease);
.icon { inline-size: 1.2em; block-size: 1.2em; fill: currentcolor; }
&:state(--pressed) { color: var(--sv-accent); background-color: transparent; background-size: 100% 100%; } }
.divider { block-size: auto; } }
.chips { gap: 0.5rem;
sv-toggle {13 collapsed lines
padding: 0.4em 0.9em; background-color: transparent; border-color: var(--sv-gray-4); border-radius: var(--sv-bdr-rad-sm);
.check { inline-size: 0; overflow: hidden; opacity: 0; transition: inline-size var(--sv-dur) var(--sv-ease), opacity var(--sv-dur) var(--sv-ease); }
&:state(--pressed) { color: var(--sv-accent); background-color: color-mix(in srgb, var(--sv-accent) 12%, transparent); border-color: var(--sv-accent);
.check { inline-size: 1.1em; opacity: 1; } } } }
.underline-group { gap: 0.5rem; align-items: center;
sv-toggle {10 collapsed lines
padding: 0.4em 0.2em; color: var(--sv-gray-3); background-color: transparent; background-image: linear-gradient(var(--sv-accent), var(--sv-accent)); background-repeat: no-repeat; background-position: bottom center; background-size: 0% var(--sv-bdr-sz-md); border: none; border-radius: 0; transition-property: color, background-size;
&:state(--pressed) { color: var(--sv-gray-0); background-color: transparent; background-size: 100% var(--sv-bdr-sz-md); } } }</style>