Search code examples
htmlcss

iOS Toggle Switch with CSS


I am trying to find the simplest way with CSS properties to make a vertical alignment to my iOS-like toggle button so as to look nice..
I dont want to use a second div - container.. I only want to move the div.switch-btn::before in the middle of the .switch-btn

<!DOCTYPE html>
    <html>
    <title>iOS Toogle Switch</title>
    <style>
    .switch{
        opacity: 0;
    }

    .switch-btn{
        width: 80px;
        height: 20px;
        background: #e5e5e5;
        position: relative;
        border-radius: 20px;
        box-shadow: inset 0 3px 10px rgba(0,0,0,.3);
    }

    .switch-btn:before{
        content: "";
        position: absolute;
        height: 36px;
        width: 36px;
        background: linear-gradient(#FFF, #f2f2f2);
        left: 2px;
        top: 2px;
        transition: all 250ms ease-out;
        cursor: pointer;
        border-radius: 50%;
        box-shadow: 0 8px 6px -4px rgba(0,0,0,.25);
    }

    input[type=checkbox]:checked + .switch-btn {
        background: #47CB8F;
    }

    input[type=checkbox]:checked + .switch-btn:before {
        left: 42px;
    }

    </style>
        <body>
        <label class="switch">
            <input type ="checkbox"/>
            <div class="switch-btn"></div>
        </label>

        <script>

        </script>   
        </body>
    </html>

Solution

  • https://jsfiddle.net/2ehmwta3/

    .switch-btn:before {
        /* ... */
        top: 50%;
        transform: translateY(-50%);
        /* ... */
    }
    

    you should set transform attribute when you want to make something on vertically centered even if the target DOM is bigger than parent element.

    explaination

    .switch-btn:before having 36px as their height but you gave top: 2px which is just move down 2 pixels from the toppest location of parent DOM object (switch-btn).

    so I gave top: 50% which will place .switch-btn:before on 10 pixels from toppest location because 20 (the height of '.switch-btn') * 50% = 10 as you know.

    and, the important part is transform: translateY(-50%). this makes the DOM move as much as half its own height. so .switch-btn:before will move 18 pixels upwards.