Text blurs when using transition and scale Chrome and FireFox - css

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.

Related

When is CSS transition loaded and triggered?

Below is a CSS code snippet to transit a button from #33ae74 to #1ce when hover it.
.button {
font-size: 3em;
font-family: inherit;
border: none;
background-color: #33ae74;
padding: 0.5em 0.75em;
}
.button:hover {
background-color: #1ce;
transition: background-color 2s ease-out;
}
It works well. My question is: before mouse hover,there is no transition bind to the button,why transition works when hover it? In another case, when hover, transition bind to the button, meanwhile the background color also be changed to #1ce immediately,so there should no color be transited. but why we could still see the transition?
that's very simple just make the transition on the original element. By doing that the transition will work when you hover and will work when the over is done.
.button {
font-size: 3em;
font-family: inherit;
border: none;
background-color: #33ae74;
padding: 0.5em 0.75em;
transition: background-color 2s ease-out;
}
.button:hover {
background-color: #1ce;
}
<button class="button">hover over me</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/

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

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 */
}

CSS transform on a li forces text in children to 'jump' after scaling in firefox

I've wrote a simple sticky-notes page. Every note is a list item containing content in paragraph, delete button in span and an image with tooltip. Here`s a piece of HTML containing one note:
<ul id="wall" class="ui-sortable">
<li id="note1">
<a href="#">
<span class="del">x</span>
<p>1221212 23 23 3322 3223</p>
<img src="..."/>
<div class="tooltip">Tooltip</div>
</a>
</li>
.
.
.
</ul>
And here`s the css:
ul li a
{
outline: none;
text-decoration: none;
display: block;
height: 200px;
width: 200px;
-moz-transition: -moz-transform 0.2s ease;
}
ul li a:hover
{
-moz-transform: scale(1.1);
-webkit-transform: scale(1.1);
font-size: 105%;
position: relative;
}
ul li p
{
overflow: hidden;
margin: 0;
padding: 20px;
-moz-user-select: none;
font-size: 120%;
font-style: italic;
}
.del
{
-moz-user-select: none;
font-size: 22px;
position: absolute;
left: 183px;
float: right;
display: none;
padding: 2px 5px 0 0;
}
The issue is, that with this code whole note scales ok, but then after scaling is complete the text (both in p and span) resizes itself a bit (I don't know, about 1-2px) and it looks really bad. Removing -moz-transition from 'ul li a' fixes the issue, but then scaling isn't smooth at all. Has any of you encountered similiar issue?
I've tried this also:
-moz-transition: -moz-transform 0.2s ease;
-moz-transition: font-size 0.2s ease;
But this doesn't help. Is there any way to use css transformation scale without the 'jumping' text? I'd prefer not to use jQueryUI for now, it's too heavy for using it only for this simple task.
Here`s jsfiddle for this:
Notes
Of course you have to run it from firefox to observe the issue. On chrome it works ok AFAIK.
UPDATE: I've to run it under FF8.0, but I've installed 13.0.1 and this glitch is also visible there.
just change the font size 105% to 100%.
ul li a:hover
{
-moz-box-shadow: 10px 10px 7px black;
-webkit-box-shadow: 10px 10px 7px black;
-moz-transform: scale(1.1);
-webkit-transform: scale(1.1);
font-size: 100%;
position: relative;
}

Resources