Looking to recreate the autoplay toggle button from YouTube using only CSS?

Recently, YouTube discontinued the use of a tag called "paper-toggle-button". As a result, I had to switch to using a regular checkbox in my script. However, I am interested not just in finding a quick fix but in truly understanding how it all works. It is frustrating that despite my efforts, the complex CSS still eludes me.

I have been following tutorials on creating sliding toggle buttons in different ways to replicate YouTube's toggle button appearance. Unfortunately, none of them have matched my expectations. One positive aspect is that the code below does not require any images, which is a plus.

https://i.sstatic.net/GWuc9.png

This task demands a deep level of CSS expertise, which I currently lack.

Here is an example of my attempt, although it looks quite unattractive due to having to manually position the label correctly. Refer to .labelterm. The point at which I got stuck was trying to incorporate a checkmark into this tutorial code.

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
    <title>Awesome checkbox</title>
    <style type="text/css">
        .mylabel {
            position: relative;
            display: block;
            width: 60px;
            height: 30px;
            margin-bottom: 15px;
        }
        .mylabel input {
            display: none;
        }
        .slidinggroove {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background: #ababab;
            border-radius: 20px;
            transition: all 0.3s ease;
        }
        .slidinggroove:after {
            position: absolute;
            content: "";
            width: 28px;
            height: 28px;
            border-radius: 50%;
            background: #fff;
            top: 1px;
            left: 1px;
            transition: all 0.3s ease;
        }
        input:checked + .slidinggroove {
            background: #5fcf80;
        }
        input:checked + .slidinggroove:after {
            transform: translateX(30px);
        }
        .labelterm {
            margin-left: 65px;
            font-size: 16px;
            color: #222;
            font-family: "Roboto", sans-serif;
            position: relative;
            top: 5px;
        }
    </style>
</head>

<body>
    <div class="mylabel">
        <input type="checkbox" id="coding">
        <div class="slidinggroove"></div>
        <label class="mylabel" for="coding" name="skills"><p class="labelterm">Test</p></label>
    </div>
</body>
</html>

Answer №1

To achieve the desired appearance shown in the image, I recommend implementing the following CSS code:

.slidinggroove::before{
  position: absolute;
  left: 7px;
  top: 50%;
  transform: translateY(-7px);
  width: 20px;
  height: 20px;
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  content: "\f00c";
  display: block;
  color: #fff;
}

For importing the icon library as a font, it is advised to use FontAwesome. You can refer to the functional snippet provided here for better understanding:

.mylabel {
  position: relative;
  display: block;
  width: 60px;
  height: 30px;
  margin-bottom: 15px;
}

.mylabel input {
  display: none;
}

.slidinggroove {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: #ababab;
  border-radius: 20px;
  transition: all 0.3s ease;
}

.slidinggroove:after {
  position: absolute;
  content: "";
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #fff;
  top: 1px;
  left: 1px;
  transition: all 0.3s ease;
}

.slidinggroove:before {
  position: absolute;
  left: 7px;
  top: 50%;
  transform: translateY(-7px);
  width: 20px;
  height: 20px;
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  content: "\f00c";
  display: block;
  color: #fff;
}

input:checked+.slidinggroove {
  background: #5fcf80;
}

input:checked+.slidinggroove:after {
  transform: translateX(30px);
}

.labelterm {
  margin-left: 65px;
  font-size: 16px;
  color: #222;
  font-family: "Roboto", sans-serif;
  position: relative;
  top: 5px;
}
<html>

<head>
  <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
  <title>Awesome checkbox</title>
</head>

<body>
  <div class="mylabel">
    <input type="checkbox" id="coding">
    <div class="slidinggroove"></div>
    <label class="mylabel" for="coding" name="skills"><p class="labelterm">Test</p></label>
  </div>
</body>

</html>

The methodology involves creating a pseudo-element with the fontawesome icon unicode as content, offering full customization options such as font-size and color on hover.

Answer №2

Expressing gratitude for your enthusiasm to learn. Let's dissect the problem into smaller parts and address each one before combining them into a comprehensive solution. Here are the components we need:

  1. A background in an oval shape for the toggle to move, referred to as "pit"
  2. A circular knob that can be moved left or right, known as "knob"
  3. The control must have its own state for checked and unchecked, utilizing a native checkbox
  4. The color of the control will change based on its state
  5. Animation features

We should start with the fundamentals. To create the toggle using HTML:

<div class="toggle">
    <input class="toggle__input" type="checkbox"> <span class="toggle__pit"> <span class="toggle__knob"></span>
    </span>
</div>

The toggle acts as the container for the entire toggle. Within it, there is a native checkbox element, toggle__pit, and a toggle__knob. Without any CSS styling, they appear as white squares. Let's style them according to the provided sample image.

.toggle__pit {
  /* set the size */
  width: 36px;
  height: 16px;
  /* define the color */
  background-color: #bababa;
  border: 1px solid #bababa;
  /* create the oval shape, value = height /2 */
  border-radius: 8px;
  /* include border width in the element size */
  box-sizing: border-box;
  /* display span as an inline block element */
  /* spans are inline elements that cannot have width or height assigned*/
  display: inline-block;
}

