Animated Segmented Control in Pure CSS | No JavaScript UI Toggle Animation
Animated Segmented Control in Pure CSS | No JavaScript UI Toggle Animation

Animated Segmented Control in Pure CSS | No JavaScript UI Toggle Animation

Create a beautiful animated segmented control using only plain CSS – no JavaScript required! 🎨
In this tutorial, you’ll learn how to build a smooth UI toggle / segmented button animation using modern CSS features like transitions, pseudo-elements, and flexbox.

This component is perfect for:

  • Tabs & toggles
  • UI dashboards
  • Web apps & landing pages
  • Minimal and modern interfaces

⚡ Lightweight
⚡ Fully responsive
⚡ Beginner friendly

👉 Watch till the end to understand how CSS-only animations work!

HTML:

Create a HTML file and add the following code:

<div class="segmented">
  <label class="segmented-button">
    <input type="radio" name="segmented" checked />
    <i class="fas fa-home"></i> Home
  </label>
  <label class="segmented-button">
    <input type="radio" name="segmented" />
    <i class="fas fa-user"></i> About Us
  </label>
  <label class="segmented-button">
    <input type="radio" name="segmented" />
    <i class="fas fa-code"></i> Skills
  </label>
  <label class="segmented-button">
    <input type="radio" name="segmented" />
    <i class="fas fa-briefcase"></i> Experince
  </label>
  <label class="segmented-button">
    <input type="radio" name="segmented" />
    <i class="fas fa-rocket"></i> Projects
  </label>
  <label class="segmented-button">
    <input type="radio" name="segmented" />
    <i class="fas fa-envelope"></i> Contact Us
  </label>
</div>

CSS:

Create a CSS file and add the following code:

html {
  color-scheme: light dark;
  background-color: light-dark(#FCFDFD, #0C0E12);
  font-family: sans-serif;
  display: grid;
  place-items: center;
  min-height: 100dvh;
}

.segmented {
  --padding: 0.25rem;
  display: flex;
  padding: var(--padding);
  border-radius: 9999px;
  anchor-name: --segmented-button-hover;
  
  &::before,
  &::after {
    content: "";
    position: absolute;
    border-radius: inherit;
    transition: inset 250ms cubic-bezier(0.4, 0, 0.2, 1);
    inset:
      calc(anchor(start) + var(--padding))
      calc(anchor(end) + var(--padding))
      calc(anchor(end) + var(--padding))
      calc(anchor(start) + var(--padding));
  }
  
  &::before {
    background-color: light-dark(#E8E9E9, #1A1C20);
    position-anchor: --segmented-button-hover;
  }
  
  &::after {
    background-color: light-dark(white, #333537);
    position-anchor: --segmented-button-checked;
    box-shadow:
      0 0 0 1px light-dark(#C7C8C8, #484A4C),
      0 1px 3px 0 rgb(0 0 0 / 0.1),
      0 1px 2px -1px rgb(0 0 0 / 0.1);
  }
}

.segmented-button {
  background-color: transparent;
  border: none;
  border-radius: inherit;
  padding: 0.65rem 1.3rem;
  font-size: inherit;
  cursor: default;
  z-index: 1;
  anchor-name: var(--anchor-name-1, --a), var(--anchor-name-2, --b);
  
  &:hover {
    --anchor-name-1: --segmented-button-hover;
  }
  
  &:has(:checked) {
    --anchor-name-2: --segmented-button-checked;
  }
  
  &:has(:focus-visible) {
    outline: 2px solid #007acc;
  }
  
  input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
  }
}

Script:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />

Video:

CSS #PureCSS #WebDesign #UIAnimation #FrontendDevelopment #HTMLCSS #NoJavaScript #UIDesign #CSSAnimation

Happy coding!