3 State CSS Toggle Switch

I have been looking around for a 3 state toggle switch but haven’t had much luck.

Basically I need a switch that has the states:
| ON | N/A | OFF |

The slider by default starts in the middle, and once the user slides to left or right, they can’t go back to the N/A (not answered) state.

Anyone have any idea on how to handle this?

3

Try something like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.switch-toggle {
width: 10em;
}
.switch-toggle label:not(.disabled) {
cursor: pointer;
}</code>
<code>.switch-toggle { width: 10em; } .switch-toggle label:not(.disabled) { cursor: pointer; }</code>
.switch-toggle {
  width: 10em;
}

.switch-toggle label:not(.disabled) {
  cursor: pointer;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />
<div class="switch-toggle switch-3 switch-candy">
<input id="on" name="state-d" type="radio" checked="" />
<label for="on" onclick="">ON</label>
<input id="na" name="state-d" type="radio" disabled checked="checked" />
<label for="na" class="disabled" onclick=""> </label>
<input id="off" name="state-d" type="radio" />
<label for="off" onclick="">OFF</label>
<a></a>
</div></code>
<code><link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" /> <div class="switch-toggle switch-3 switch-candy"> <input id="on" name="state-d" type="radio" checked="" /> <label for="on" onclick="">ON</label> <input id="na" name="state-d" type="radio" disabled checked="checked" /> <label for="na" class="disabled" onclick=""> </label> <input id="off" name="state-d" type="radio" /> <label for="off" onclick="">OFF</label> <a></a> </div></code>
<link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />

<div class="switch-toggle switch-3 switch-candy">
  <input id="on" name="state-d" type="radio" checked="" />
  <label for="on" onclick="">ON</label>

  <input id="na" name="state-d" type="radio" disabled checked="checked" />
  <label for="na" class="disabled" onclick=""> </label>

  <input id="off" name="state-d" type="radio" />
  <label for="off" onclick="">OFF</label>

  <a></a>
</div>

This will start with N/A as the default option (via checked="checked"), but make it unselectable later (by using disabled)

JSFiddle Demo (Simplified)

12

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.switch-toggle {
float: left;
background: #242729;
}
.switch-toggle input {
position: absolute;
opacity: 0;
}
.switch-toggle input + label {
padding: 7px;
float:left;
color: #fff;
cursor: pointer;
}
.switch-toggle input:checked + label {
background: green;
}</code>
<code>.switch-toggle { float: left; background: #242729; } .switch-toggle input { position: absolute; opacity: 0; } .switch-toggle input + label { padding: 7px; float:left; color: #fff; cursor: pointer; } .switch-toggle input:checked + label { background: green; }</code>
.switch-toggle {
   float: left;
   background: #242729;
}
.switch-toggle input {
  position: absolute;
  opacity: 0;
}
.switch-toggle input + label {
  padding: 7px;
  float:left;
  color: #fff;
  cursor: pointer;
}
.switch-toggle input:checked + label {
  background: green;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> <div class="switch-toggle switch-3 switch-candy">
<input id="on" name="state-d" type="radio" checked="" />
<label for="on" onclick="">ON</label>
<input id="na" name="state-d" type="radio" checked="checked" />
<label for="na" class="disabled" onclick="">N/A</label>
<input id="off" name="state-d" type="radio" />
<label for="off" onclick="">OFF</label>
</div></code>
<code> <div class="switch-toggle switch-3 switch-candy"> <input id="on" name="state-d" type="radio" checked="" /> <label for="on" onclick="">ON</label> <input id="na" name="state-d" type="radio" checked="checked" /> <label for="na" class="disabled" onclick="">N/A</label> <input id="off" name="state-d" type="radio" /> <label for="off" onclick="">OFF</label> </div></code>
 <div class="switch-toggle switch-3 switch-candy">

  <input id="on" name="state-d" type="radio" checked="" />
  <label for="on" onclick="">ON</label>

  <input id="na" name="state-d" type="radio" checked="checked" />
  <label for="na" class="disabled" onclick="">N/A</label>

  <input id="off" name="state-d" type="radio" />
  <label for="off" onclick="">OFF</label>

</div>

2

If you’d like a No / Unset / Yes toggle with coloring, something like this:

Then use the answer from DarkAjax above, but add the following CSS:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.switch-toggle input:checked.toggle-no ~ a {
background-color: red;
}
.switch-toggle input:checked.toggle-yes ~ a {
background-color: green;
}
.switch-toggle input:checked.toggle-unset ~ a {
background-color: grey;
}
</code>
<code>.switch-toggle input:checked.toggle-no ~ a { background-color: red; } .switch-toggle input:checked.toggle-yes ~ a { background-color: green; } .switch-toggle input:checked.toggle-unset ~ a { background-color: grey; } </code>
.switch-toggle  input:checked.toggle-no ~ a {
    background-color:  red;
 }

 .switch-toggle  input:checked.toggle-yes ~ a {
    background-color:  green;
 }

 .switch-toggle  input:checked.toggle-unset ~ a {
    background-color:  grey;
 }

And add the respective classes (class=”toggle-no” , etc.) to the respective radio button inputs. And you can also add icons and such if you’d like.

Hopefully this helps someone!

As a jQuery plugin

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>function filterme(value) {
value = parseInt(value, 10); // Convert to an integer
if (value === 1) {
$('#RangeFilter').removeClass('rangeAll', 'rangePassive').addClass('rangeActive');
$('span').text('Active');
} else if (value === 2) {
$('#RangeFilter').removeClass('rangeActive', 'rangePassive').addClass('rangeAll');
$('span').text('All');
} else if (value === 3) {
$('#RangeFilter').removeClass('rangeAll', 'rangeActive').addClass('rangePassive');
$('span').text('Passive');
}
}</code>
<code>function filterme(value) { value = parseInt(value, 10); // Convert to an integer if (value === 1) { $('#RangeFilter').removeClass('rangeAll', 'rangePassive').addClass('rangeActive'); $('span').text('Active'); } else if (value === 2) { $('#RangeFilter').removeClass('rangeActive', 'rangePassive').addClass('rangeAll'); $('span').text('All'); } else if (value === 3) { $('#RangeFilter').removeClass('rangeAll', 'rangeActive').addClass('rangePassive'); $('span').text('Passive'); } }</code>
function filterme(value) {
  value = parseInt(value, 10); // Convert to an integer
  if (value === 1) {
    $('#RangeFilter').removeClass('rangeAll', 'rangePassive').addClass('rangeActive');
    $('span').text('Active');
  } else if (value === 2) {
    $('#RangeFilter').removeClass('rangeActive', 'rangePassive').addClass('rangeAll');
    $('span').text('All');
  } else if (value === 3) {
    $('#RangeFilter').removeClass('rangeAll', 'rangeActive').addClass('rangePassive');
    $('span').text('Passive');
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="range-field" style=" width:60px">
<input type="range" id="RangeFilter" name="points" onchange="filterme(this.value);" min="1" class="rangeAll" max="3" value="2">
</p>
<span>All</span></code>
<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p class="range-field" style=" width:60px"> <input type="range" id="RangeFilter" name="points" onchange="filterme(this.value);" min="1" class="rangeAll" max="3" value="2"> </p> <span>All</span></code>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="range-field" style=" width:60px">
  <input type="range" id="RangeFilter" name="points" onchange="filterme(this.value);" min="1" class="rangeAll" max="3" value="2">
</p>
<span>All</span>

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>(function($) {
$.fn.removeClasses = function(classes) {
return this.removeClass(classes.join(' '));
};
$.fn.switchify = function(config) {
config = config || {};
var prefix = config.prefix || 'range-';
var onCls = prefix + (config.onCls || 'on' );
var offCls = prefix + (config.offCls || 'off' );
var unsetCls = prefix + (config.unsetCls || 'unset');
var $self = this;
return this.on('change', function(e) {
var value = parseInt(this.value, 10);
switch (value) {
case 1 : return $self.removeClasses([unsetCls, offCls]).addClass(onCls);
case 2 : return $self.removeClasses([onCls, offCls]).addClass(unsetCls);
case 3 : return $self.removeClasses([onCls, unsetCls]).addClass(offCls);
default : return $self;
}
});
};
})(jQuery);
$('#range-filter').switchify({
onCls : 'active',
offCls : 'passive',
unsetCls : 'all'
}).on('change', function(e) {
var $self = $(this);
if ($self.hasClass('range-active')) $('span').text('Active');
else if ($self.hasClass('range-passive')) $('span').text('Passive');
else if ($self.hasClass('range-all')) $('span').text('All');
else $('span').text('Error!');
});</code>
<code>(function($) { $.fn.removeClasses = function(classes) { return this.removeClass(classes.join(' ')); }; $.fn.switchify = function(config) { config = config || {}; var prefix = config.prefix || 'range-'; var onCls = prefix + (config.onCls || 'on' ); var offCls = prefix + (config.offCls || 'off' ); var unsetCls = prefix + (config.unsetCls || 'unset'); var $self = this; return this.on('change', function(e) { var value = parseInt(this.value, 10); switch (value) { case 1 : return $self.removeClasses([unsetCls, offCls]).addClass(onCls); case 2 : return $self.removeClasses([onCls, offCls]).addClass(unsetCls); case 3 : return $self.removeClasses([onCls, unsetCls]).addClass(offCls); default : return $self; } }); }; })(jQuery); $('#range-filter').switchify({ onCls : 'active', offCls : 'passive', unsetCls : 'all' }).on('change', function(e) { var $self = $(this); if ($self.hasClass('range-active')) $('span').text('Active'); else if ($self.hasClass('range-passive')) $('span').text('Passive'); else if ($self.hasClass('range-all')) $('span').text('All'); else $('span').text('Error!'); });</code>
(function($) {
  $.fn.removeClasses = function(classes) {
    return this.removeClass(classes.join(' '));
  };
  $.fn.switchify = function(config) {
    config = config || {};
    var prefix   =           config.prefix   || 'range-';
    var onCls    = prefix + (config.onCls    || 'on'   );
    var offCls   = prefix + (config.offCls   || 'off'  );
    var unsetCls = prefix + (config.unsetCls || 'unset');
    var $self = this;
    return this.on('change', function(e) {
      var value = parseInt(this.value, 10);
      switch (value) {
        case 1  :  return $self.removeClasses([unsetCls, offCls]).addClass(onCls);
        case 2  :  return $self.removeClasses([onCls, offCls]).addClass(unsetCls);
        case 3  :  return $self.removeClasses([onCls, unsetCls]).addClass(offCls);
        default :  return $self;
      }
    });
  };
})(jQuery);

$('#range-filter').switchify({
   onCls    : 'active',
   offCls   : 'passive',
   unsetCls : 'all'
}).on('change', function(e) {
  var $self = $(this);
  if      ($self.hasClass('range-active'))  $('span').text('Active');
  else if ($self.hasClass('range-passive')) $('span').text('Passive');
  else if ($self.hasClass('range-all'))     $('span').text('All');
  else                                      $('span').text('Error!');
});
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.range-field { width: 60px; }</code>
<code>.range-field { width: 60px; }</code>
.range-field { width: 60px; }
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="range-field">
<input type="range" id="range-filter" name="points" min="1" class="rangeAll" max="3" value="2">
</p>
<span>All</span></code>
<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p class="range-field"> <input type="range" id="range-filter" name="points" min="1" class="rangeAll" max="3" value="2"> </p> <span>All</span></code>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="range-field">
  <input type="range" id="range-filter" name="points" min="1" class="rangeAll" max="3" value="2">
</p>
<span>All</span>

2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$(document).ready(function(){
$("#toggle-button1").addClass("active");
$(".tri-state-toggle-button").click(function(){
$(".tri-state-toggle-button").removeClass("active");
var id = $(this).attr('id');
$("#" + id).addClass("active");
});
});</code>
<code>$(document).ready(function(){ $("#toggle-button1").addClass("active"); $(".tri-state-toggle-button").click(function(){ $(".tri-state-toggle-button").removeClass("active"); var id = $(this).attr('id'); $("#" + id).addClass("active"); }); });</code>
$(document).ready(function(){
  $("#toggle-button1").addClass("active");
  $(".tri-state-toggle-button").click(function(){
    $(".tri-state-toggle-button").removeClass("active");
    var id = $(this).attr('id');
    $("#" + id).addClass("active");
  });
});
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>body {
margin-left: 100px;
margin-top: 100px;
}
.tri-state-toggle {
background: rgba(0,0,0,0.8);
box-shadow: inset 0 2px 8px 0 rgba(165,170,174,0.25);
border-radius: 24px;
display: inline-block;
overflow: hidden;
display: inline-flex;
flex-direction: row;
transition: all 500ms ease;
}
.tri-state-toggle-button {
border-radius: 22px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
width: 64px;
background-color: transparent;
border: 0px solid transparent;
margin: 2px;
color: white;
cursor: pointer;
/* -webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out; */
transition: all 0.5s ease;
}
.tri-state-toggle-button.active {
background-image: linear-gradient(
90deg,
rgba(229, 3, 87, 1) 0%,
rgba(229, 3, 56, 1) 35%,
rgba(219, 101, 17, 1) 100%
);
border: 0px solid rgba(207,207,207,0.6);
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.1);
color: white;
font-weight: 500;
transition: all .5s ease-in;
}
.tri-state-toggle-button:focus {
outline: none;
}</code>
<code>body { margin-left: 100px; margin-top: 100px; } .tri-state-toggle { background: rgba(0,0,0,0.8); box-shadow: inset 0 2px 8px 0 rgba(165,170,174,0.25); border-radius: 24px; display: inline-block; overflow: hidden; display: inline-flex; flex-direction: row; transition: all 500ms ease; } .tri-state-toggle-button { border-radius: 22px; height: 44px; display: flex; align-items: center; justify-content: center; width: 64px; background-color: transparent; border: 0px solid transparent; margin: 2px; color: white; cursor: pointer; /* -webkit-transition: all 0.5s ease-in-out; -moz-transition: all 0.5s ease-in-out; -ms-transition: all 0.5s ease-in-out; -o-transition: all 0.5s ease-in-out; */ transition: all 0.5s ease; } .tri-state-toggle-button.active { background-image: linear-gradient( 90deg, rgba(229, 3, 87, 1) 0%, rgba(229, 3, 56, 1) 35%, rgba(219, 101, 17, 1) 100% ); border: 0px solid rgba(207,207,207,0.6); box-shadow: 0 8px 16px 0 rgba(0,0,0,0.1); color: white; font-weight: 500; transition: all .5s ease-in; } .tri-state-toggle-button:focus { outline: none; }</code>
body {
  margin-left: 100px;
  margin-top: 100px;
}

.tri-state-toggle {
    background: rgba(0,0,0,0.8);
    box-shadow: inset 0 2px 8px 0 rgba(165,170,174,0.25);
    border-radius: 24px;
    display: inline-block;
    overflow: hidden;
    display: inline-flex;
    flex-direction: row;
  transition: all 500ms ease; 
}

.tri-state-toggle-button {
    border-radius: 22px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    background-color: transparent;
    border: 0px solid transparent;
    margin: 2px;
    color: white;
    cursor: pointer;
  
/*    -webkit-transition: all 0.5s ease-in-out;
  -moz-transition:    all 0.5s ease-in-out;
  -ms-transition:     all 0.5s ease-in-out;
  -o-transition:      all 0.5s ease-in-out; */
  transition:         all 0.5s ease;
}

.tri-state-toggle-button.active {
    background-image: linear-gradient(
                            90deg,
                            rgba(229, 3, 87, 1) 0%,
                            rgba(229, 3, 56, 1) 35%,
                            rgba(219, 101, 17, 1) 100%
                          );
    border: 0px solid rgba(207,207,207,0.6);
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.1);
    color: white;
    font-weight: 500;
  transition: all .5s ease-in;
}

.tri-state-toggle-button:focus {
  outline: none;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Select any one option:</h3>
<div class="tri-state-toggle">
<button class="tri-state-toggle-button" id="toggle-button1">
Song
</button>
<button class="tri-state-toggle-button" id="toggle-button2">
Video
</button>
<button class="tri-state-toggle-button" id="toggle-button3">
Party
</button>
</div></code>
<code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <h3>Select any one option:</h3> <div class="tri-state-toggle"> <button class="tri-state-toggle-button" id="toggle-button1"> Song </button> <button class="tri-state-toggle-button" id="toggle-button2"> Video </button> <button class="tri-state-toggle-button" id="toggle-button3"> Party </button> </div></code>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Select any one option:</h3>
<div class="tri-state-toggle">

    <button class="tri-state-toggle-button" id="toggle-button1">
        Song
    </button>

    <button class="tri-state-toggle-button" id="toggle-button2">
        Video
    </button>

    <button class="tri-state-toggle-button" id="toggle-button3">
        Party
    </button>

</div>

Additionally to gat’s reply, it’s possible to model this as a grouped radio button through Bootstrap:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="options" id="On" />ON</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="NA" />N/A</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="Off" />OFF</label>
</div>
</code>
<code><div class="btn-group" data-toggle="buttons"> <label class="btn btn-primary"> <input type="radio" name="options" id="On" />ON</label> <label class="btn btn-primary"> <input type="radio" name="options" id="NA" />N/A</label> <label class="btn btn-primary"> <input type="radio" name="options" id="Off" />OFF</label> </div> </code>
<div class="btn-group" data-toggle="buttons">
    <label class="btn btn-primary">
        <input type="radio" name="options" id="On" />ON</label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="NA" />N/A</label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="Off" />OFF</label>
</div>

JSFiddle: http://jsfiddle.net/p7DGe/1/

I created a JSFiddle that demonstrates a fully functional three state switch. Please note that the javascript window in JSfiddle was not working properly so the script is loaded in the html window.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>function togglebutton(range) {
var val = range.value;
if (val == 1) {
//change color of slider background
range.className = "rangeFalse";
//alter text
$('.toggle-false-msg').attr('id', 'textActive');
$('.toggle-neutral-msg').attr('id', '');
$('.toggle-true-msg').attr('id', '');
} else if (val == 2) {
//change color of slider background
range.className = "rangeNeutral";
//alter text
$('.toggle-false-msg').attr('id', '');
$('.toggle-neutral-msg').attr('id', 'textActive');
$('.toggle-true-msg').attr('id', '');
} else if (val == 3) {
//change color of slider background
range.className = "rangeTrue";
//alter text
$('.toggle-false-msg').attr('id', '');
$('.toggle-neutral-msg').attr('id', '');
$('.toggle-true-msg').attr('id', 'textActive');
}
}</code>
<code>function togglebutton(range) { var val = range.value; if (val == 1) { //change color of slider background range.className = "rangeFalse"; //alter text $('.toggle-false-msg').attr('id', 'textActive'); $('.toggle-neutral-msg').attr('id', ''); $('.toggle-true-msg').attr('id', ''); } else if (val == 2) { //change color of slider background range.className = "rangeNeutral"; //alter text $('.toggle-false-msg').attr('id', ''); $('.toggle-neutral-msg').attr('id', 'textActive'); $('.toggle-true-msg').attr('id', ''); } else if (val == 3) { //change color of slider background range.className = "rangeTrue"; //alter text $('.toggle-false-msg').attr('id', ''); $('.toggle-neutral-msg').attr('id', ''); $('.toggle-true-msg').attr('id', 'textActive'); } }</code>
function togglebutton(range) {
  var val = range.value;
  if (val == 1) {
    //change color of slider background
    range.className = "rangeFalse";

    //alter text 
    $('.toggle-false-msg').attr('id', 'textActive');
    $('.toggle-neutral-msg').attr('id', '');
    $('.toggle-true-msg').attr('id', '');
  } else if (val == 2) {
    //change color of slider background
    range.className = "rangeNeutral";

    //alter text 
    $('.toggle-false-msg').attr('id', '');
    $('.toggle-neutral-msg').attr('id', 'textActive');
    $('.toggle-true-msg').attr('id', '');

  } else if (val == 3) {
    //change color of slider background
    range.className = "rangeTrue";

    //alter text 
    $('.toggle-false-msg').attr('id', '');
    $('.toggle-neutral-msg').attr('id', '');
    $('.toggle-true-msg').attr('id', 'textActive');
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.test_div {
height: 50px;
width: 50px;
background: #204d75 !important;
top: 100px;
position: relative;
display: block;
}
.toggle-container {
position: relative;
width: 8em;
margin: 1em;
padding: 0.25em;
border: thin solid lightgrey;
text-align: center;
}
.range-field {
display: inline-block;
width: 100px;
margin: 0px;
border-radius: 2px;
}
input[type=range] {
-webkit-appearance: none;
margin: 0;
width: 100%;
padding: 0px;
outline: none;
border: none;
}
.toggle-false-msg {
display: none;
opacity: .2;
transition: .5s opacity;
display: inline-block;
position: relative;
top: -8px;
}
.toggle-true-msg {
display: none;
opacity: .2;
transition: .5s opacity;
display: inline-block;
position: relative;
top: -8px;
}
.toggle-neutral-msg {
display: none;
opacity: .2;
transition: .5s opacity;
display: none;
position: relative;
top: -8px;
}
#rangeActive {
background-color: blue;
}
#textActive {
opacity: 1;
color: black;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 30px;
cursor: pointer;
animate: 0.2s;
box-shadow: 0px 0px 0px #000000;
background: #3071A9;
border-radius: 0px;
border: 0px solid #000000;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 0px 0px 0px #000000;
border: 0px solid #000000;
height: 30px;
width: 19px;
border-radius: 0px;
background: #FFFFFF;
cursor: pointer;
-webkit-appearance: none;
margin-top: 0px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #3071A9;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 30px;
cursor: pointer;
animate: 0.2s;
box-shadow: 0px 0px 0px #000000;
background: #3071A9;
border-radius: 0px;
border: 0px solid #000000;
}
input[type=range]::-moz-range-thumb {
box-shadow: 0px 0px 0px #000000;
border: 0px solid #000000;
height: 30px;
width: 19px;
border-radius: 0px;
background: #FFFFFF;
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 30px;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #3071A9;
border: 0px solid #000000;
border-radius: 0px;
box-shadow: 0px 0px 0px #000000;
}
input[type=range]::-ms-fill-upper {
background: #3071A9;
border: 0px solid #000000;
border-radius: 0px;
box-shadow: 0px 0px 0px #000000;
}
input[type=range]::-ms-thumb {
box-shadow: 0px 0px 0px #000000;
border: 0px solid #000000;
height: 30px;
width: 19px;
border-radius: 0px;
background: #FFFFFF;
cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
background: #3071A9;
}
input[type=range]:focus::-ms-fill-upper {
background: #3071A9;
}
.rangeFalse::-webkit-slider-runnable-track {
background: #5d0a0a !important;
}
.rangeFalse::-webkit-slider-thumb {
background: white !important;
}
.rangeNeutral::-webkit-slider-runnable-track {
background: #204d75 !important;
}
.rangeNeutral::-webkit-slider-thumb {
background: white !important;
}
.rangeTrue::-webkit-slider-runnable-track {
background: #0e4e1f !important;
}
.rangeTrue::-webkit-slider-thumb {
background: white !important;
}</code>
<code>.test_div { height: 50px; width: 50px; background: #204d75 !important; top: 100px; position: relative; display: block; } .toggle-container { position: relative; width: 8em; margin: 1em; padding: 0.25em; border: thin solid lightgrey; text-align: center; } .range-field { display: inline-block; width: 100px; margin: 0px; border-radius: 2px; } input[type=range] { -webkit-appearance: none; margin: 0; width: 100%; padding: 0px; outline: none; border: none; } .toggle-false-msg { display: none; opacity: .2; transition: .5s opacity; display: inline-block; position: relative; top: -8px; } .toggle-true-msg { display: none; opacity: .2; transition: .5s opacity; display: inline-block; position: relative; top: -8px; } .toggle-neutral-msg { display: none; opacity: .2; transition: .5s opacity; display: none; position: relative; top: -8px; } #rangeActive { background-color: blue; } #textActive { opacity: 1; color: black; } input[type=range]:focus { outline: none; } input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 30px; cursor: pointer; animate: 0.2s; box-shadow: 0px 0px 0px #000000; background: #3071A9; border-radius: 0px; border: 0px solid #000000; } input[type=range]::-webkit-slider-thumb { box-shadow: 0px 0px 0px #000000; border: 0px solid #000000; height: 30px; width: 19px; border-radius: 0px; background: #FFFFFF; cursor: pointer; -webkit-appearance: none; margin-top: 0px; } input[type=range]:focus::-webkit-slider-runnable-track { background: #3071A9; } input[type=range]::-moz-range-track { width: 100%; height: 30px; cursor: pointer; animate: 0.2s; box-shadow: 0px 0px 0px #000000; background: #3071A9; border-radius: 0px; border: 0px solid #000000; } input[type=range]::-moz-range-thumb { box-shadow: 0px 0px 0px #000000; border: 0px solid #000000; height: 30px; width: 19px; border-radius: 0px; background: #FFFFFF; cursor: pointer; } input[type=range]::-ms-track { width: 100%; height: 30px; cursor: pointer; animate: 0.2s; background: transparent; border-color: transparent; color: transparent; } input[type=range]::-ms-fill-lower { background: #3071A9; border: 0px solid #000000; border-radius: 0px; box-shadow: 0px 0px 0px #000000; } input[type=range]::-ms-fill-upper { background: #3071A9; border: 0px solid #000000; border-radius: 0px; box-shadow: 0px 0px 0px #000000; } input[type=range]::-ms-thumb { box-shadow: 0px 0px 0px #000000; border: 0px solid #000000; height: 30px; width: 19px; border-radius: 0px; background: #FFFFFF; cursor: pointer; } input[type=range]:focus::-ms-fill-lower { background: #3071A9; } input[type=range]:focus::-ms-fill-upper { background: #3071A9; } .rangeFalse::-webkit-slider-runnable-track { background: #5d0a0a !important; } .rangeFalse::-webkit-slider-thumb { background: white !important; } .rangeNeutral::-webkit-slider-runnable-track { background: #204d75 !important; } .rangeNeutral::-webkit-slider-thumb { background: white !important; } .rangeTrue::-webkit-slider-runnable-track { background: #0e4e1f !important; } .rangeTrue::-webkit-slider-thumb { background: white !important; }</code>
.test_div {
  height: 50px;
  width: 50px;
  background: #204d75 !important;
  top: 100px;
  position: relative;
  display: block;
}

.toggle-container {
  position: relative;
  width: 8em;
  margin: 1em;
  padding: 0.25em;
  border: thin solid lightgrey;
  text-align: center;
}

.range-field {
  display: inline-block;
  width: 100px;
  margin: 0px;
  border-radius: 2px;
}

input[type=range] {
  -webkit-appearance: none;
  margin: 0;
  width: 100%;
  padding: 0px;
  outline: none;
  border: none;
}

.toggle-false-msg {
  display: none;
  opacity: .2;
  transition: .5s opacity;
  display: inline-block;
  position: relative;
  top: -8px;
}

.toggle-true-msg {
  display: none;
  opacity: .2;
  transition: .5s opacity;
  display: inline-block;
  position: relative;
  top: -8px;
}

.toggle-neutral-msg {
  display: none;
  opacity: .2;
  transition: .5s opacity;
  display: none;
  position: relative;
  top: -8px;
}

#rangeActive {
  background-color: blue;
}

#textActive {
  opacity: 1;
  color: black;
}

input[type=range]:focus {
  outline: none;
}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 30px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000;
  background: #3071A9;
  border-radius: 0px;
  border: 0px solid #000000;
}

input[type=range]::-webkit-slider-thumb {
  box-shadow: 0px 0px 0px #000000;
  border: 0px solid #000000;
  height: 30px;
  width: 19px;
  border-radius: 0px;
  background: #FFFFFF;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: 0px;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: #3071A9;
}

input[type=range]::-moz-range-track {
  width: 100%;
  height: 30px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000;
  background: #3071A9;
  border-radius: 0px;
  border: 0px solid #000000;
}

input[type=range]::-moz-range-thumb {
  box-shadow: 0px 0px 0px #000000;
  border: 0px solid #000000;
  height: 30px;
  width: 19px;
  border-radius: 0px;
  background: #FFFFFF;
  cursor: pointer;
}

input[type=range]::-ms-track {
  width: 100%;
  height: 30px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  color: transparent;
}

input[type=range]::-ms-fill-lower {
  background: #3071A9;
  border: 0px solid #000000;
  border-radius: 0px;
  box-shadow: 0px 0px 0px #000000;
}

input[type=range]::-ms-fill-upper {
  background: #3071A9;
  border: 0px solid #000000;
  border-radius: 0px;
  box-shadow: 0px 0px 0px #000000;
}

input[type=range]::-ms-thumb {
  box-shadow: 0px 0px 0px #000000;
  border: 0px solid #000000;
  height: 30px;
  width: 19px;
  border-radius: 0px;
  background: #FFFFFF;
  cursor: pointer;
}

input[type=range]:focus::-ms-fill-lower {
  background: #3071A9;
}

input[type=range]:focus::-ms-fill-upper {
  background: #3071A9;
}

.rangeFalse::-webkit-slider-runnable-track {
  background: #5d0a0a !important;
}

.rangeFalse::-webkit-slider-thumb {
  background: white !important;
}

.rangeNeutral::-webkit-slider-runnable-track {
  background: #204d75 !important;
}

.rangeNeutral::-webkit-slider-thumb {
  background: white !important;
}

.rangeTrue::-webkit-slider-runnable-track {
  background: #0e4e1f !important;
}

.rangeTrue::-webkit-slider-thumb {
  background: white !important;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggle-container">
<div class="toggle-false-msg">Off</div>
<div class="range-field" style=" width:60px">
<input type="range" name="points" min="1" class="" max="3" value="2"
onchange="togglebutton(this);">
</div>
<div class="toggle-neutral-msg">Neutral</div>
<div class="toggle-true-msg">On</div>
</div></code>
<code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="toggle-container"> <div class="toggle-false-msg">Off</div> <div class="range-field" style=" width:60px"> <input type="range" name="points" min="1" class="" max="3" value="2" onchange="togglebutton(this);"> </div> <div class="toggle-neutral-msg">Neutral</div> <div class="toggle-true-msg">On</div> </div></code>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggle-container">
  <div class="toggle-false-msg">Off</div>
  <div class="range-field" style=" width:60px">
    <input type="range" name="points" min="1" class="" max="3" value="2"
           onchange="togglebutton(this);">
  </div>
  <div class="toggle-neutral-msg">Neutral</div>
  <div class="toggle-true-msg">On</div>
</div>

Instead of using radio buttons this switch utilizes a range and passes the value into JavaScript to determine the actions of the switch. The biggest hurdle in designing this was changing the pseudo element of the range (specifically the background color of its track). This can be achieved by setting different classes with pseduo elements and using java to rotate through the classes.

Information on modifying pseudo elements can be found in the link below. I used method 1 described in the article.

Resources

  • http://pankajparashar.com/posts/modify-pseudo-elements-css/
  • https://jsfiddle.net/buzzyearlight/u7sg8oLa/

I reworked a bit @mustafa bagwala answer, so here is the same example with three state button, possibility to set between two but get between three and different colors.

And the output can be something like this:

Here are the CSS code and the HTML code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.switch-toggle input {
opacity: 0;
height: 25px;
position: absolute;
border-radius: 15px;
}
.switch-toggle input + label {
float: left;
color: #fff;
height: 25px;
font-size: 12px;
cursor: pointer;
}
.switch-toggle input[value="na"] + label {
pointer-events: none;
opacity: 0.5;
}
.switch-toggle input[value="na"]:checked + label {
background: grey;
}
.switch-toggle input[value="on"]:checked + label {
background: green;
}
.switch-toggle input[value="off"]:checked + label {
background: red
}</code>
<code>.switch-toggle input { opacity: 0; height: 25px; position: absolute; border-radius: 15px; } .switch-toggle input + label { float: left; color: #fff; height: 25px; font-size: 12px; cursor: pointer; } .switch-toggle input[value="na"] + label { pointer-events: none; opacity: 0.5; } .switch-toggle input[value="na"]:checked + label { background: grey; } .switch-toggle input[value="on"]:checked + label { background: green; } .switch-toggle input[value="off"]:checked + label { background: red }</code>
.switch-toggle input {
    opacity: 0;
    height: 25px;
    position: absolute;
    border-radius: 15px;
}

.switch-toggle input + label {
    float: left;
    color: #fff;
    height: 25px;
    font-size: 12px;
    cursor: pointer;
}

.switch-toggle input[value="na"] + label {
    pointer-events: none;
    opacity: 0.5;
}

.switch-toggle input[value="na"]:checked + label {
    background: grey;
}

.switch-toggle input[value="on"]:checked + label {
    background: green;
}

.switch-toggle input[value="off"]:checked + label {
    background: red
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />
<div class="switch-toggle switch-3 switch-candy">
<input id="on" name="state-d" type="radio" value="on" />
<label for="on">ON</label>
<input id="na" name="state-d" type="radio" value="na" checked="checked" />
<label for="na">N/A</label>
<input id="off" name="state-d" type="radio" value="off" />
<label for="off">OFF</label>
<a></a>
</div></code>
<code><link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" /> <div class="switch-toggle switch-3 switch-candy"> <input id="on" name="state-d" type="radio" value="on" /> <label for="on">ON</label> <input id="na" name="state-d" type="radio" value="na" checked="checked" /> <label for="na">N/A</label> <input id="off" name="state-d" type="radio" value="off" /> <label for="off">OFF</label> <a></a> </div></code>
<link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />
    
    <div class="switch-toggle switch-3 switch-candy">
      <input id="on" name="state-d" type="radio" value="on" />
      <label for="on">ON</label>
    
      <input id="na" name="state-d" type="radio" value="na" checked="checked" />
      <label for="na">N/A</label>
    
      <input id="off" name="state-d" type="radio" value="off" />
      <label for="off">OFF</label>
    
      <a></a>
    </div>

This is a 3 way React switch with forward, reverse, an unlocked track, and keyboard controls and you can see it in action at CodePen here. It starts at the left position, called Option 1, but you can modify it to start wherever you’d like.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>/*React Component*/
class ThreeWayToggleSwitchComponent extends React.Component {
constructor(props) {
super(props);
this.threeWayToggleSwitchComponentDivRef = React.createRef();
this.option1Ref = React.createRef();
this.option3Ref = React.createRef();
this.slidingButtonDivRef = React.createRef();
this.state = {
selectedOption: "Option 1"
};
this.handleOptionChange = this.handleOptionChange.bind(this);
this.keyboardPress = this.keyboardPress.bind(this);
}
handleOptionChange(event) {
if (event.target.value === "Option 1") {
if (this.state.selectedOption === "Option 2") {
this.setState({
selectedOption: event.target.value
});
this.slidingButtonDivRef.current.style.transform = "translate(0px)";
this.slidingButtonDivRef.current.style.background = "green";
}
else if (this.state.selectedOption === "Option 3") {
this.setState({
selectedOption: "Option 2"
});
this.slidingButtonDivRef.current.style.transform = "translate(40px)";
this.slidingButtonDivRef.current.style.background = "yellow";
}
}
else if (event.target.value === "Option 2") {
this.setState({
selectedOption: "Option 2"
});
this.slidingButtonDivRef.current.style.transform = "translate(40px)";
this.slidingButtonDivRef.current.style.background = "yellow";
}
else if (event.target.value === "Option 3") {
if (this.state.selectedOption === "Option 1") {
this.setState({
selectedOption: "Option 2"
});
this.slidingButtonDivRef.current.style.transform = "translate(40px)";
this.slidingButtonDivRef.current.style.background = "yellow";
}
else if (this.state.selectedOption === "Option 2") {
this.setState({
selectedOption: "Option 3"
});
this.slidingButtonDivRef.current.style.transform = "translate(80px)";
this.slidingButtonDivRef.current.style.background = "red";
}
}
}
keyboardPress(event) {
if (event.keyCode === 37) {
this.option1Ref.current.click();
}
else if (event.keyCode === 39) {
this.option3Ref.current.click();
}
}
componentDidMount() {
this.threeWayToggleSwitchComponentDivRef.current.focus();
}
render() {
return(
<div ref={this.threeWayToggleSwitchComponentDivRef} id="three-way-toggle-switch-component-div" tabIndex="0" onKeyDown={this.keyboardPress}>
<div id="radio-buttons-and-sliding-button-container-div">
<div id="radio-buttons-div">
<label id="option-1-label" className="single-option-label" for="option-1">Label 1
<input type="radio" ref={this.option1Ref} id="option-1" className="radio-input-class" name="radio-input" value="Option 1" checked={this.state.selectedOption === "Option 1"} onChange={this.handleOptionChange}/>
</label>
<label id="option-2-label" className="single-option-label" for="option-2">Label 2
<input type="radio" id="option-2" className="radio-input-class" name="radio-input" value="Option 2" checked={this.state.selectedOption === "Option 2"} onChange={this.handleOptionChange}/>
</label>
<label id="option-3-label" className="single-option-label" for="option-3">Label 3
<input type="radio" ref={this.option3Ref} id="option-3" className="radio-input-class" name="radio-input" value="Option 3" checked={this.state.selectedOption === "Option 3"} onChange={this.handleOptionChange}/>
</label>
</div>
<div ref={this.slidingButtonDivRef} id="sliding-button-div">
</div>
<div>
<div id="selected-option">Option Selected: {this.state.selectedOption}
</div>
<div id="keyboard-message">
You can control the sliding button via the left arrow key or the right arrow key on your keyboard.
</div>
</div>
);
}
};
ReactDOM.render(<ThreeWayToggleSwitchComponent/>, document.getElementById("react-component-div"));
/*CSS Styling*/
#three-way-toggle-switch-component-div:focus {
outline: none;
}
#radio-buttons-and-sliding-button-container-div {
position: relative;
display: inline-block;
height: 30px;
width: 120px;
border: 2px solid black;
border-radius: 5px;
}
#sliding-button-div {
position: absolute;
display: inline-block;
top: 0;
height: 30px;
width: 40px;
background: green;
transition: 0.8s;
border-radius: 3px;
}
#radio-buttons-div {
display: flex;
justify-content: space-between;
}
.single-option-label {
width: 100%;
color: transparent;
}
.radio-input-class {
display: none;
}
</code>
<code>/*React Component*/ class ThreeWayToggleSwitchComponent extends React.Component { constructor(props) { super(props); this.threeWayToggleSwitchComponentDivRef = React.createRef(); this.option1Ref = React.createRef(); this.option3Ref = React.createRef(); this.slidingButtonDivRef = React.createRef(); this.state = { selectedOption: "Option 1" }; this.handleOptionChange = this.handleOptionChange.bind(this); this.keyboardPress = this.keyboardPress.bind(this); } handleOptionChange(event) { if (event.target.value === "Option 1") { if (this.state.selectedOption === "Option 2") { this.setState({ selectedOption: event.target.value }); this.slidingButtonDivRef.current.style.transform = "translate(0px)"; this.slidingButtonDivRef.current.style.background = "green"; } else if (this.state.selectedOption === "Option 3") { this.setState({ selectedOption: "Option 2" }); this.slidingButtonDivRef.current.style.transform = "translate(40px)"; this.slidingButtonDivRef.current.style.background = "yellow"; } } else if (event.target.value === "Option 2") { this.setState({ selectedOption: "Option 2" }); this.slidingButtonDivRef.current.style.transform = "translate(40px)"; this.slidingButtonDivRef.current.style.background = "yellow"; } else if (event.target.value === "Option 3") { if (this.state.selectedOption === "Option 1") { this.setState({ selectedOption: "Option 2" }); this.slidingButtonDivRef.current.style.transform = "translate(40px)"; this.slidingButtonDivRef.current.style.background = "yellow"; } else if (this.state.selectedOption === "Option 2") { this.setState({ selectedOption: "Option 3" }); this.slidingButtonDivRef.current.style.transform = "translate(80px)"; this.slidingButtonDivRef.current.style.background = "red"; } } } keyboardPress(event) { if (event.keyCode === 37) { this.option1Ref.current.click(); } else if (event.keyCode === 39) { this.option3Ref.current.click(); } } componentDidMount() { this.threeWayToggleSwitchComponentDivRef.current.focus(); } render() { return( <div ref={this.threeWayToggleSwitchComponentDivRef} id="three-way-toggle-switch-component-div" tabIndex="0" onKeyDown={this.keyboardPress}> <div id="radio-buttons-and-sliding-button-container-div"> <div id="radio-buttons-div"> <label id="option-1-label" className="single-option-label" for="option-1">Label 1 <input type="radio" ref={this.option1Ref} id="option-1" className="radio-input-class" name="radio-input" value="Option 1" checked={this.state.selectedOption === "Option 1"} onChange={this.handleOptionChange}/> </label> <label id="option-2-label" className="single-option-label" for="option-2">Label 2 <input type="radio" id="option-2" className="radio-input-class" name="radio-input" value="Option 2" checked={this.state.selectedOption === "Option 2"} onChange={this.handleOptionChange}/> </label> <label id="option-3-label" className="single-option-label" for="option-3">Label 3 <input type="radio" ref={this.option3Ref} id="option-3" className="radio-input-class" name="radio-input" value="Option 3" checked={this.state.selectedOption === "Option 3"} onChange={this.handleOptionChange}/> </label> </div> <div ref={this.slidingButtonDivRef} id="sliding-button-div"> </div> <div> <div id="selected-option">Option Selected: {this.state.selectedOption} </div> <div id="keyboard-message"> You can control the sliding button via the left arrow key or the right arrow key on your keyboard. </div> </div> ); } }; ReactDOM.render(<ThreeWayToggleSwitchComponent/>, document.getElementById("react-component-div")); /*CSS Styling*/ #three-way-toggle-switch-component-div:focus { outline: none; } #radio-buttons-and-sliding-button-container-div { position: relative; display: inline-block; height: 30px; width: 120px; border: 2px solid black; border-radius: 5px; } #sliding-button-div { position: absolute; display: inline-block; top: 0; height: 30px; width: 40px; background: green; transition: 0.8s; border-radius: 3px; } #radio-buttons-div { display: flex; justify-content: space-between; } .single-option-label { width: 100%; color: transparent; } .radio-input-class { display: none; } </code>
/*React Component*/
class ThreeWayToggleSwitchComponent extends React.Component {
  constructor(props) {
    super(props);

    this.threeWayToggleSwitchComponentDivRef = React.createRef();
    this.option1Ref = React.createRef();
    this.option3Ref = React.createRef();
    this.slidingButtonDivRef = React.createRef();

    this.state = {
      selectedOption: "Option 1"
    };

    this.handleOptionChange = this.handleOptionChange.bind(this);
    this.keyboardPress = this.keyboardPress.bind(this);
  }

  handleOptionChange(event) {
    if (event.target.value === "Option 1") {
      if (this.state.selectedOption === "Option 2") {
        this.setState({
          selectedOption: event.target.value
        });

        this.slidingButtonDivRef.current.style.transform = "translate(0px)";
        this.slidingButtonDivRef.current.style.background = "green";  
      }
      else if (this.state.selectedOption === "Option 3") {
        this.setState({
          selectedOption: "Option 2"
        });

        this.slidingButtonDivRef.current.style.transform = "translate(40px)";
        this.slidingButtonDivRef.current.style.background = "yellow";
      }
    }
    else if (event.target.value === "Option 2") {
      this.setState({
        selectedOption: "Option 2"
      });

      this.slidingButtonDivRef.current.style.transform = "translate(40px)";
      this.slidingButtonDivRef.current.style.background = "yellow";
    }
    else if (event.target.value === "Option 3") {
      if (this.state.selectedOption === "Option 1") {
        this.setState({
          selectedOption: "Option 2"
        });

        this.slidingButtonDivRef.current.style.transform = "translate(40px)";
        this.slidingButtonDivRef.current.style.background = "yellow";
      }
      else if (this.state.selectedOption === "Option 2") {
        this.setState({
          selectedOption: "Option 3"
        });

        this.slidingButtonDivRef.current.style.transform = "translate(80px)";
        this.slidingButtonDivRef.current.style.background = "red";
      }
    }
  }

  keyboardPress(event) { 
    if (event.keyCode === 37) {
      this.option1Ref.current.click();
    }
    else if (event.keyCode === 39) {
      this.option3Ref.current.click();
    }
  }

  componentDidMount() {
    this.threeWayToggleSwitchComponentDivRef.current.focus();
  }

  render() {    
    return(
      <div ref={this.threeWayToggleSwitchComponentDivRef} id="three-way-toggle-switch-component-div" tabIndex="0" onKeyDown={this.keyboardPress}>
        <div id="radio-buttons-and-sliding-button-container-div">
          <div id="radio-buttons-div">
            <label id="option-1-label" className="single-option-label" for="option-1">Label 1
              <input type="radio" ref={this.option1Ref} id="option-1" className="radio-input-class" name="radio-input" value="Option 1" checked={this.state.selectedOption === "Option 1"} onChange={this.handleOptionChange}/>
            </label>

            <label id="option-2-label" className="single-option-label" for="option-2">Label 2
              <input type="radio" id="option-2" className="radio-input-class" name="radio-input" value="Option 2" checked={this.state.selectedOption === "Option 2"} onChange={this.handleOptionChange}/>
            </label>

            <label id="option-3-label" className="single-option-label" for="option-3">Label 3
              <input type="radio" ref={this.option3Ref} id="option-3" className="radio-input-class" name="radio-input" value="Option 3" checked={this.state.selectedOption === "Option 3"} onChange={this.handleOptionChange}/>
            </label>
          </div>

          <div ref={this.slidingButtonDivRef} id="sliding-button-div">
          </div>
        <div>

        <div id="selected-option">Option Selected: {this.state.selectedOption}
        </div>

        <div id="keyboard-message">
          You can control the sliding button via the left arrow key or the right arrow key on your keyboard.
        </div>
      </div>
    );
  }
};

ReactDOM.render(<ThreeWayToggleSwitchComponent/>, document.getElementById("react-component-div"));

/*CSS Styling*/
#three-way-toggle-switch-component-div:focus {
  outline: none;
}

#radio-buttons-and-sliding-button-container-div {
  position: relative;
  display: inline-block;
  height: 30px;
  width: 120px;
  border: 2px solid black;
  border-radius: 5px;
}

#sliding-button-div {
  position: absolute;
  display: inline-block;
  top: 0;
  height: 30px;
  width: 40px;
  background: green;
  transition: 0.8s;
  border-radius: 3px;
}

#radio-buttons-div {
  display: flex;
  justify-content: space-between;
}

