Why doesn't a CSS transition to the default style work? - css

I've been procrastinating by trying to make a fancier HTML checkbox, using Font Awesome for icons. I'm almost happy with this: (CodePen)
HTML
<input type="checkbox" id="cb"/>
<label for="cb">
<i class='icon-check-sign'></i>
</label>
CSS
#cb {
display: none;
}
#cb + label {
font-size: 64px;
color: #002b36; /* black */
transition: color 1s;
}
/* hover */
#cb + label:hover > i {
color: #268bd2; /* blue */
transition: color 1s;
}
/* checked */
#cb:checked + label > i {
color: #859900; /* green */
transition: color 1s;
}
/* checked + hover */
#cb:checked + label:hover > i {
color: #dc322f; /* red */
transition: color 1s;
}
(The colours and transition duration are exaggerated to make the issue more visible.)
My problem is that the colour changes smoothly when going from the default state to the hover state (the cursor is moved over the icon), from hover to checked (the icon is clicked), and from hover+checked to checked (the cursor is moved away). However, when going from hover back to default (the mouse cursor is moved away from an unchecked icon), the color doesn't transition but changes immediately.
Why does that happen and how could it be fixed? Bonus question: can this effect be somehow done without as much extra markup? (The <i> and the <label>.)
(I also suppose this would be more usable if I swapped between a checked and unchecked icon, but that seems like it would require chaining two transitions on different elements and I've no idea if that's even possible with CSS alone.)

You're missing a > i
#cb + label > i {
font-size: 32px;
color: #002b36; /* black */
transition: color 1s;
}
Updated CodePen

if you have a transtion in the :hover like this
something:hover{
transition: ...;
}
The transition will only apply when you hover so you need to put the transition in the default style for it to transition all states
like this
something{
color: red;
transition: all 200ms ease;
}
something:hover{
color: blue;
}
So in your case you need to add the following styles.
#cb + label i {
transition: color 1s;
}

solution
demo: http://jsfiddle.net/SuunK/2/
the markup:
<input type=checkbox id=cb hidden>
<label for=cb></label>
the style:
[for=cb] {
padding: 5px 16px;
position: relative;
border-radius: 4px;
background-color: black;
transition: background-color 1s;
}
[for=cb]:before,[for=cb]:after{
content:'';
position:absolute;
}
[for=cb]:before{
width: 6px;
height: 10px;
background: white;
-webkit-transform: rotateZ(-45deg);
left: 8px;
bottom: 6px;
}
[for=cb]:after{
width: 5px;
height: 16px;
background: white;
-webkit-transform: rotateZ(45deg);
right: 13px;
bottom: 5px;
}
[for=cb]:hover{
background-color: #268bd2; /* blue */
}
/* checked */
#cb:checked + label{
background-color: #859900; /* green */
}
/* checked + hover */
#cb:checked + label:hover{
background-color: #dc322f; /* red */
}

Related

css button background colour showing another colour in delay in transition

I am trying to button background colour transition on hover.
I observed that when I hover the button it is showing different colour in delay time.
Below is the code.
.button {
background-color: aqua;
transition: background-color 1s ease 0.5s;
width: 500px;
height: 500px;
font-size: 24pt;
}
.button:hover {
background-color: blue;
}
.button:active {
background-color: rgb(216, 36, 4);
}
<button type="button" class="button">button</button>
If you remove delay time, also you will observe the flickering effect when you hover or select.
Here is the video on how it is behaving. https://youtu.be/O0q-SK-eejk
Kindly, Help me to solve it, not to show different colour in delay time.
The reason you see the gray color is because of the default styles added by the browser for the background property. Try the following code.
.button {
background: inherit;
background-color: aqua;
transition: background-color 1s ease 0.5s;
width: 500px;
height: 500px;
font-size: 24pt;
}
.button:hover {
background: inherit;
background-color: blue;
}
.button:active {
background-color: rgb(216, 36, 4);
}
<button type="button" class="button">button</button>

Why is there a delay for the transition of my pseudo elements?

