Search code examples
htmlcssstylestoggle

Checkbox toggle square getting lost


I have been working on a custom-styled checkbox, but for some reason, the square when the toggle is checked is getting lost.

Anyone could please point out what I did wrong with this checkbox?

https://jsfiddle.net/d67k5uyq/6/

HTML

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>switch toggle menu using html css only</title>
   </head>
   <body>
      <div class="container">
      
        <div>
          <input type="checkbox" class="toggle" id="default">
          <label for="default" data-checked="Checked" data-unchecked="Unchecked"></label>      
        </div>
        
     </div>
   </body>
</html>

I believe is something to do with the before and after where I'm forgetting to set some value.

CSS

body{
  background: #485461;
  font-family: sans-serif;
  height: 100vh;
  overflow: hidden;
}

.container{
  margin: 0 auto;
  text-align: center;
  padding-top: 30px;
  color: white; 
}

input[type=checkbox].toggle{
  display: none;
}

input[type=checkbox].toggle + label{
  display: inline-block;
  height: 60px;
  width: 200px;
  position: relative;
  font-size:20px;
  border: 4px solid white;
  padding: 0;
  margin: 0;
  cursor: pointer;
  box-sizing: border-box;
  transition: all 0.3s ease; 
}

input[type=checkbox].toggle + label:before{
  position: absolute;
  top: 4px;
  height: 44px;
  width: 44px;
  content: '';
  transition: all 0.3s ease;
  z-index: 3;
}

input[type=checkbox].toggle + label:after{
  width: 140px;
  text-align: center;
  z-index: 2;
  text-transform: uppercase;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  text-overflow: ellipsis;
  overflow: hidden;
 }

input[type=checkbox].toggle:not(:checked) + label{
 background-color: transparent;
 text-align: right;
}

input[type=checkbox].toggle:not(:checked) + label:after{
  content: attr(data-unchecked);
  right: 0;
  left: auto;
  opacity: 1;
  color: white;
}

input[type=checkbox].toggle:not(:checked) + label:before{
   left: 4px;
   background-color: white;
}

input[type=checkbox].toggle:checked + label{
   text-align: left;
   border-color: yellow;
}

input[type=checkbox].toggle:checked + label:after{
   content: attr(data-checked);
   left: 4px;
   right: auto;
   opacity: 1;
   color: white;
}

input[type=checkbox].toggle:checked + label:before{
   left: 144px;
   border-color: yellow;
}

Solution

  • When the input is unchecked then the before pseudo element is given a background color of white.

    When it is checked then it is given a color to the border, but the border has not been given any width.

    Assuming you want a yellow bordered square the this snippet not only sets the border color but also solid and 1px width.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>switch toggle menu using html css only</title>
      <style>
        body {
          background: #485461;
          font-family: sans-serif;
          height: 100vh;
          overflow: hidden;
        }
        
        .container {
          margin: 0 auto;
          text-align: center;
          padding-top: 30px;
          color: white;
        }
        
        input[type=checkbox].toggle {
          display: none;
        }
        
        input[type=checkbox].toggle+label {
          display: inline-block;
          height: 60px;
          width: 200px;
          position: relative;
          font-size: 20px;
          border: 4px solid white;
          padding: 0;
          margin: 0;
          cursor: pointer;
          box-sizing: border-box;
          transition: all 0.3s ease;
        }
        
        input[type=checkbox].toggle+label::before {
          position: absolute;
          top: 4px;
          height: 44px;
          width: 44px;
          content: '';
          transition: all 0.3s ease;
          z-index: 3;
        }
        
        input[type=checkbox].toggle+label::after {
          width: 140px;
          text-align: center;
          z-index: 2;
          text-transform: uppercase;
          position: absolute;
          top: 50%;
          transform: translateY(-50%);
          text-overflow: ellipsis;
          overflow: hidden;
          content: 'A';
        }
        
        input[type=checkbox].toggle:not(:checked)+label {
          background-color: transparent;
          text-align: right;
        }
        
        input[type=checkbox].toggle:not(:checked)+label::after {
          content: attr(data-unchecked);
          right: 0;
          left: auto;
          opacity: 1;
          color: white;
        }
        
        input[type=checkbox].toggle:not(:checked)+label::before {
          left: 4px;
          background-color: white;
        }
        
        input[type=checkbox].toggle:checked+label {
          text-align: left;
          border-color: yellow;
        }
        
        input[type=checkbox].toggle:checked+label::after {
          content: attr(data-checked);
          left: 4px;
          right: auto;
          opacity: 0.5;
          color: white;
        }
        
        input[type=checkbox].toggle:checked+label::before {
          left: 144px;
          border-color: yellow;
          border-style: solid;
          border-width: 1px;
        }
      </style>
    
    </head>
    
    <body>
      <div class="container">
    
        <div>
          <input type="checkbox" class="toggle" id="default">
          <label for="default" data-checked="Checked" data-unchecked="Unchecked"></label>
        </div>
    
      </div>
    </body>
    
    </html>