.single-option-label {
  width: 100%;
  color: transparent;
}

.radio-input-class {
  display: none;
}

With Bootstrap 5 and JQuery :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$(document).on('click', '.switch-3', function(event) {
/* get switch slider */
let slider = $(this).find('.switch-3-slider');
/* get switch height */
let height = $(this).height();
/* get coord of click */
let clickPos = event.pageY - $(this).offset().top;
/* get 1/3 of switch height */
let heightThird1 = height / 3;
let heightThird2 = heightThird1 + height / 3;
if (clickPos > heightThird2) {
$(this).removeClass('switch-state-top');
$(this).removeClass('switch-state-center');
$(this).addClass('switch-state-bottom');
$(this).find('.switch-3-label').eq(2).find('.switch-3-radio').prop('checked', true);
} else if (clickPos > heightThird1 && clickPos <= heightThird2) {
$(this).removeClass('switch-state-top');
$(this).removeClass('switch-state-bottom');
$(this).addClass('switch-state-center');
$(this).find('.switch-3-label').eq(1).find('.switch-3-radio').prop('checked', true);
} else {
$(this).removeClass('switch-state-bottom');
$(this).removeClass('switch-state-center');
$(this).addClass('switch-state-top');
$(this).find('.switch-3-label').eq(0).find('.switch-3-radio').prop('checked', true);
}
});</code>
<code>$(document).on('click', '.switch-3', function(event) { /* get switch slider */ let slider = $(this).find('.switch-3-slider'); /* get switch height */ let height = $(this).height(); /* get coord of click */ let clickPos = event.pageY - $(this).offset().top; /* get 1/3 of switch height */ let heightThird1 = height / 3; let heightThird2 = heightThird1 + height / 3; if (clickPos > heightThird2) { $(this).removeClass('switch-state-top'); $(this).removeClass('switch-state-center'); $(this).addClass('switch-state-bottom'); $(this).find('.switch-3-label').eq(2).find('.switch-3-radio').prop('checked', true); } else if (clickPos > heightThird1 && clickPos <= heightThird2) { $(this).removeClass('switch-state-top'); $(this).removeClass('switch-state-bottom'); $(this).addClass('switch-state-center'); $(this).find('.switch-3-label').eq(1).find('.switch-3-radio').prop('checked', true); } else { $(this).removeClass('switch-state-bottom'); $(this).removeClass('switch-state-center'); $(this).addClass('switch-state-top'); $(this).find('.switch-3-label').eq(0).find('.switch-3-radio').prop('checked', true); } });</code>
$(document).on('click', '.switch-3', function(event) {
    /* get switch slider */
    let slider = $(this).find('.switch-3-slider');
    /* get switch height */
    let height = $(this).height();
    /* get coord of click */
    let clickPos = event.pageY - $(this).offset().top;
    /* get 1/3 of switch height */
    let heightThird1 = height / 3;
    let heightThird2 = heightThird1 + height / 3;
    if (clickPos > heightThird2) {
        $(this).removeClass('switch-state-top');
        $(this).removeClass('switch-state-center');
        $(this).addClass('switch-state-bottom');
        $(this).find('.switch-3-label').eq(2).find('.switch-3-radio').prop('checked', true);
    } else if (clickPos > heightThird1 && clickPos <= heightThird2) {
        $(this).removeClass('switch-state-top');
        $(this).removeClass('switch-state-bottom');
        $(this).addClass('switch-state-center');
        $(this).find('.switch-3-label').eq(1).find('.switch-3-radio').prop('checked', true);
    } else {
        $(this).removeClass('switch-state-bottom');
        $(this).removeClass('switch-state-center');
        $(this).addClass('switch-state-top');
        $(this).find('.switch-3-label').eq(0).find('.switch-3-radio').prop('checked', true);
    }

});
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.switch-3 {
width: 3rem;
height: 7.5rem;
overflow: hidden;
}
.switch-3 .switch-3-slider {
width: 3rem;
height: 7.5rem;
left: 0;
right: 0;
transition: ease .4s all;
}
.switch-3 .switch-3-cover {
width: 3rem;
height: 2.5rem;
}
.switch-3 .switch-3-key {
width: 3rem;
height: 2.5rem;
background-color: rgba(0, 0, 0, .25);
}
.switch-3-label {
flex: 0 1 2.5rem;
}
.switch-3.switch-state-top .switch-3-slider {
bottom: 5rem;
}
.switch-3.switch-state-center .switch-3-slider {
bottom: 2.5rem;
}
.switch-3.switch-state-bottom .switch-3-slider {
bottom: 0rem;
}</code>
<code>.switch-3 { width: 3rem; height: 7.5rem; overflow: hidden; } .switch-3 .switch-3-slider { width: 3rem; height: 7.5rem; left: 0; right: 0; transition: ease .4s all; } .switch-3 .switch-3-cover { width: 3rem; height: 2.5rem; } .switch-3 .switch-3-key { width: 3rem; height: 2.5rem; background-color: rgba(0, 0, 0, .25); } .switch-3-label { flex: 0 1 2.5rem; } .switch-3.switch-state-top .switch-3-slider { bottom: 5rem; } .switch-3.switch-state-center .switch-3-slider { bottom: 2.5rem; } .switch-3.switch-state-bottom .switch-3-slider { bottom: 0rem; }</code>
.switch-3 {
    width: 3rem;
    height: 7.5rem;
    overflow: hidden;
}

