Skip to content

Instantly share code, notes, and snippets.

@artemsites
Last active May 11, 2024 14:17
Show Gist options
  • Save artemsites/8e769f613192d56d2ae9271213161dca to your computer and use it in GitHub Desktop.
Save artemsites/8e769f613192d56d2ae9271213161dca to your computer and use it in GitHub Desktop.
<h1 id="как-сделать-switcher-на-css-стилизовав-input-typecheckbox">Как сделать Switcher на CSS стилизовав input type=&quot;checkbox&quot;</h1>
<p><img src="https://practical-web.ru/uploads/kak-sdelat-switcher-na-css-stilizovav-input-type-checkbox/how-it-view.webp" alt="Checkbox Switcher на CSS"></p>
<p>Перед работой нам понадобится установить препроцессор CSS - SCSS<br>и какой нибудь сборщик frontend приложений,<br>например сборщик Vite.js.<br>Если вы его не умеете устанвливать,<br>то можете узнать как это делать в статье <a href="https://practical-web.ru/bundlers/kak-ustanovit-i-primenyat-sborshchik-frontend-prilozheniy-vite-js">об установке и применении сборщика Vite.js</a> </p>
<h2 id="1-создадим-html-структуру-switcher-компонента">1. Создадим html структуру Switcher компонента</h2>
<pre><code>&lt;label class=&quot;switcher&quot;&gt;
&lt;span class=&quot;switcher__label&quot;&gt;Switcher&lt;/span&gt;
&lt;div class=&quot;switcher__box&quot;&gt;
&lt;span class=&quot;switcher__indicator&quot;&gt;&lt;/span&gt;
&lt;input class=&quot;switcher__checkbox&quot; type=&quot;checkbox&quot; name=&quot;&quot; id=&quot;&quot;&gt;
&lt;/div&gt;
&lt;/label&gt;
</code></pre>
<h2 id="2-создадим-javascript-объявление-логики-компонентов-switcher-на-странице">2. Создадим JavaScript объявление логики компонентов Switcher на странице</h2>
<pre><code>// assets/js/switcher.js
document.addEventListener(&quot;DOMContentLoaded&quot;, function () {
try {
const switcherAll = document.querySelectorAll(&quot;.switcher&quot;);
switcherAll.forEach(function (switcher) {
switcher.addEventListener(&quot;click&quot;, function (e) {
if (switcher.classList.contains(&quot;_on&quot;)) {
switcher.classList.remove(&quot;_on&quot;);
switcher.classList.add(&quot;_off&quot;);
} else {
switcher.classList.remove(&quot;_off&quot;);
switcher.classList.add(&quot;_on&quot;);
}
// Установка значения checked в value
const checkbox = switcher.querySelector(&quot;.switcher__checkbox&quot;);
checkbox.value=checkbox.checked
// Сброс анимации сплющивания
const indicator = switcher.querySelector(&quot;.switcher__indicator&quot;);
indicator.style.animationName = &quot;none&quot;;
requestAnimationFrame(function () {
indicator.style.animationName = &quot;&quot;;
});
});
});
} catch (err) {
console.error(&quot;switcher.js: &quot;, err);
} finally {
}
});
</code></pre>
<h2 id="3-создадим-scss-описание-компонентов-switcher-на-странице">3. Создадим SCSS описание компонентов Switcher на странице</h2>
<pre><code>// assets/scss/_switcher.scss
.switcher {
$padding: 0.15rem;
$indicatorSize: 1.8rem;
$boxColorActive: #26b7ff;
$transitionTime: 300ms;
display: inline-flex;
flex-direction: column;
&amp;__label {
display: inline-flex;
justify-content: center;
font-family: Arial, sans-serif;
margin-bottom: 0.1rem;
}
&amp;__box {
width: 4.4rem;
height: 2rem;
display: inline-flex;
align-items: center;
box-sizing: border-box;
padding: $padding;
background: #d8d8d8;
border-radius: 2rem;
transition: background $transitionTime;
position: relative;
}
&amp;__indicator {
width: $indicatorSize;
height: $indicatorSize;
display: inline-flex;
background-color: white;
border-radius: 50%;
transition: left $transitionTime;
position: absolute;
left: $padding;
}
&amp;__checkbox {
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
margin: 0;
position: absolute;
left: 0;
top: 0;
}
&amp;._on &amp; {
&amp;__indicator {
animation-name: indicatorScale;
animation-duration: $transitionTime;
left: calc(100% - $indicatorSize - $padding);
}
&amp;__box {
background: $boxColorActive;
}
}
&amp;._off &amp; {
&amp;__indicator {
animation-name: indicatorScale;
animation-duration: $transitionTime;
left: $padding;
}
}
}
@keyframes indicatorScale {
0% {
transform: scaleY(1);
filter: blur(0.15rem);
}
10% {
transform: scaleY(0.95);
}
20% {
transform: scaleY(0.9);
}
50% {
transform: scaleY(0.8);
}
80% {
transform: scaleY(0.9);
}
90% {
transform: scaleY(0.95);
}
100% {
transform: scaleY(1);
filter: unset;
}
}
</code></pre>
<h2 id="4-готово-теперь-у-нас-есть-работающий-компонент-switcher">4. Готово, теперь у нас есть работающий компонент Switcher</h2>
<p><strong>При этом у него внутри есть обычный <code>&lt;input type=&quot;checkbox&quot;&gt;</code></strong> имеющий значение <code>checked</code> и <code>value</code> равные <code>true</code> или <code>false</code> </p>
<h2 id="код-статьи-хранится-в-github-репозитории">Код статьи хранится в <a href="https://github.com/artemsites/switcher">GitHub репозитории</a></h2>
<h2 id="посмотреть-компонент-switcher-в-действии-можно-здесь">Посмотреть компонент Switcher в действии можно <a target="_blank" href="https://practical-web.ru/demo/switcher/index.html" title="Посмотреть компонент Switcher в действии">здесь</a></h2>

Как сделать Switcher на CSS стилизовав input type="checkbox"

Checkbox Switcher на CSS

Перед работой нам понадобится установить препроцессор CSS - SCSS
и какой нибудь сборщик frontend приложений,
например сборщик Vite.js.
Если вы его не умеете устанвливать,
то можете узнать как это делать в статье об установке и применении сборщика Vite.js

1. Создадим html структуру Switcher компонента

<label class="switcher">
  <span class="switcher__label">Switcher</span>
  <div class="switcher__box">
    <span class="switcher__indicator"></span>
    <input class="switcher__checkbox" type="checkbox" name="" id="">
  </div>
</label>

2. Создадим JavaScript объявление логики компонентов Switcher на странице

// assets/js/switcher.js
document.addEventListener("DOMContentLoaded", function () {
  try {

    const switcherAll = document.querySelectorAll(".switcher");
    switcherAll.forEach(function (switcher) {
      switcher.addEventListener("click", function (e) {
        if (switcher.classList.contains("_on")) {
          switcher.classList.remove("_on");
          switcher.classList.add("_off");
        } else {
          switcher.classList.remove("_off");
          switcher.classList.add("_on");
        }

        // Установка значения checked в value
        const checkbox = switcher.querySelector(".switcher__checkbox");
        checkbox.value=checkbox.checked

        // Сброс анимации сплющивания
        const indicator = switcher.querySelector(".switcher__indicator");
        indicator.style.animationName = "none";
        requestAnimationFrame(function () {
          indicator.style.animationName = "";
        });
      });
    });

  } catch (err) {
    console.error("switcher.js: ", err);
  } finally {
  }
});

3. Создадим SCSS описание компонентов Switcher на странице

// assets/scss/_switcher.scss

.switcher {
  $padding: 0.15rem;
  $indicatorSize: 1.8rem;
  $boxColorActive: #26b7ff;
  $transitionTime: 300ms;

  display: inline-flex;
  flex-direction: column;

  &__label {
    display: inline-flex;
    justify-content: center;

    font-family: Arial, sans-serif;
    margin-bottom: 0.1rem;
  }

  &__box {
    width: 4.4rem;
    height: 2rem;

    display: inline-flex;
    align-items: center;

    box-sizing: border-box;
    padding: $padding;
    background: #d8d8d8;
    border-radius: 2rem;

    transition: background $transitionTime;

    position: relative;
  }

  &__indicator {
    width: $indicatorSize;
    height: $indicatorSize;

    display: inline-flex;

    background-color: white;
    border-radius: 50%;

    transition: left $transitionTime; 

    position: absolute;
    left: $padding;
  }

  &__checkbox {
    width: 100%;
    height: 100%;

    opacity: 0;
    cursor: pointer;

    margin: 0;
    position: absolute;
    left: 0;
    top: 0;
  }

  &._on & {
    &__indicator {
      animation-name: indicatorScale;
      animation-duration: $transitionTime;

      left: calc(100% - $indicatorSize - $padding);
    }

    &__box {
      background: $boxColorActive;
    }
  }

  &._off & { 
    &__indicator {
      animation-name: indicatorScale;
      animation-duration: $transitionTime;

      left: $padding;
    }
  }
}

@keyframes indicatorScale {
  0% {
    transform: scaleY(1);
    filter: blur(0.15rem);
  }

  10% {
    transform: scaleY(0.95);
  }

  20% {
    transform: scaleY(0.9);
  }

  50% {
    transform: scaleY(0.8);
  }

  80% {
    transform: scaleY(0.9);
  }

  90% {
    transform: scaleY(0.95);
  }

  100% {
    transform: scaleY(1);
    filter: unset;
  }
}

4. Готово, теперь у нас есть работающий компонент Switcher

При этом у него внутри есть обычный <input type="checkbox"> имеющий значение checked и value равные true или false

Код статьи хранится в GitHub репозитории

Посмотреть компонент Switcher в действии можно здесь

Видео-разбор статьи

[[youtube id="8uEi_WK8zC8"]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment