Pure CSS Switches with Custom Properties
A Pen by Stas Melnikov on CodePen.
<div class="page"> | |
<div class="page__demo"> | |
<div class="main-container"> | |
<div class="page__container"> | |
<label class="switch switch_type1" role="switch"> | |
<input type="checkbox" class="switch__toggle" checked> | |
<span class="switch__label"></span> | |
</label> | |
<label class="switch switch_type2" role="switch"> | |
<input type="checkbox" class="switch__toggle"> | |
<span class="switch__label"></span> | |
</label> | |
<label class="switch switch_type3" role="switch"> | |
<input type="checkbox" class="switch__toggle" checked> | |
<span class="switch__label"></span> | |
</label> | |
</div> | |
</div> | |
</div> | |
<footer class="footer"> | |
<div class="main-container footer__container"> | |
<a href="http://stas-melnikov.ru/donate/" rel="noopener noreferrer" target="_blank">Liked? Please, look the page</a> | |
<a href="http://stas-melnikov.ru" class="melnik909" rel="noopener noreferrer" target="_blank">Developed by Stas Melnikov</a> | |
</div> | |
</footer> | |
</div> |
A Pen by Stas Melnikov on CodePen.
.switch{ | |
--uiSwitchSize: var(--switchSize, 64px); | |
--uiSwitchBgColor: var(--switchBgColor, #f1f1f1); | |
--uiSwitchBgColorActive: var(--switchBgColorActive, #4ed164); | |
--uiSwitchBorderColorActive: var(--switchBorderColorActive, #fff); | |
--uiSwitchBorderColorFocus: var(--switchBgColorFocus, #43b556); | |
--uiSwitchButtonBgColor: var(--switchButtonBgColor, #fff); | |
display: inline-block; | |
position: relative; | |
cursor: pointer; | |
-webkit-tap-highlight-color: transparent; | |
} | |
.switch__label{ | |
display: block; | |
width: 100%; | |
height: 100%; | |
} | |
.switch__toggle{ | |
width: 0; | |
height: 0; | |
opacity: 0; | |
position: absolute; | |
top: 0; | |
left: 0; | |
} | |
.switch__toggle:focus ~ .switch__label{ | |
box-shadow: 0 0 0 var(--uiSwitchThickFocus, 4px) var(--uiSwitchBorderColorFocus); | |
} | |
.switch__toggle:checked:focus ~ .switch__label{ | |
box-shadow: 0 0 0 var(--uiSwitchThickFocus, 4px) var(--uiSwitchBorderColorActive); | |
} | |
.switch__label:before, .switch__label:after{ | |
content: ""; | |
cursor: pointer; | |
position: absolute; | |
top: 0; | |
left: 0; | |
} | |
.switch__label:before{ | |
width: 100%; | |
height: 100%; | |
box-sizing: border-box; | |
background-color: var(--uiSwitchBgColor); | |
} | |
.switch__label:after{ | |
top: 50%; | |
z-index: 3; | |
transition: transform .4s cubic-bezier(0.44,-0.12, 0.07, 1.15); | |
} | |
/* type 1 */ | |
.switch_type1{ | |
--uiSwitchBorderRadius: var(--switchBorderRadius, 60px); | |
width: var(--uiSwitchSize); | |
height: calc((var(--uiSwitchSize) / 2)); | |
border-radius: var(--uiSwitchBorderRadius); | |
background-color: var(--uiSwitchBgColorActive); | |
} | |
.switch_type1 .switch__label{ | |
border-radius: var(--uiSwitchBorderRadius); | |
} | |
.switch_type1 .switch__label:before{ | |
border-radius: var(--uiSwitchBorderRadius); | |
transition: opacity .2s ease-out .1s, transform .2s ease-out .1s; | |
transform: scale(1); | |
opacity: 1; | |
} | |
.switch_type1 .switch__toggle:checked ~ .switch__label:before{ | |
transform: scale(0); | |
opacity: .7; | |
} | |
.switch_type1 .switch__label:after{ | |
width: calc(var(--uiSwitchSize) / 2); | |
height: calc(var(--uiSwitchSize) / 2); | |
transform: translate3d(0, -50%, 0); | |
background-color: var(--uiSwitchButtonBgColor); | |
border-radius: 100%; | |
box-shadow: 0 2px 5px rgba(0, 0, 0, .3); | |
} | |
.switch_type1 .switch__toggle:checked ~ .switch__label:after{ | |
transform: translate3d(100%, -50%, 0); | |
} | |
/* type 2 */ | |
.switch_type2{ | |
--uiSwitchIndent: var(--switchIndent, 8px); | |
--uiSwitchBorderRadius: var(--switchBorderRadius, 60px); | |
width: var(--uiSwitchSize); | |
height: calc((var(--uiSwitchSize) / 2)); | |
border-radius: var(--uiSwitchBorderRadius); | |
background-color: var(--uiSwitchBgColorActive); | |
} | |
.switch_type2 .switch__label{ | |
border-radius: var(--uiSwitchBorderRadius); | |
} | |
.switch_type2 .switch__label:before{ | |
border-radius: var(--uiSwitchBorderRadius); | |
transition: opacity .2s ease-out .1s, transform .2s ease-out .1s; | |
transform: scale(1); | |
opacity: 1; | |
} | |
.switch_type2 .switch__toggle:checked ~ .switch__label:before{ | |
transform: scale(0); | |
opacity: .7; | |
} | |
.switch_type2 .switch__toggle ~ .switch__label:after{ | |
width: calc((var(--uiSwitchSize) / 2) - calc(var(--uiSwitchIndent) * 2)); | |
height: calc((var(--uiSwitchSize) / 2) - calc(var(--uiSwitchIndent) * 2)); | |
transform: translate3d(var(--uiSwitchIndent), -50%, 0); | |
background-color: var(--uiSwitchButtonBgColor); | |
border-radius: 100%; | |
} | |
.switch_type2 .switch__toggle:checked ~ .switch__label:after{ | |
transform: translate3d(calc(var(--uiSwitchSize) - calc((var(--uiSwitchSize) / 2) - calc(var(--uiSwitchIndent) * 2)) - var(--uiSwitchIndent)), -50%, 0); | |
} | |
/* type 3 */ | |
.switch_type3{ | |
--uiSwitchIndent: var(--switchIndent, 8px); | |
width: var(--uiSwitchSize); | |
height: calc((var(--uiSwitchSize) / 2)); | |
background-color: var(--uiSwitchBgColorActive); | |
} | |
.switch_type3 .switch__toggle:checked ~ .switch__label:before{ | |
background-color: var(--uiSwitchBgColorActive); | |
} | |
.switch_type3 .switch__label:after{ | |
width: calc((var(--uiSwitchSize) / 2) - calc(var(--uiSwitchIndent) * 2)); | |
height: calc((var(--uiSwitchSize) / 2) - calc(var(--uiSwitchIndent) * 2)); | |
transform: translate3d(var(--uiSwitchIndent), -50%, 0); | |
background-color: var(--uiSwitchButtonBgColor); | |
} | |
.switch_type3 .switch__toggle:checked ~ .switch__label:after{ | |
transform: translate3d(calc(var(--uiSwitchSize) - calc((var(--uiSwitchSize) / 2) - calc(var(--uiSwitchIndent) * 2)) - var(--uiSwitchIndent)), -50%, 0); | |
} | |
/* demo styles for switch */ | |
.switch{ | |
--switchSize: 128px; | |
margin-top: 40px; | |
} | |
.switch_type2{ | |
--switchBgColorActive: #e85c3f; | |
--switchBgColorFocus: #d54b2e; | |
} | |
/* | |
* demo page | |
*/ | |
@media screen and (min-width: 768px){ | |
html{ | |
font-size: 62.5%; | |
} | |
} | |
@media screen and (max-width: 767px){ | |
html{ | |
font-size: 50%; | |
} | |
} | |
body{ | |
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Open Sans, Ubuntu, Fira Sans, Helvetica Neue, sans-serif; | |
font-size: 1.6rem; | |
color: #222; | |
background-color: #dfdfdf; | |
margin: 0; | |
-webkit-overflow-scrolling: touch; | |
} | |
a{ | |
text-decoration: none; | |
color: #222; | |
} | |
.page{ | |
min-height: 100vh; | |
display: flex; | |
flex-direction: column; | |
justify-content: space-around; | |
} | |
.page__demo{ | |
flex-grow: 1; | |
display: flex; | |
} | |
.main-container{ | |
padding-left: 1rem; | |
padding-right: 1rem; | |
margin-left: auto; | |
margin-right: auto; | |
max-width: 1400px; | |
display: flex; | |
} | |
.page__container{ | |
margin: auto; | |
display: flex; | |
flex-direction: column; | |
} | |
.footer{ | |
padding-top: 1rem; | |
padding-bottom: 1rem; | |
text-align: center; | |
font-size: 1.4rem; | |
} | |
@media screen and (min-width: 641px){ | |
.footer__container{ | |
display: flex; | |
justify-content: space-between; | |
} | |
.melnik909{ | |
margin-left: 2rem; | |
} | |
} | |
@media screen and (max-width: 640px){ | |
.melnik909{ | |
display: none; | |
} | |
} |