I need to animate both of the element and its pseudo element.
Then I noticed, when I hover, everything is fine. But then I stop hovering, the Home animates first and after that, the pseudo element Link starts animating.
Why it behaves like this? Is there a way to make them animate simultaneously?
Here's a simplified recreation of my problem:
a {
color: blue;
transition: all 1s;
text-decoration: none;
}
a:hover {
color: red;
font-size: 48px;
}
a:hover::before {
color: green;
font-size: 32px;
}
a::before {
content: 'Link:';
transition: all 1s;
}
Home
I'm using MacOS with Chrome Version 83.0.4103.97 (Official Build) (64-bit)
If you can't reproduce the problem, here's a screengrab of it:
I also assigned the default values ​​to ::before and works fine. I think it trying to inherit the default values and it's confusing.
a {
color: blue;
transition: all 1s;
text-decoration: none;
}
a:hover {
color: red;
font-size: 48px;
}
a::before {
content: 'Link:';
transition: all 1s;
font-size: 1rem;
color: blue;
}
a:hover::before {
color: green;
font-size: 32px;
}
Home
Because there is no default font-size for the pseudo element so the pseudo element will inherit the font-size of the a. Here is what is happening:
we initially have both element at font-size X (X is based on your other properties, 16px here)
On hover the pseudo element will have 32px and a will have 48px
when you unhover (and here is the trick) the pseudo element will inherit for a moment the font-size of the a (48px) so your transition will be from 32px to 48px - y where y is changing du to the transition applied to a until the 48px - y is back to X
Same logic apply with coloration because it's also inherited. Simply set a default font-size and color
a {
color: blue;
transition: all 1s;
text-decoration: none;
}
a:hover {
color: red;
font-size: 48px;
}
a:hover::before {
color: green;
font-size: 32px;
}
a::before {
content: 'Link:';
transition: all 1s;
font-size:16px;
color:blue;
}
Home
I found a solution on mouseover it's a bit ugly but at least it's working smoothly
a {
color: blue;
transition: all 1s;
text-decoration: none;
}
a::before {
content: 'Link:';
/* transition: all 1s; */
}
a:hover {
color: red;
font-size: 48px;
}
a:hover::before {
transition: all 1s;
color: green;
font-size: 32px;
}
Home

Translate text and <i>-tag inside an <a>-tag with CSS