.toggle__knob {
  /* set the size */
  width: 14px;
  height: 14px;
  /* make it a circle */
  border-radius: 50%;
  background-color: white;
  display: inline-block;
}

.toggle .toggle__input {
  /* keep the checkbox hidden */
  display: none;
}
<div class="toggle">
  <input class="toggle__input" type="checkbox"> <span class="toggle__pit">
                <span class="toggle__knob"></span>
  </span>

</div>

Now, the toggle resembles the sample image but remains in an unchecked state. We need to make it interactive so it responds to user actions. Since the checkbox is hidden, users cannot interact with it directly. By utilizing a <label> element to associate with the input, even when the input is hidden, we can manipulate it. Some modifications to the HTML are necessary to wrap the input within the label.

.toggle__pit {
  /* set the size */
  width: 36px;
  height: 16px;
  /* define the color */
  background-color: #bababa;
  border: 1px solid #bababa;
  /* create the oval shape, value = height /2 */
  border-radius: 8px;
  /* include border width in the element size */
  box-sizing: border-box;
  /* display span as an inline block element */
  /* spans are inline elements that cannot have width or height assigned*/
  display: inline-block;
}

.toggle .toggle__pit::after {
  /* move the knob to the right if the checkbox is checked */
  content: 'L';
  font-family: Helvetica, Arial, Sans-Serif;
  color: white;
  font-size: 12px;
  display: inline-block;
  transform: translateX(4px) translateY(-3px) scaleX(-1) rotate(-40deg);
  transform-origin: 50% 50%;
}

.toggle__knob {
  /* set the size */
  width: 14px;
  height: 14px;
  /* make it a circle */
  border-radius: 50%;
  background-color: white;
  display: inline-block;
  /* position it absolutely */
  position: absolute;
}

.toggle__label {
  /* act as a reference point for positioning the knob */
  position: relative;
  line-height: 16px;
}

.toggle .toggle__input {
  /* keep the checkbox hidden */
  display: none;
}

.toggle .toggle__input:checked+.toggle__pit {
  /* change pit color if the checkbox is checked */
  background-color: #167ac6;
  border: 1px solid #167ac6;
}

.toggle .toggle__input:checked+.toggle__pit .toggle__knob {
  /* move the knob to the right if the checkbox is checked */
  left: 21px;
}
<div class="toggle">
  <label class="toggle__label"> <input class="toggle__input" type="checkbox"> <span class="toggle__pit">
                <span class="toggle__knob"></span>
        </span>
        </label>
</div>

Finally, to ensure smooth state transitions, add some transition properties to toogle__knob and toggle__pit.

.toggle__pit {
  /* set the size */
  width: 36px;
  height: 16px;
  /* define the color */
  background-color: #bababa;
  border: 1px solid #bababa;
  /* create the oval shape, value = height /2 */
  border-radius: 8px;
  /* include border width in the element size */
  box-sizing: border-box;
  /* display span as an inline block element */
  /* spans are inline elements that cannot have width or height assigned */
  display: inline-block;
  transition: background-color 0.5s linear, border 0.5s linear;
}

.toggle .toggle__pit::after {
  /* use L to simulate a tick */
  content: 'L';
  font-family: Helvetica, Arial, Sans-Serif;
  color: white;
  font-size: 12px;
  display: inline-block;
  /* horizontally flip the mock tick and rotate it */
  transform: translateX(4px) translateY(-3px) scaleX(-1) rotate(-40deg);
  transform-origin: 50% 50%;
}

.toggle__knob {
  /* set the size */
  width: 14px;
  height: 14px;
  /* make it a circle */
  border-radius: 50%;
  background-color: white;
  display: inline-block;
  /* position it to the left initially */
  position: absolute;
  left: 1px;
  /* enable animation */
  transition: all 0.5s linear;
}

.toggle__label {
  /* act as a reference point for knob positioning */
  position: relative;
  line-height: 16px;
}

.toggle .toggle__input {
  /* keep the checkbox hidden */
  display: none;
}

.toggle .toggle__input:checked+.toggle__pit {
  /* change pit color if the checkbox is checked */
  background-color: #167ac6;
  border: 1px solid #167ac6;
}

.toggle .toggle__input:checked+.toggle__pit .toggle__knob {
  /* move the knob to the right if the checkbox is checked */
  left: 21px;
}
<div class="toggle">
  <label class="toggle__label"> <input class="toggle__input" type="checkbox"> <span class="toggle__pit">
                <span class="toggle__knob"></span>
        </span>
        </label>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The code is failing to execute the if statement even when the conditions are satisfied, specifically when both variables are NULL

Running a search query with two dropdown lists, encountering an issue where an if-statement does not execute when conditions are met. Specifically, when both dropdown lists are on the default selected option and return a value of NULL. Below is the code s ...

Create a resizable textarea within a flexbox container that allows for scrolling