.switch-3 .switch-3-slider {
    width: 3rem;
    height: 7.5rem;
    left: 0;
    right: 0;
    transition: ease .4s all;
}

.switch-3 .switch-3-cover {
    width: 3rem;
    height: 2.5rem;
}

.switch-3 .switch-3-key {
    width: 3rem;
    height: 2.5rem;
    background-color: rgba(0, 0, 0, .25);
}

.switch-3-label {
    flex: 0 1 2.5rem;
}

.switch-3.switch-state-top .switch-3-slider {
    bottom: 5rem;
}

.switch-3.switch-state-center .switch-3-slider {
    bottom: 2.5rem;
}

.switch-3.switch-state-bottom .switch-3-slider {
    bottom: 0rem;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="position-relative d-inline-block switch-3 switch-state-bottom" role="button">
<div class="h-100 w-100 d-flex flex-column flex-nowrap text-light bg-primary">
<label class="d-flex justify-content-center align-items-center switch-3-label">
<small>ON</small>
<input class="switch-3-radio" type="radio" value="on" />
</label>
<label class="d-flex justify-content-center align-items-center switch-3-label">
<small>N/A</small>
<input class="switch-3-radio" type="radio" value="na" />
</label>
<label class="d-flex justify-content-center align-items-center switch-3-label">
<small>OFF</small>
<input class="switch-3-radio" type="radio" value="off" checked />
</label>
</div>
<div class="position-absolute d-block switch-3-slider">
<span class="d-block bg-primary switch-3-cover"></span>
<span class="d-block bg-primary switch-3-cover"></span>
<span class="d-block switch-3-key"></span>
<span class="d-block bg-primary switch-3-cover"></span>
<span class="d-block bg-primary switch-3-cover"></span>
</div>
</div></code>
<code><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="position-relative d-inline-block switch-3 switch-state-bottom" role="button"> <div class="h-100 w-100 d-flex flex-column flex-nowrap text-light bg-primary"> <label class="d-flex justify-content-center align-items-center switch-3-label"> <small>ON</small> <input class="switch-3-radio" type="radio" value="on" /> </label> <label class="d-flex justify-content-center align-items-center switch-3-label"> <small>N/A</small> <input class="switch-3-radio" type="radio" value="na" /> </label> <label class="d-flex justify-content-center align-items-center switch-3-label"> <small>OFF</small> <input class="switch-3-radio" type="radio" value="off" checked /> </label> </div> <div class="position-absolute d-block switch-3-slider"> <span class="d-block bg-primary switch-3-cover"></span> <span class="d-block bg-primary switch-3-cover"></span> <span class="d-block switch-3-key"></span> <span class="d-block bg-primary switch-3-cover"></span> <span class="d-block bg-primary switch-3-cover"></span> </div> </div></code>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div class="position-relative d-inline-block switch-3 switch-state-bottom" role="button">
    <div class="h-100 w-100 d-flex flex-column flex-nowrap text-light bg-primary">
        <label class="d-flex justify-content-center align-items-center switch-3-label">
            <small>ON</small>
            <input class="switch-3-radio" type="radio" value="on" />
        </label>
        <label class="d-flex justify-content-center align-items-center switch-3-label">
             <small>N/A</small>
             <input class="switch-3-radio" type="radio" value="na" />
        </label>
        <label class="d-flex justify-content-center align-items-center switch-3-label">
            <small>OFF</small>
            <input class="switch-3-radio" type="radio" value="off" checked />
        </label>
    </div>
    <div class="position-absolute d-block switch-3-slider">
        <span class="d-block bg-primary switch-3-cover"></span>
        <span class="d-block bg-primary switch-3-cover"></span>
        <span class="d-block switch-3-key"></span>
        <span class="d-block bg-primary switch-3-cover"></span>
        <span class="d-block bg-primary switch-3-cover"></span>
    </div>
</div>

You can always use concentric ternary operator.
Here’s the catch..

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>className = {title === 'One' ? classes.one : (title === 'Two : classes.two : classes.three)
</code>
<code>className = {title === 'One' ? classes.one : (title === 'Two : classes.two : classes.three) </code>
className = {title === 'One' ? classes.one : (title === 'Two : classes.two : classes.three)

and so on..for n number of classes.

I used “SWITCH” for switching the state. From Off to Mid, Mid to High, High to Mid, and Mid to Off. Sliding effect is applied for natural interaction. Here is my JSfiddle.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const switchContainer = document.querySelector(".switch-container");
const switchButton = document.querySelector(".switch-button");
const switchIndicator = document.querySelector(".switch-indicator");
const switchLabel = document.querySelector(".switch-label");
let currentState = 0;
switchContainer.addEventListener("click", function() {
switch (currentState) {
case 0: // From A to B
switchButton.classList.add("mid");
switchIndicator.classList.add("mid");
switchLabel.textContent = "Mid";
currentState = 1;
break;
case 1: // From B to C
switchButton.classList.remove("mid");
switchButton.classList.add("high");
switchIndicator.classList.remove("mid");
switchIndicator.classList.add("high");
switchLabel.textContent = "High";
currentState = 2;
break;
case 2: // From C to B
switchButton.classList.remove("high");
switchButton.classList.add("mid");
switchIndicator.classList.remove("high");
switchIndicator.classList.add("mid");
switchLabel.textContent = "Mid";
currentState = 3;
break;
case 3: // From B to A
switchButton.classList.remove("mid");
switchIndicator.classList.remove("mid");
switchLabel.textContent = "Off";
currentState = 0;
break;
}
});
switchButton.addEventListener("mousedown", (e) => {
dragging = true;
initialX = e.clientX;
});
document.addEventListener("mousemove", (e) => {
if (dragging) {
const deltaX = e.clientX - initialX;
if (deltaX > 20) {
updateSwitchState();
initialX = e.clientX;
} else if (deltaX < -20) {
currentState = (currentState - 1 + 4) % 4;
updateSwitchState();
initialX = e.clientX;
}
}
});
document.addEventListener("mouseup", () => {
dragging = false;
});
// Set the initial label text
switchLabel.textContent = "Off";</code>
<code>const switchContainer = document.querySelector(".switch-container"); const switchButton = document.querySelector(".switch-button"); const switchIndicator = document.querySelector(".switch-indicator"); const switchLabel = document.querySelector(".switch-label"); let currentState = 0; switchContainer.addEventListener("click", function() { switch (currentState) { case 0: // From A to B switchButton.classList.add("mid"); switchIndicator.classList.add("mid"); switchLabel.textContent = "Mid"; currentState = 1; break; case 1: // From B to C switchButton.classList.remove("mid"); switchButton.classList.add("high"); switchIndicator.classList.remove("mid"); switchIndicator.classList.add("high"); switchLabel.textContent = "High"; currentState = 2; break; case 2: // From C to B switchButton.classList.remove("high"); switchButton.classList.add("mid"); switchIndicator.classList.remove("high"); switchIndicator.classList.add("mid"); switchLabel.textContent = "Mid"; currentState = 3; break; case 3: // From B to A switchButton.classList.remove("mid"); switchIndicator.classList.remove("mid"); switchLabel.textContent = "Off"; currentState = 0; break; } }); switchButton.addEventListener("mousedown", (e) => { dragging = true; initialX = e.clientX; }); document.addEventListener("mousemove", (e) => { if (dragging) { const deltaX = e.clientX - initialX; if (deltaX > 20) { updateSwitchState(); initialX = e.clientX; } else if (deltaX < -20) { currentState = (currentState - 1 + 4) % 4; updateSwitchState(); initialX = e.clientX; } } }); document.addEventListener("mouseup", () => { dragging = false; }); // Set the initial label text switchLabel.textContent = "Off";</code>
const switchContainer = document.querySelector(".switch-container");
const switchButton = document.querySelector(".switch-button");
const switchIndicator = document.querySelector(".switch-indicator");
const switchLabel = document.querySelector(".switch-label");

let currentState = 0;

switchContainer.addEventListener("click", function() {
  switch (currentState) {
    case 0: // From A to B
      switchButton.classList.add("mid");
      switchIndicator.classList.add("mid");
      switchLabel.textContent = "Mid";
      currentState = 1;
      break;
    case 1: // From B to C
      switchButton.classList.remove("mid");
      switchButton.classList.add("high");
      switchIndicator.classList.remove("mid");
      switchIndicator.classList.add("high");
      switchLabel.textContent = "High";
      currentState = 2;
      break;
    case 2: // From C to B
      switchButton.classList.remove("high");
      switchButton.classList.add("mid");
      switchIndicator.classList.remove("high");
      switchIndicator.classList.add("mid");
      switchLabel.textContent = "Mid";
      currentState = 3;
      break;
    case 3: // From B to A
      switchButton.classList.remove("mid");
      switchIndicator.classList.remove("mid");
      switchLabel.textContent = "Off";
      currentState = 0;
      break;
  }
});


switchButton.addEventListener("mousedown", (e) => {
  dragging = true;
  initialX = e.clientX;
});

document.addEventListener("mousemove", (e) => {
  if (dragging) {
    const deltaX = e.clientX - initialX;
    if (deltaX > 20) {
      updateSwitchState();
      initialX = e.clientX;
    } else if (deltaX < -20) {
      currentState = (currentState - 1 + 4) % 4;
      updateSwitchState();
      initialX = e.clientX;
    }
  }
});

document.addEventListener("mouseup", () => {
  dragging = false;
});

// Set the initial label text
switchLabel.textContent = "Off";
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>.switch-component {
display: inline-block;
position: relative;
}
.switch-container {
display: inline-block;
position: relative;
width: 40px;
height: 24px;
border-radius: 12px;
border: 1px solid #d9d9d9;
}
.switch-button {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 24px;
border-radius: 12px;
background-color: #f7f7f7;
transition: background-color 0.3s;
}
.switch-indicator {
position: absolute;
top: 4px;
left: 4px;
width: 16px;
height: 16px;
border-radius: 8px;
background-color: white;
transition: left 0.3s;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
.switch-button.mid {
background-color: #77ff77;
}
.switch-button.high {
background-color: #ff7777;
}
.switch-indicator.mid {
left: 12px;
}
.switch-indicator.high {
left: 24px;
}
.switch-wrapper {
display: flex;
}
.switch-label {
font-family: 'Roboto', sans-serif;
font-size: 12px;
color: #777;
text-align: center;
margin-top: 5px;
}</code>
<code>.switch-component { display: inline-block; position: relative; } .switch-container { display: inline-block; position: relative; width: 40px; height: 24px; border-radius: 12px; border: 1px solid #d9d9d9; } .switch-button { position: absolute; top: 0; left: 0; width: 40px; height: 24px; border-radius: 12px; background-color: #f7f7f7; transition: background-color 0.3s; } .switch-indicator { position: absolute; top: 4px; left: 4px; width: 16px; height: 16px; border-radius: 8px; background-color: white; transition: left 0.3s; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } .switch-button.mid { background-color: #77ff77; } .switch-button.high { background-color: #ff7777; } .switch-indicator.mid { left: 12px; } .switch-indicator.high { left: 24px; } .switch-wrapper { display: flex; } .switch-label { font-family: 'Roboto', sans-serif; font-size: 12px; color: #777; text-align: center; margin-top: 5px; }</code>
.switch-component {
  display: inline-block;
  position: relative;
}

.switch-container {
  display: inline-block;
  position: relative;
  width: 40px;
  height: 24px;
  border-radius: 12px;
  border: 1px solid #d9d9d9;
}

.switch-button {
  position: absolute;
  top: 0;
  left: 0;
  width: 40px;
  height: 24px;
  border-radius: 12px;
  background-color: #f7f7f7;
  transition: background-color 0.3s;
}

.switch-indicator {
  position: absolute;
  top: 4px;
  left: 4px;
  width: 16px;
  height: 16px;
  border-radius: 8px;
  background-color: white;
  transition: left 0.3s;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}

.switch-button.mid {
  background-color: #77ff77;
}

.switch-button.high {
  background-color: #ff7777;
}

.switch-indicator.mid {
  left: 12px;
}

.switch-indicator.high {
  left: 24px;
}

.switch-wrapper {
  display: flex;
}

.switch-label {
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  color: #777;
  text-align: center;
  margin-top: 5px;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><div class="switch-component">
<div class="switch-container">
<div class="switch-wrapper">
<div class="switch-button"></div>
<div class="switch-indicator"></div>
</div>
</div>
<div class="switch-label"></div>
</div></code>
<code><div class="switch-component"> <div class="switch-container"> <div class="switch-wrapper"> <div class="switch-button"></div> <div class="switch-indicator"></div> </div> </div> <div class="switch-label"></div> </div></code>
<div class="switch-component">
<div class="switch-container">
  <div class="switch-wrapper">
    <div class="switch-button"></div>
    <div class="switch-indicator"></div>  
  </div>  
</div>
<div class="switch-label"></div>
</div>

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật