Here is one example of toggle button with pure css no js needed

CSS:
/*I am hidding input element*/
.milosev-toggle-checkbox {
    display: none;
}

/*in this rule I defining actual size of the toggle*/
.milosev-toggle {
    position: relative;
    width: 72px;
    height: 36px;
}

.milosev-toggle-button {
    width: 36px;
    height: 36px;
    border: 1px solid #c0c0c0;
    border-radius: 50%;
    background: -webkit-linear-gradient(top, #ffffff 0%, #ebebeb 100%);
    z-index: 1;
    position: relative;
}

.milosev-toggle-color-left {
    background: red;
}

.milosev-toggle-color-right {
    background: yellow;
}

.milosev-toggle-wrapper .milosev-toggle-background-right, .milosev-toggle-wrapper .milosev-toggle-color-left {
    width: 100%;
    height: 100%;
    position: absolute;
    border-radius: 18px;
}

.milosev-toggle-wrapper {
    width: 100%;
    height: 100%;
    border-radius: 36px;
    z-index: 1;
    position: absolute;
}

/*smooth effect*/
.milosev-toggle-button-container {
    transition: margin 0.3s ease-in 0s;
}

/*with this block of rules I am moving a button*/
.milosev-toggle-checkbox:checked + .milosev-toggle-label .milosev-toggle-wrapper {
    margin-left: 0;
}

.milosev-toggle-checkbox:checked + .milosev-toggle-label .milosev-toggle-button-container {
    margin-left: 36px;
}
/*---*/

/*display / hide background - in my case red or yellow*/
.milosev-toggle-wrapper .milosev-toggle-background-left {
    display: none; /*left color by default is hidden*/
}

.milosev-toggle-checkbox:checked + .milosev-toggle-label .milosev-toggle-wrapper .milosev-toggle-background-left {
    display: block; /*when checked left is displayed*/
}
.milosev-toggle-checkbox:checked + .milosev-toggle-label .milosev-toggle-wrapper .milosev-toggle-background-right {
    display: none; /*when checked right color is hidden*/
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>

    <!--this, first, div I need to constrain size of the toggle-->
    <div class="milosev-toggle">

        <!--this is going to be hidden and I need input for interaction (checked / unchecked)-->
        <input type="checkbox" class="milosev-toggle-checkbox" id="milosev-checkbox">

        <!--without label click will not work-->
        <label class="milosev-toggle-label" for="milosev-checkbox">

            <!--with this one I am covering click area (it has to be everywhere on toggle) -->
            <div class="milosev-toggle-wrapper">

                <div class="milosev-toggle-background-left milosev-toggle-color-left">
                </div>
                <div class="milosev-toggle-background-right milosev-toggle-color-right">
                </div>

            </div>

            <!--button is defined here, and it is moved when input is checked (in css search for 'checked')-->
            <div class="milosev-toggle-button-container">
                <div class="milosev-toggle-button"></div>
            </div>

        </label>

    </div>

</body>
</html>
Live example:

---

Another example:

CSS:

/*actual size of the toggle*/
.milosev-toggle {
    position: relative;
    width: 82px;
    -webkit-user-select: none;
}

/*hide input element*/
.milosev-toggle-checkbox {
    display: none;
}

/********************************************************/

/*background colors*/

/*even though this rule is for label, it also sets position of background colors*/
.milosev-toggle-label {
    display: block;
    cursor: pointer;
    padding: 5px;
}

.milosev-toggle-background-left, .milosev-toggle-background-right {
    width: 54px;
    height: 37px;
    float: left; /*this css force colors to be in one line*/
    overflow: visible;
    position: relative;
}

.milosev-toggle-background-left {
    border-right-style: solid;
    border-right-width: 1px;
    border-color: white;
}

.milosev-toggle-background-right {
    text-align: right;
}

.milosev-toggle-color-right {
    background: yellow;
}

.milosev-toggle-color-left {
    background: red;
}

/*also size of toggle, but extended with color which is going to move left or right, in this rule also transition is included*/
.milosev-toggle-inner {
    width: 109px;
    height: 37px;
    margin-left: -36px; /*animation will go from -36 to 0*/
    transition: margin 0.3s ease-in 0s;
    z-index: 1;
}

/*end of background colors design*/

/********************************************************/

/*toggle button*/

/*button itself*/
.milosev-toggle-button-container {
    top: 5px; /*with this line we are actually setting button to be on the same top as colors, without top it will go under colors*/
    right: 42px;
    transition: right 0.3s ease-in 0s;
}

.milosev-toggle-button-bg {
    width: 34px;
    height: 34px;
    border: 1px solid #c0c0c0;
    border-radius: 18px;
    background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(235,235,235,1) 100%);
    -webkit-filter: drop-shadow(0px 3px 5px rgba(0,0,0, 0.2)); /*shadow*/
    z-index: 1;
    position: absolute;
}

/*better feeling*/
.milosev-toggle-button {
    width: 30px;
    height: 30px;
    top: 2px;
    left: 2px;
    border-radius: 18px;
    background: -webkit-linear-gradient(top, rgba(235,235,235,1) 0%,rgba(250,250,250,1) 100%);
    z-index: 2;
    position: absolute;
}

/*end of toggle button*/

/********************************************************/

/*background colors behaviour*/
.milosev-toggle-checkbox:checked + .milosev-toggle-label .milosev-toggle-inner {
    margin-left: 0;
}

/*toggle button behaviour*/
.milosev-toggle-checkbox:checked + .milosev-toggle-label .milosev-toggle-button-container {
    right: 4px;
}

/********************************************************/

/*radius*/
.milosev-toggle-wrapper {
    width: 72px;
    height: 36px;
    overflow: hidden;
    border-radius: 36px;
    z-index: 1;
    position: relative;
}

/********************************************************/

/*on (|) and off (O) icons*/
.slider-off-icon {
    width: 16px;
    height: 16px;
    background: transparent;
    border: 2px solid #fff;
    border-radius: 20px;
    position: absolute;
    top: 8px;
    right: 11px;
    -webkit-box-shadow: 0px -1px 0px rgba(0,0,0,0.35), inset 0px -0.5px 0px rgba(0,0,0,0.35);
}

.slider-on-icon {
    width: 2px;
    height: 20px;
    background-color: rgb(255,255,255);
    position: absolute;
    top: 8px;
    left: 20px;
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>

<!--this, first, div I need to constrain size of the toggle-->
<div class="milosev-toggle">

    <!--this is going to be hidden and I need input for interaction (checked / unchecked)-->
    <input type="checkbox" class="milosev-toggle-checkbox" id="milosev-checkbox">

    <!--without label click will not work-->
    <label class="milosev-toggle-label" for="milosev-checkbox">

        <!--with this one I am covering click area (it has to be everywhere on toggle) -->
        <div class="milosev-toggle-wrapper">
            <div class="milosev-toggle-inner">

                <div class="milosev-toggle-background-left milosev-toggle-color-left">
                    <div class="slider-on-icon">
                    </div>
                </div>
                <div class="milosev-toggle-background-right milosev-toggle-color-right">
                    <div class="slider-off-icon">
                    </div>
                </div>

            </div>

        </div>

        <!--button is defined here, and it is moved when input is checked (in css search for 'checked')-->
        <div class="milosev-toggle-button-container milosev-toggle-button-bg">
            <div class="milosev-toggle-button"></div>
        </div>

    </label>

</div>

</body>
</html>
Live example: