skip to Main Content

The task I have is to create a tri-state radio button/ switch and change the button to an image.

I have found the following example here. Which gives the following:

enter image description here

Although it’s useful, I specifically need to replace the button itself with an image. So, the button(image) moves when the user toggles it on/ neutral/ off. The look and feel I’m trying to create (where the purple box is an image):

Centred:

enter image description here

Right toggled:

enter image description here

Left toggled:

enter image description here

I’ve used example #1 mentioned here for inspiration, and I’ve tried manipulating the code as follows…

* {
  box-sizing: border-box;
}

body {
  
  background: -webkit-linear-gradient(90deg, #00c6ff 10%, #0072ff 90%); /* Chrome 10+, Saf5.1+ */
  background:    -moz-linear-gradient(90deg, #00c6ff 10%, #0072ff 90%); /* FF3.6+ */
  background:     -ms-linear-gradient(90deg, #00c6ff 10%, #0072ff 90%); /* IE10 */
  background:      -o-linear-gradient(90deg, #00c6ff 10%, #0072ff 90%); /* Opera 11.10+ */
  background:         linear-gradient(90deg, #00c6ff 10%, #0072ff 90%); /* W3C */
        
}

h1 {
  color: white;
  font-size: 2em;
  text-align: center;
  font-family: 'Indie Flower', cursive;
}

.container {
  position: fixed;
  top: 40%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.radio-wrapper {
    width: 145px;
    height: 50px;
    display: inline-block;
    vertical-align: middle;
    background: rgba(0, 0, 0, 0.4);
    border-radius: 30px;
    position: relative;
    margin-left: 1%;
    p {
        position: absolute;
        z-index: 10;
        color: white;
        font-size: 1.7em;
        margin: 0;
        margin-top: 13px;
    }
    .correct {
        left: 17px;
        top: -5px;
    }
    .wrong {
        right: 17px;
        top: -5px;
    }
    .neutral-icon {
        left: 69px;
        top: -8px;
        opacity: .5;
    }
    label {
        z-index: 9;
    }
  img {
      z-index: 100;
  }
}

input[type="radio"] {
    display: none;
}

.ion-close-round { 
  z-index: 99;
  font-size: 18px;
}
.neutral-icon i {
  font-size: 10px;
}
.neutral + img {
    display: inline-block;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    position: absolute;
    left: 33%;
    transition: transform 1s;
}

.neutral:checked + img {
    display: inline-block;
    width: 50px;
    height: 50px;
    border-radius: 100%;
    position: absolute;
    text-align: center;
}

.yes + label {
    display: inline-block;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    position: absolute;
    left: 0;
    text-align: center;
}

.yes:checked + label {
    display: inline-block;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: rgb(32, 213, 50);
    background: -moz-linear-gradient(top, rgba(32, 213, 50, 1) 0%, rgba(28, 195, 1, 1) 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(32, 213, 50, 1)), color-stop(100%, rgba(28, 195, 1, 1)));
    background: -webkit-linear-gradient(top, rgba(32, 213, 50, 1) 0%, rgba(28, 195, 1, 1) 100%);
    background: -o-linear-gradient(top, rgba(32, 213, 50, 1) 0%, rgba(28, 195, 1, 1) 100%);
    background: -ms-linear-gradient(top, rgba(32, 213, 50, 1) 0%, rgba(28, 195, 1, 1) 100%);
    background: linear-gradient(to bottom, rgba(32, 213, 50, 1) 0%, rgba(28, 195, 1, 1) 100%);
    -moz-animation-duration: 0.4s;
    -moz-animation-name: slidein;
    -webkit-animation-duration: 0.4s;
    -webkit-animation-name: slidein;
    animation-duration: 0.4s;
    animation-name: slidein;
    -webkit-transform: translateZ(0);
}

.no + label {
    display: inline-block;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    position: absolute;
    right: 0;
    text-align: center;
}

.no:checked + label {
    display: inline-block;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: red;
    -moz-animation-duration: 0.4s;
    -moz-animation-name: slideno;
    -webkit-animation-duration: 0.4s;
    -webkit-animation-name: slideno;
    animation-duration: 0.4s;
    animation-name: slideno;
    -webkit-transform: translateZ(0);
    background: rgb(230, 108, 103);
    background: -moz-linear-gradient(top, rgba(230, 108, 103, 1) 0%, rgba(221, 79, 75, 1) 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(230, 108, 103, 1)), color-stop(100%, rgba(221, 79, 75, 1)));
    background: -webkit-linear-gradient(top, rgba(230, 108, 103, 1) 0%, rgba(221, 79, 75, 1) 100%);
    background: -o-linear-gradient(top, rgba(230, 108, 103, 1) 0%, rgba(221, 79, 75, 1) 100%);
    background: -ms-linear-gradient(top, rgba(230, 108, 103, 1) 0%, rgba(221, 79, 75, 1) 100%);
    background: linear-gradient(to bottom, rgba(230, 108, 103, 1) 0%, rgba(221, 79, 75, 1) 100%);
}


@keyframes slidein {
    from {
        transform: translate(50px, 0);
    }
    to {
        transform: translate(0px, 0px);
    }
}


@keyframes slideno {
    from {
      transform: translate(-50px,0);
    }
    to {
        transform: translate( 0px, 0px);
    }
}

@keyframes returnLeft {
    from {
        transform: translate(-50px,0);
    }
    to {
        transform: translate(0px,0);
    }
}

@keyframes returnRight {
    from {
        transform: translate(50px,0);
    }
    to {
        transform: translate(0px,0);
    }
}
<h1>Tri-state Toggle Button</h1>
<div class="container">
  <div class="radio-wrapper">
    <p class="correct"><i class="ion-checkmark-round"></i>
    </p>
    <p class="neutral-icon"><i class="ion-record"></i>
    </p>
    <p class="wrong"><i class="ion-close-round"></i></p>
    <input type="radio" name="event" class="yes" id="radio-yes" />

    <label for="radio-yes"></label>

    <input type="radio" name="event" class="neutral" checked id="radio-neutral" img src="[link to image here]"/>
    <img for="radio-neutral"></img>


    <input type="radio" name="event" class="no" id="radio-no" />
    <label for="radio-no"></label>
  </div>
</div>

However, for some reason the button appears behind the radio button wrapper, I also can’t select the central toggle and I can’t seem to fix that…

I get something looking like this:

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    I have found an alternative that does what I'm after.

    It isn't the radio button solution, but it uses a slider and offers three toggle modes.

    Code here:

    .slide-container {
      width: 300px;
    }
    
    .slider {
      -webkit-appearance: none;
      width: 100%;
      height: 10px;
      border-radius: 5px;
      background: grey;
      outline: none;
      opacity: 0.7;
      -webkit-transition: .2s;
      transition: opacity .2s;
    }
    
    .slider:hover {
      opacity: 1;
    }
    
    .slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      appearance: none;
      width: 30px;
      height: 30px;
      border: 0;
        border-radius: 50%;
      background-image: url('https://play-lh.googleusercontent.com/ahJtMe0vfOlAu1XJVQ6rcaGrQBgtrEZQefHy7SXB7jpijKhu1Kkox90XDuH8RmcBOXNn');
      background-size: contain;
      background-position: center center;
      background-repeat: no-repeat;
      cursor: pointer;
    }
    
    .slider::-moz-range-thumb {
      width: 23px;
      height: 24px;
      border: 0;
        border-radius: 50%;
      background-image: url('https://play-lh.googleusercontent.com/ahJtMe0vfOlAu1XJVQ6rcaGrQBgtrEZQefHy7SXB7jpijKhu1Kkox90XDuH8RmcBOXNn');
      background-size: contain;
      background-position: center center;
      background-repeat: no-repeat;
      cursor: pointer;
    }
    <div class="slide-container">
         <input type="range" min="0" max="100" value="50" step="50" class="slider" id="myRange">
    </div>


    1. In HTML: If you don’t need the label on the bar, you can just remove the value of ‘One’ ‘Two’ ‘Three’ or change it but not the id.

    2. In CSS: You may just change the background into background:url("../img/youricon.png") center center no-repeat;
      in the input#one:checked/ input#two:checked/ input#three:checked property.

    I found the reference from here:
    https://www.sliderrevolution.com/resources/styling-radio-buttons/
    hope it could help!

    .switch {
      position: relative;
      width: 14rem;
      padding: 0 1rem;
      font-family: verdana;
      &:before {
        content: '  ';
        position: absolute;
        left: 0;
        z-index: -1;
        width: 100%;
        height: 3rem;
        background: #000;
        border-radius: 30px;
      }
      &__label {
        display: inline-block;
        width: 2rem;
        padding: 1rem;
        text-align: center;
        cursor: pointer;
        transition: color 200ms ease-out;
        &:hover {
          color: white;
        }
      }
      &__indicator {
        width: 4rem;
        height: 4rem;
        position: absolute;
        top: -.5rem;
        left: 0;
        background: blue;
        border-radius: 50%;
        transition: transform 600ms cubic-bezier(.02,.94,.09,.97),
                    background 300ms cubic-bezier(.17,.67,.14,1.03);
        transform: translate3d(1rem,0,0);
      }
    
      input#one:checked ~ .switch__indicator {
        background: PaleGreen;
        transform: translate3d(1.2rem,0,0);
      }
      input#two:checked ~ .switch__indicator {
        background: MediumTurquoise;
        transform: translate3d(5.5rem,0,0);
      }
      input#three:checked ~ .switch__indicator {
        background: PaleVioletRed;
        transform: translate3d(10.6rem,0,0);
      }
      input[type="radio"] {
        &:not(:checked),
        &:checked {
          display: none;
        }
      }
    }
    <div class="switch">
      <input name="switch" id="one" type="radio" checked/>
      <label for="one" class="switch__label">One</label>
      <input name="switch" id="two" type="radio" />
      <label for="two" class="switch__label">Two</label>
      <input name="switch" id="three" type="radio" />
      <label for="three" class="switch__label" >Three</label>
      <div class="switch__indicator" /></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search