Jan's Development Microblog
| Jan Valkenburg | HTML | Reading time: 4 min

HTML switch control (CSS input toggle)

Safari has introduced the long-awaited new input element: the switch control. Let's dive in and take a look at the old and the new ways of creating toggles.

For years, we have been creating our own switches using HTML and CSS. However, since December 2023, with the release of Safari Technology Preview Release 185, there is a better way to accomplish this.

Code examples of CSS toggles

Today, we still need to write some HTML along with a substantial amount of CSS to create a switch. I have developed two versions of the toggle, both of which can be found in the code below. The first one is a classic toggle and should function correctly in all browsers.

The robust input toggle

<label class="input--switch2">
  <input type="checkbox" hidden>
  <div class="input--switch2-inner"></div>
</label>

.input--switch2 .input--switch2-inner {
  position: relative;
  cursor: pointer;
  
  display: block;
  width: 50px;
  height: 25px;
  
  border: 1px solid;
  border-radius: 2rem;

  background-color: red;
  transition: background-color 500ms;
}
.input--switch2 .input--switch2-inner::after {
    content: "";
    position: absolute;
    top: 2.5px;
    left: 2px;
    
    display: block;
    inline-size: 18px;
    block-size: 18px;
    border-radius: 18px;
    
    border: 1px solid;
    background-color: white;
    transition: left 500ms;
  }
}
.input--switch2 input:checked ~ .input--switch2-inner {
    background-color: green;
}
.input--switch2 input:checked ~ .input--switch2-inner::after {
  left: calc(100% - 22px);
}

More modern CSS input toggle

A more modern approach to achieve this involves utilizing nested CSS with the new :has() function and incorporating other contemporary CSS techniques. This method significantly cleans up the code.

<label class="input--switch">
  <input type="checkbox" hidden>
</label>

.input--switch {
  position: relative;
  cursor: pointer;
  display: inline-block;
  inline-size: 50px;
  block-size: 25px;
  
  border: 1px solid;
  border-radius: 50px;

  background-color: red;
  transition: background-color 500ms;
  &::after {
    content: "";
    position: absolute;
    top: 2.5px;
    left: 2px;
    
    display: block;
    inline-size: 18px;
    block-size: 18px;
    border-radius: 18px;
    
    border: 1px solid;
    background-color: white;
    transition: left 500ms;
  }
  &:has(input:checked) {
    background-color: green;
    &::after {
      left: calc(100% - 22px);
    }
  }
}

The new way of creating input switches

Starting with Safari Technology Preview Release 185 we can ditch all the CSS and extra HTML and we can do the same with one line of HTML.

Example of the new Safari switch control (toggle)
<input type="checkbox" switch>

As you can see pretty simple. The only downside is that I was not able to style it. If I find a way I will update this blog post with it. For now, I assume the Webkit team will fix this in the future, as this input type is kinda fresh. We will have to wait and see. For now, we can take a look at it and test it using Safari Technology Preview and wait until other browsers pick up this future and include it in their browsers.

I have included a CodePen example for all of you, showcasing all the code examples mentioned above. This allows you to view and test it for yourself.

Final word

It is great to see that browser makers are continually implementing new and improved ways to incorporate toggles on our website. Although these new features may still be months or even years away from practical use, they provide a glimpse into the future of the internet.

「私の旅は笑いに満ちていてほしい。」— I want my journey to be full of laughter. - Yuna, Final Fantasy X


Newsletter signup

Stay up to date about my latest blog posts.