Hey there! I'm struggling with a Flexbox Container that has three children. The first child contains a textarea, but it's overflowing beyond its parent element. Additionally, I want to make the content within child 2 and 3 scrollable. I've ...

Increase or decrease the quantity of items by cloning with Jquery and dynamically changing the ID

Currently, I am working on a jQuery clone project where I need to dynamically add and delete rows. Despite searching extensively on Stack Overflow and Google, I only have a basic understanding of how jQuery clone works. Any suggestions would be greatly ap ...

What is the best way to display label text beside each other?

I am currently utilizing bootstrap 3 to style my website. I am facing an issue where I cannot get the label text 'mycomp account number' to appear on a single line: .lab { display: inline-block; font-weight: 10px !important; } <section ...

Determine all the child nodes using Xpath

How can I extract all child nodes (option tags) from the following HTML using Html Agility Pack? <select name="akt-miest" id="onoffaci"> <option value="a_0">Všetci</option> <option value="a_1">Iba prihlásení</option> <o ...

The Node js server operates by passively listening for incoming connections rather than actively establishing them

I have been working on setting up a node.js server to send emails to a specific email address using the sendgrid API. Everything was working perfectly until I attempted to deploy the server on Heroku. After deployment, the terminal shows that the server ...

Apply a unique font to the gridview that is not universally available on all systems

Can I use a custom font for my gridview that is accessible to all users, even if it doesn't exist in all systems? Is there a way to include the font in the project folder so that it can be viewed by everyone? ...

The hamburger symbol on my website is failing to show the menu options

I'm having trouble getting my burger icon to display the navigation menu on mobile devices. I've tried adjusting functions in my JavaScript and tweaking the media queries in my CSS file, but the menu still won't show up when the page size is ...

Basic contact form with modal feedback

Hey there, I'm looking for a way to have a regular contact form on my webpage and once it's submitted, display the PHP action in a pop-up modal that says "Thanks for contacting us" before allowing users to close it. I've worked with HTML con ...

Enhancing Your Cytoscape Graph Node with an HTML Label

Currently, I am utilizing cytoscape.js to visually represent relationships between nodes. Specifically, I am trying to generate unique and stylish labels for a single node. My goal is to create more sophisticated label styles than those demonstrated in the ...

Troubleshooting: Css navbar alignment

How can I center the navigation bar both horizontally and vertically? I've tried various methods but nothing seems to work. Here is my HTML: <section class="navigation" ng-controller="NavController"> <div class="nav-container"> ...

What is the best way to deactivate a div along with all its contained elements?

Currently, I am facing an issue where I need to deactivate a div element but I am struggling to find a solution. <div ng-repeat="item in items"> <div ng-click="somefunction()">{{some value}}</div> </div> JavaScript: $scope.items ...

I'm a beginner in Ajax and I'm wondering how I can reset my CSS back to its original value after making an Ajax call. Is there a way to reload the CSS?

Currently, I am utilizing a jQuery ajax() call to fetch a response from a PHP page for form submission/validation purposes. Upon success, the response contains a list of form elements along with corresponding error messages (such as missing field or invali ...

Tips for starting a local HTML website on IE10 with compatibility mode enabled

I am facing an issue with my old HTML+JScript pages that are accessed only from a local hard drive. These pages used to function properly in earlier versions of IE, however, they no longer work in IE10 due to some changes made. Since I did not write the co ...

Turn off hover functionality for mobile and tablet devices

Is there a way to prevent hover effects on mobile and tablet devices for an SVG file used in the img tag? scss file: .menu-link:hover { img { filter: invert(40%) sepia(90%) saturate(2460%) hue-rotate(204deg) brightness(93%) contrast(93%); } .side ...

Rotating the transform causes the div to be pushed beyond the screen boundaries and renders

html, body { margin: 0; padding: 0; overflow-x: hidden; } /*HEADER*/ #header { background: blue; background-attachment: fixed; background-size: cover; width: 100vw; height: 100vh; } .btn-1, .btn-2, .btn-3 { background ...

The issue persists where Tailwind Inline color decorators are unable to function properly alongside CSS variables

In my current project using Tailwind CSS with CSS variables for styling, I have noticed a peculiar issue. The color previewers/decorators that usually appear when defining a color are not showing up in my class names. These previewers are quite helpful in ...

Body of the table spanning the entire width of the screen

Looking for a solution to create a responsive table layout where the thead stretches up to a specified div, while the tbody expands to fill the entire screen width. Is this achievable without using fixed values? https://i.stack.imgur.com/v2ZYx.png It is ...

Convert a string into HTML text using regular expressions

How can you correctly transform a string such as this: html attr = "value" attr2 = 'UnmatchInSubstrings' some \escapedTag content subtag subcontent /subtag br / /html into: <html attr = "value" attr2 = 'UnmatchInSubstrings'&g ...

Validation script needed for data list selection

<form action="order.php" method="post" name="myForm" id="dropdown" onsubmit="return(validate());"> <input list="From" name="From" autocomplete="off" type="text" placeholder="Starting Point"> <datalist id="From"> <option ...