I've been trying to make a toggleable button through css, and I've been wondering if there's a way to transition between these two states smoothly when the checkbox is clicked, I've managed to do it without animations but it'd be neat if it was possible to anime the transition
toggle-button {
position: relative;
display: inline-block;
width: 120px;
height: 40px;
margin-left: 100px;
}
.toggle-button input{
opacity: 0;
height: 0;
width: 0;
}
.options-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to right, white 50%, gray 50%);
border-radius:3px;
}
.button-options {
display: grid;
grid-template-columns: 1fr 1fr;
justify-items: center;
align-items: center;
height: 100%;
width: 100%;
background: linear-gradient(to right, black 50%, white 50%);
-webkit-background-clip: text;
-webkit-transition: .4s;
transition: .4s;
cursor: pointer;
}
.toggle-button input:checked + .options-wrapper {
background: linear-gradient(to right, gray 50%, white 50%);
}
.toggle-button input:checked + .options-wrapper > .button-options {
background: linear-gradient(to right, white 50%, black 50%);
-webkit-background-clip: text;
}
#keyframes shiftOpacity {
from { opacity: 0; }
to { opacity: 1; }
}
.button-options > p {
color: transparent
}
<label class="toggle-button">
<input type="checkbox">
<div class="options-wrapper">
<div class="button-options">
<p>Daily</p>
<p>Hourly</p>
</div>
</div>
</label>
This seems to work, i created a background div that goes back and forth when the input is checked, i also changed how the text change colors.
toggle-button {
position: relative;
display: inline-block;
width: 120px;
height: 40px;
margin-left: 100px;
}
.toggle-button input{
opacity: 0;
height: 0;
width: 0;
}
.options-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius:3px;
}
.button-options {
display: grid;
grid-template-columns: 1fr 1fr;
justify-items: center;
align-items: center;
height: 100%;
width: 100%;
color: gray;
cursor: pointer;
position: relative;
}
.button-options .bg {
position: absolute;
height: 100%;
width: 50%;
left: 0;
background: gray;
transition: .5s ease-in-out;
}
.toggle-button input:checked + .options-wrapper .bg {
left: 50%;
}
.toggle-button input + .options-wrapper p:first-of-type {
color: white;
}
.toggle-button input:checked + .options-wrapper p:first-of-type {
color: gray;
}
.toggle-button input:checked + .options-wrapper p:last-of-type {
color: white;
}
.button-options p {
position: relative;
transition: .5s ease-in-out;
}
<label class="toggle-button">
<input type="checkbox">
<div class="options-wrapper">
<div class="button-options bg-left">
<div class="bg"></div>
<p>Daily</p>
<p>Hourly</p>
</div>
</div>
</label>
Related
Im trying to do the same button but without the need to make hover (running the animated background all the time).
I've tried different approach like using background-clip, shadows, etc but unfortunately without success.
Maybe if I use another element like a div and span can work but I really want to do it with a button.
Codepen
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: #000;
}
.glow-on-hover {
width: 220px;
height: 50px;
border: none;
outline: none;
color: #fff;
background: #111;
cursor: pointer;
position: relative;
z-index: 0;
border-radius: 10px;
}
.glow-on-hover:before {
content: '';
background: linear-gradient(45deg, #ff0000, #ff7300, #fffb00, #48ff00, #00ffd5, #002bff, #7a00ff, #ff00c8, #ff0000);
position: absolute;
top: -2px;
left: -2px;
background-size: 400%;
z-index: -1;
filter: blur(5px);
width: calc(100% + 4px);
height: calc(100% + 4px);
animation: glowing 20s linear infinite;
opacity: 0;
transition: opacity .3s ease-in-out;
border-radius: 10px;
}
.glow-on-hover:active {
color: #000
}
.glow-on-hover:active:after {
background: transparent;
}
.glow-on-hover:hover:before {
opacity: 1;
}
.glow-on-hover:after {
z-index: -1;
content: '';
position: absolute;
width: 100%;
height: 100%;
background: #111;
left: 0;
top: 0;
border-radius: 10px;
}
#keyframes glowing {
0% {
background-position: 0 0;
}
50% {
background-position: 400% 0;
}
100% {
background-position: 0 0;
}
}
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<button class="glow-on-hover" type="button">HOVER ME, THEN CLICK ME!</button>
What is making your ::before pseudo-element to hide when it's not hovered is opacity:0. If you remove it, you will have the desired effect. Also, you might want to remove the glow-on-hover:hover:before selector since it's not going to be any use.
I've got the following CSS and HTML. The problem is, that when the mouse is moved over the button, the red rectangle flashes to the center instead of smoothly moving to the center. It is strange because when the mouse is moved away from the button, it moves back slowly. How can I make the red rectangle move to the center smooth?
.btn {
position: relative;
display: inline-block;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
top: -10px;
left: -10px;
}
.btn .bottom-right {
bottom: -10px;
right: -10px;
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='btn'>
<span class='btn-text'>button</span>
<div class='rect top-left blue-translucent'></div>
<div class='rect bottom-right red-translucent'></div>
</div>
For some reason, it didn't work with bottom: -10px and right: -10px. I'm not sure if this has to do with my code or if this is a browser problem, but the easy fix is to use the top and left properties instead:
.btn {
position: relative;
display: inline-block;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
top: -10px;
left: -10px;
}
.btn .bottom-right {
top: 10px;
left: 10px;
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='btn'>
<span class='btn-text'>button</span>
<div class='rect top-left blue-translucent'></div>
<div class='rect bottom-right red-translucent'></div>
</div>
.red-translucent {
background-color: red;
top: 10px;
left: 10px;
}
Use transform instead of top, left, bottom, right like this:
.btn {
position: relative;
display: flex;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
transform: translate(-10px, -10px);
}
.btn .bottom-right {
transform: translate(10px, 10px);
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
transform: translate(0px, 0px);
}
This will work smoothly on either the move-in or move-out of the pointer.
lastly I'm developing a website, and I'm gonna implement here a little "button" in CSS.
My question is: How to make its shadow glowing without having to put cursor on it and hover? I want its shadow to glow automatically. I've tried to change some attributes from code below, but it doesn't work. Anybody know how to do it exactly? Any help appreciated :)
Here is some code snippet I tried to modify:
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: #000;
}
.glow-on-hover {
width: 220px;
height: 50px;
border: none;
outline: none;
color: #fff;
background: #111;
cursor: pointer;
position: relative;
z-index: 0;
border-radius: 10px;
}
.glow-on-hover:before {
content: '';
background: linear-gradient(45deg, #ff0000, #ff7300, #fffb00, #48ff00, #00ffd5, #002bff, #7a00ff, #ff00c8, #ff0000);
position: absolute;
top: -2px;
left:-2px;
background-size: 400%;
z-index: -1;
filter: blur(5px);
width: calc(100% + 4px);
height: calc(100% + 4px);
animation: glowing 20s linear infinite;
opacity: 0;
transition: opacity .3s ease-in-out;
border-radius: 10px;
}
.glow-on-hover:active {
color: #000
}
.glow-on-hover:active:after {
background: transparent;
}
.glow-on-hover:hover:before {
opacity: 1;
}
.glow-on-hover:after {
z-index: -1;
content: '';
position: absolute;
width: 100%;
height: 100%;
background: #111;
left: 0;
top: 0;
border-radius: 10px;
}
#keyframes glowing {
0% { background-position: 0 0; }
50% { background-position: 400% 0; }
100% { background-position: 0 0; }
}
<button class="glow-on-hover" type="button">HOVER ME, THEN CLICK ME!</button>
Whole code and the exact button I wanna implement can be found on: https://codepen.io/leandrosimoes/pen/VqZxaG
This codepen has a yes / no toggle. the Yes doesn't display after the toggle has moved over it, but the No works? What css will get the Yes to show up?
https://codepen.io/trynn/pen/NWPNMdE
input[type="radio"].toggle {
display: none;
& + label{
cursor: pointer;
min-width: 60px;
border-radius: 30px;
&:hover{
background: none;
}
&:after{
background: blue;
content: "";
height: 100%;
position: absolute;
z-index:-1;
border-radius: 30px;
top: 0;
transition: left 200ms cubic-bezier(0.77, 0, 0.175, 1);
width: 100%;
}
}
&.toggle-left + label {
border-right: 0;
color: #fff;
&:after{
left: 100%;
}
}
&.toggle-right + label{
margin-left: -5px;
color: #fff;
&:after{
left: -100%;
}
}
&:checked + label {
cursor: default;
color: #fff;
transition: color 200ms;
&:after{
left: 0;
}
}
}
You added 2 blue bubbles for toggle-left and toggle-right since you only needed one of them moving from one to another. For your case, in order to not go over the 'yes', you should remove the :after in toggle-right. Try this:
.toggle-switch-container {
position: relative;
line-height: 32px;
border-radius: 30px;
width: fit-content;
margin-left: auto;
margin-right: auto;
margin-bottom:25px;
background-color: rgba(0, 0, 0, 1);
z-index:1;
}
.btn{
display: inline-block;
padding: 10px;
position: relative;
text-align: center;
transition: background 600ms ease, color 600ms ease;
z-index:100;
}
input[type="radio"].toggle {
display: none;
& + label{
cursor: pointer;
min-width: 60px;
border-radius: 30px;
&:hover{
background: none;
}
}
&.toggle-left + label {
border-right: 0;
color: #fff;
&:after{
background: blue;
content: "";
height: 100%;
position: absolute;
z-index:-1;
border-radius: 30px;
top: 0;
transition: left 200ms cubic-bezier(0.77, 0, 0.175, 1);
width: 100%;
left: 100%;
}
}
&.toggle-right + label{
margin-left: -5px;
color: #fff;
}
&:checked + label {
cursor: default;
color: #fff;
transition: color 200ms;
&:after{
left: 0;
}
}
}
For a simple explanation why this works: for 2 elements having the same z-index, the last element comes in front of the other. Your 2 toggle buttons had the same z-index, so their :after, so the toggle-right:after comes in front of toggle-left blocking the 'yes'. By removing the :after of toggle-right, you removed the element blocking the 'yes' solving the problem.
I think you are looking for this
body {
background-color: #ddd;
}
/*Style main div and remove default checkbox*/
.switch {
position: relative;
width: 75px;
margin: 0 auto;
}
.switch-checkbox {
display: none;
}
/*Style words and oval switch */
.switch-labels {
display: block;
overflow: hidden;
cursor: pointer;
border-radius: 20px;
}
.switch-text {
display: block;
width: 200%;
margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.switch-text:before,
.switch-text:after {
float: left;
width: 50%;
line-height: 30px;
color: white;
box-sizing: border-box;
}
.switch-text:before {
content: "ON";
padding-left: 10px;
background-color: #E1F6FF;
color: #000000;
}
.switch-text:after {
content: "OFF";
padding-right: 10px;
background-color: #4D5585;
color: #FFFFFF;
text-align: right;
}
/*Style center dot*/
.switch-dot {
width: 30px;
height: 30px;
background: #FFFFFF;
position: absolute;
top: 0;
bottom: 0;
right: 41px;
margin-right: 5px;
border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.switch-dot:after{
content: "";
position: absolute;
width: 20px;
height: 20px;
background-size: cover;
background-image: url('http://www.free-icons-download.net/images/multiply-icon-27981.png');
margin: 5px 0 0 5px;
}
/*State changer*/
.switch-checkbox:checked+.switch-labels .switch-text {
margin-left: 0;
}
.switch-checkbox:checked+.switch-labels .switch-dot {
right: 0px;
margin-right: 0px;
}
<div class="switch">
<input type="checkbox" name="switch" class="switch-checkbox" id="myswitch" checked>
<label class="switch-labels" for="myswitch">
<span class="switch-text"></span>
<span class="switch-dot"></span>
</label>
</div>
Using 2 text as on and off
.toggle-label {
position: relative;
display: block;
width: 300px;
height: 80px;
margin-top: 8px;
border: 1px solid #808080;
margin: 200px auto;
}
.toggle-label input[type=checkbox] {
opacity: 0;
position: absolute;
width: 100%;
height: 100%;
}
.toggle-label input[type=checkbox]+.back {
position: absolute;
width: 100%;
height: 100%;
background: #ed1c24;
transition: background 150ms linear;
}
.toggle-label input[type=checkbox]:checked+.back {
background: #00a651; /*green*/
}
.toggle-label input[type=checkbox]+.back .toggle {
display: block;
position: absolute;
content: ' ';
background: #fff;
width: 50%;
height: 100%;
transition: margin 150ms linear;
border: 1px solid #808080;
border-radius: 0;
}
.toggle-label input[type=checkbox]:checked+.back .toggle {
margin-left: 150px;
}
.toggle-label .label {
display: block;
position: absolute;
width: 50%;
color: #000;
line-height: 80px;
text-align: center;
font-size: 2em;
}
.toggle-label .label.on { left: 0px; }
.toggle-label .label.off { right: 0px; }
.toggle-label input[type=checkbox]:checked+.back .label.on {
color: #fff;
}
.toggle-label input[type=checkbox]+.back .label.off {
color: #000;
}
.toggle-label input[type=checkbox]:checked+.back .label.off {
color: #000;
}
<label class='toggle-label'>
<input type='checkbox'/>
<span class='back'>
<span class='toggle'></span>
<span class='label on'>ON</span>
<span class='label off'>OFF</span>
</span>
</label>
I want to make the following animation:
One div with 2 same arrows and on hover first arrow should move on left/right. I tried to do it, but it unsuccessfully. I'm setting background with 2 images, but how I can set animation for 1 of the images like the gif?
.arrow-right2 {
content: "";
background: transparent url(https://i.imgur.com/u7cYXIo.png) 0 -185px no-repeat, transparent url(https://i.imgur.com/u7cYXIo.png) 0 -185px no-repeat;
height: 35px;
position: absolute;
top: -5%;
left: 0;
width: 35px;
}
Try to use 2 different divs with the same arrows, with position absolute and use this to overlap the two arrows. If you can, use a single image, not a sprite. Then apply the effect on hover on one of the images.
body {
background: red;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
position: relative;
}
.arrow1 {
background: url('https://i.imgur.com/u7cYXIo.png') no-repeat -17px -199px;
width: 12px;
height: 24px;
display: block;
left: 0;
position: absolute;
}
.arrow2 {
background: url('https://i.imgur.com/u7cYXIo.png') no-repeat -17px -199px;
width: 12px;
height: 24px;
display: block;
position: absolute;
transition: all 0.4s;
left: 0;
}
.arrow2:hover {
left: -10px;
transition: all 0.4s;
}
<div class="container">
<div class="arrow1">
</div>
<div class="arrow2">
</div>
</div>
You can adjust background-position like below. You start with a different position for each one then you make them the same:
.arrow {
background:
url(https://i.imgur.com/u7cYXIo.png) -10px -185px,
url(https://i.imgur.com/u7cYXIo.png) 10px -185px,
red;
background-repeat:no-repeat;
height: 50px;
width: 50px;
transition:all 0.5s;
}
.arrow:hover {
background-position:10px -185px;
}
<div class="arrow"></div>
Or the opposite
.arrow {
background:
url(https://i.imgur.com/u7cYXIo.png),
url(https://i.imgur.com/u7cYXIo.png),
red;
background-position:10px -185px;
background-repeat:no-repeat;
height: 50px;
width: 50px;
transition:all 0.5s;
}
.arrow:hover {
background-position:
-10px -185px,
10px -185px;
}
<div class="arrow"></div>
And if you want to adjust coloration you can consider mix-blend-mode
.arrow {
background:
url(https://i.imgur.com/u7cYXIo.png),
url(https://i.imgur.com/u7cYXIo.png),
#000;
background-position:10px -185px;
background-repeat:no-repeat;
height: 50px;
width: 50px;
transition:all 0.5s;
position:relative;
}
.arrow:before {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background: red;
mix-blend-mode: multiply;
opacity:0;
transition:all 0.5s;
}
.arrow:hover {
background-position:
-10px -185px,
10px -185px;
}
.arrow:hover:before {
opacity:1;
}
<div class="arrow"></div>