So I have the following situation for a button I am making:
<i class="fas fa-angle-left"></i> Previous
which can be seen fully on https://jsfiddle.net/pre3xzL5/ (<i>-tag from Font Awesome).
Basically I want the text inside the button to be centered from the beginning (it isn't now), and then when I hover the arrow (<i>-tag) appears and comes from the middle to the left, and then the next should also go from the middle (centered as it should be) at moved a bit to the right. However, now, the next is starting at the place where it should be when hovered. It makes sense since the <i>-tag is taking up space, but that's the question: Can I correct this ?
I have done it using margins instead. But I've read that using margins for transitions and such is bad practice, and not good for performance - hence the try with translate.
These two transition statements are the only ones you need, set initially on the relevant elements. The position absolute changed to position relative on hover gets you the effect you want.
.button
{
transition: all 0.15s ease-in-out;
i
{
position:absolute;
transition: all 0.15s ease-in-out;
}
}
.button:hover
{
i
{
position:relative;
}
}
html:
<i class="fas fa-angle-left"></i> Previous
scss:
.button {
background: red;
padding: 20px 20px;
color: white;
text-transform: uppercase;
border-radius: 50px;
cursor: pointer;
position: relative;
justify-self: center;
display: inline-block;
width: 140px;
text-decoration: none;
text-align: center;
transition: all 0.15s ease-in-out;
border: 1px red solid;
i {
position:absolute;
opacity: 0.0;
transition: all 0.15s ease-in-out;
transform: translateX(.5em);
}
}
.button:hover {
background: red;
border: 1px black solid;
i {
position:relative;
transform: translateX(0px);
opacity: 1.0;
}
}
https://jsfiddle.net/pre3xzL5/1/

Text blurs when using transition and scale Chrome and FireFox

when I use both transition andtransform, then the animations are not very smooth on both chrome andfirefox. It blurs when you hover over it. The only browser on which it is normal is IE.
Chome / FireFox (Note the text, when the animation starts it start to be blurry. When it finishes it pops back to smooth letters.)
Desired result (This is working in IE)
How do I make these animations also smooth on chrome and firefox?
Snippet:
as soon as the transition is complete, the element has to be focused again. Thats what it looks like now on chrome and firefox.
button {
background-color: cornflowerblue;
border: 1px solid cornflowerblue;
font-weight: bold;
font-size: 14px;
color: #fff;
padding: 10px;
border-radius: 3px;
transition: all .33s ease-in-out;
}
button:hover {
transform: scale(1.1);
transition: all .33s ease-in-out;
}
<button>Hover me</button>
You can accomplish a very similar effect using font relative units (em) and increasing the element font-size on hover.
button {
font-size: .875em; /* =14/16 or whatever your base font size is */
padding: .625em; /* =10/16 */
border-radius: .1875em; /* =3/16 */
}
button:hover {
font-size: 1em; /* close enough to 1.1x */
}
Note this generally considered to be less performant than using transforms, at the very least try to position the element so that there are fewer re-flows around it.
Chrome 64 on Windows 10:
button {
background-color: cornflowerblue;
border: 1px solid cornflowerblue;
font-weight: bold;
font-size: .875em; /* =14/16 or whatever your base font size is */
color: #fff;
padding: .625em; /* =10/16 */
border-radius: .1875em; /* =3/16 */
transition: all .33s ease-in-out;
transform: translateX(-50%) translateY(-50%);
}
button:hover {
font-size: 1em; /* close enough to 1.1x */
transition: all .33s ease-in-out;
}
<span style="position: relative; left: 2.5em; top: 1em;">
<button>Hover me</button>
</span>
I managed to remove the blur on Firefox with:
Backface visibility hidden fixes the problem as it simplifies the animation to just the front of the object, whereas the default state is the front and the back.
backface-visibility: hidden;
or ( or both )
TranslateZ also works as it is a hack to add hardware acceleration to the animation.
transform: translateZ(0);
You can try if perspective can fix your issue, it fixes the text into it's z-axis, no technical idea why.
button {
background-color: cornflowerblue;
border: 1px solid cornflowerblue;
font-weight: bold;
font-size: 14px;
color: #fff;
padding: 10px;
border-radius: 3px;
transition: all .33s ease-in-out;
-webkit-perspective: 1;
perspective: 1;
}
button:hover {
transform: scale(1.1);
transition: all .33s ease-in-out;
}
<button>Hover me</button>
The best and so far only way I found which removes the blur effect is to scale down the element first, and then scaling it up to its original size.
Here's an example:
button {
background-color: cornflowerblue;
border: 1px solid cornflowerblue;
font-weight: bold;
font-size: 16px;
color: #fff;
padding: 20px;
border-radius: 3px;
transition: all .33s ease-in-out;
transform:scale(0.7);
}
button:hover {
transform : perspective(1px) scale(1);
transition: all .33s ease-in-out;
}
<button>Hover me</button>
I know this is not the desired result but I looked quite hard and didn't find anything better.

Issues getting my CSS transition to work

Edit: I just applied the CSS to my website and it actually works. Apparently it was in the editor it was not. Not sure what the deal was, but it seems to work fine outside of the editor.
I'm trying to create a custom checkbox based on the style here:http://codepen.io/CreativeJuiz/pen/BiHzp
I am trying to get the checkboxes background to transition when it is checked. However I am unable to get the transition to work, it just snaps right to the next color when checked.
/* Base for label styling */
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
position: absolute;
left: -9999px;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
position: relative;
padding-left: 25px;
cursor: pointer;
}
/* checkbox aspect */
[type="checkbox"] + label:before{
content: '';
position: absolute;
left:0; top: 2px;
width: 17px; height: 17px;
border: 1px solid #aaa;
background: #f8f8f8;
border-radius: 3px;
box-shadow: inset 0 1px 3px rgba(0,0,0,.3)
transition-duration: 0.5s;
transition-property: all;
}
/* Checked Transition */
[type="checkbox"]:checked + label:before {
background-color: #1ba8c4;
}
What am I doing wrong here?
Add transition to the checked element too.
[type="checkbox"]:checked + label:before {
background-color: #1ba8c4;
transition-duration: 0.5s;
transition-property: all;
}
It supposed to work. :)

Resources