<div class="container">
<div class="ripple"></div>
<div class="toggle" data-state="visible">
<svg xmlns="http://www.w3.org/2000/svg" class="eye" width="32" height="32"><circle cx="16" cy="15" r="3"/><path d="M30 16s-6.268 7-14 7-14-7-14-7 6.268-7 14-7 14 7 14 7zM22.772 10.739a8 8 0 1 1-13.66.189"/></svg>
</div>
<input type="text" id="password"
placeholder="Enter password" autocomplete="off">
<label for="password"></label>
</div>
$backgroundColor: #d4fce4;
$backgroundColorSelection: #d4fce4;
$boxShadow: #c1e6d0;
$boxShadow-hover: #c1e6d0;
@mixin size($width: null, $height: $width) {
width: $width;
height: $height;
}
%reset {
margin: 0;
padding: 0;
}
%flex {
display: flex;
justify-content: center;
align-items: center;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
html,
body {
@include size($width: 100%);
@extend %reset;
font-family: "Poppins", sans-serif;
}
body {
@extend %reset;
@extend %flex;
@include size($width:100%);
overflow: hidden;
background: $backgroundColor;
}
.container {
position: relative;
perspective: 80;
border-radius: 100vw;
}
.ripple {
position: absolute;
width: 180px;
height: 70px;
z-index: 90;
right: 0;
transition: transform 0.2s;
transition: transform 0.2s;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 25px;
overflow: hidden;
border-radius: 100vw;
pointer-events: none;
&.animate {
&:before {
animation: clicked 0.4s forwards cubic-bezier(0.5, 0.61, 0.36, 1);
}
}
&:before {
content: "";
background: rgba(0, 0, 0, 0.1);
width: 100px;
height: 100px;
position: absolute;
top: 50%;
right: 41px;
border-radius: 50%;
opacity: 0;
transform: translate(50%, -50%) scale(0.5);
pointer-events: none;
}
@keyframes clicked {
0% {
opacity: 0;
transform: translate(50%, -50%) scale(0.5);
}
10% {
opacity: 0.8;
}
100% {
opacity: 0;
transform: translate(50%, -50%) scale(1.2);
}
}
}
.toggle {
position: absolute;
width: 85px;
height: 70px;
background: transparent;
z-index: 100;
right: 0;
top: 0;
transition: transform 0.2s;
display: flex;
justify-content: center;
align-items: center;
padding: 0;
overflow: hidden;
border-radius: 100vw;
cursor: pointer;
&:before {
content: "";
display: block;
position: absolute;
left: 35px;
top: 25px;
height: 2px;
background: black;
transform-origin: top left;
transform: rotateZ(46deg);
transition: width 0.13s ease-out;
}
&[data-state="visible"] {
&:before {
width: 25px;
}
}
&[data-state="hidden"] {
&:before {
width: 0;
}
}
.eye {
fill: #000000;
transition: transform .13s linear;
stroke-width: 0;
transform: scale(1) rotateY(0);
path {
fill: none;
stroke-width: 1.5;
stroke-miterlimit: 5;
stroke: #000000;
}
}
&:active {
transform: scale(0.9);
+ input {
transform: rotateY(1deg);
letter-spacing: 1.5px;
box-shadow: 3px 0px 15px 0px $boxShadow-hover;
cursor: text;
&.password {
letter-spacing: 3px;
}
}
&:before {
transform: rotateZ(46deg) rotateY(5deg);
}
.eye {
transform: scale(0.75) rotateY(5deg);
}
}
}
input {
@extend %flex;
@include size($width: 340px, $height: 70px);
background: #ffffff;
border-radius: 10px;
will-change: transform;
border-radius: 100vw;
transition: all 0.2s ease;
cursor: pointer;
color: #ffffff;
font-size: 22px;
color: #000000;
outline: none;
text-align: left;
border: 0;
padding: 10px 80px 10px 30px;
transform-origin: left center;
transition: transform 0.13s;
font-family: "Poppins", sans-serif;
box-shadow: 0px 0px 30px 0px $boxShadow;
transition: letter-spacing 0.13s ease-out, box-shadow 0.13s ease-out;
&::selection {
background: $backgroundColorSelection;
}
&::placeholder {
color: $boxShadow;
}
&.password {
letter-spacing: 1px;
}
}
View Compiled
const eye = document.querySelector('.eye'),
ripple = document.querySelector('.ripple'),
toggle = document.querySelector('.toggle'),
input = document.querySelector('input');
function click(e) {
ripple.classList.add('animate');
input.classList.add('animate');
input.classList.toggle('password');
input.type === 'text' ? input.type = 'password' : input.type = 'text';
toggle.dataset.state = input.type === 'text' ? 'visible' : 'hidden';
}
toggle.addEventListener('click', click);
function removeAnimate() {
ripple.classList.remove('animate');
input.classList.remove('animate');
toggle.style.pointerEvents = 'all';
}
ripple.addEventListener('animationend', removeAnimate)
View Compiled