How to fix blurry Image on transform scale - html

When i put transform: scale(1.1); on hover on some element the image became blurry. How to fix this bug?
Example

Try this, it's work fine for me!
img {
-webkit-backface-visibility: hidden;
-ms-transform: translateZ(0); /* IE 9 */
-webkit-transform: translateZ(0); /* Chrome, Safari, Opera */
transform: translateZ(0);
}

TL;DR
transform: scale is actually scaling the original image, and because you are leaving it to the browser's render engine to figure out what should go there you got a blurry image. try
img {
transform: scale(.9)
}
img:hover {
transform: scale(1)
}
Aaron Sibler answered the question for me.
I just experienced this riddle. In your example, you’ll
need to transform img DOWN something like “transform: scale(0.7)” and
then scale UP to the images native dimensions on hover like
“transform: scale(1.0)”
The scale value is relative to the original image’s dimensions – not
their current dimensions on screen so a scale of 1 always equals the
original image’s dimensions.
I’ve used this here;
http://meetaaronsilber.com/experiments/css3imgpop/index.html

I had this problem with SVG scaling and blurry images. I scaled up a background image to 4.5 and the image rendered very blurry while scaling up.
I read that you can scale down first transform: scale(0.7) and then scale up to transform: scale(1.0). In my case this meant a huge rebuild of my animation. I had a very complex animation with multiple scales and transforms etc.
I just left all as is and added a pseudo scale width. The browser then seems to re-render every frame, but since the width does not actually change you still can use
transform: scale(x.x) for scaling and you get a very sharp image.
Maybe someone can confirm this. Here is my code. In my case the image was 86px wide and it zoomed up to 4.5 times the initial value.
<div class="overall-scale">
<div class="image-scale"></div>
</div>
#keyframes overall-scale {
0% {
transform: scale(1);
}
100% {
transform: scale(4.5);
}
}
#keyframes image-scale {
0% {
width: 86px;
}
100% {
width: 86px;
}
}
Hope this helps and my explanation makes sense.
Please comment if this does not work for you.

I' ve read all the comments, and tryied all solutions people suggested. But nothing was really good except rotate(360deg). Everything, except this one made stuttering on images, or they became too blurry initially. But rotating is looking strange if you don't hide it. So I decided to rotate for 0.0000001deg and it worked! Image is blurry only during the transition, but at the end and at the start of it it is sharp. May be I just had too small pictures.
So, my current solution is adding this part to CSS (and nothing else):
img {
transform: rotate(0.00000000001deg);
}

Related

Please explain to me how this CSS property removes the trailing lines from a transition

This is a bit of a long-winded question, but I hope someone can break this down for me. I have 2 questions:
Why a CSS property doesn't do what it should.
Why this particular CSS property works on an unsuspecting element, and why it doesn't work on the CSS :hover selector.
Created a flipcard animation. Got some graphics/trailing lines issues with transitions (in Chrome).
Doing some Googling, I found out that apparently, using -webkit-transform: translate3d(0,0,0); is supposed to fix the issue by using hardware acceleration.
However, I couldn't figure out where to place this CSS property. I tried placing it on the .flipcard-container, .flipcard, on the actual transition (.flipcard-container: hover .flipcard).
None of these removed the trailing lines caused by the animation.
Question 1: Where can I use the -webkit-transform: translate3d(0,0,0); properly in order to take advantage of the hardware acceleration, and why does/doesn't it work there?
But, after doing even more Googling and copying someone else's code, I found adding perspective: 600pxto the .flipcard-container somehow fixed the issue. And on top of that, it even makes my animation look really nice.
It shouldn't bother me so much, but it does that I cannot figure out why this worked.
According to the MDN docs:
The perspective CSS property determines the distance between the z=0
plane and the user in order to give a 3D-positioned element some
perspective.
Question 2: Why does this work in my transition so well? Shouldn't I have to place perspective in .flipcard-container: hover .flipcard instead of the .flip-container?
Of course, when placing it in the css :hover selector, the entire transition stops working. Does the perspective property also use hardware acceleration?
Here is the code, and thank you in advance.
.flipcard-container {
height: 400px;
width: 300px;
/* uncommenting the below property will fix the issue */
/* -webkit-perspective: 600; */
}
.flipcard-container:hover .flipcard {
transform: rotateY(180deg) scale(1.5);
}
.flipcard, .front, .back {
width: 100%;
height: 100%;
}
.flipcard {
transform-style: preserve-3d;
transition: all .8s ease-in-out;
}
.front {
background: #6093e5;
position: relative;
backface-visibility: hidden;
}
.back {
background: #e56060;
position: absolute;
backface-visibility: hidden;
top: 0;
transform: rotateY(180deg);
}
<div class="flipcard-container">
<div class="flipcard">
<div class="front"></div>
<div class="back"></div>
</div>
</div>
Question 1
You are overriding the transform: tags with the hardware acceleration. This causes that the animation doesn't work if you put it in.
You can use this, to archive better (more stable fps)
.flipcard-container:hover .flipcard {
transform: rotateY(180deg) scale(1.5);
will-change: -webkit-transition;
will-change: transition;
}
it uses the new will-change property.
More details
The will-change CSS property provides a way for authors to hint
browsers about the kind of changes to be expected on an element, so
that the browser can setup appropriate optimizations ahead of time
before the element is actually changed. These kind of optimizations
can increase the responsiveness of a page by doing potentially
expensive work ahead of time before they are actually required.
Question 2
If you look at e.g. this:
https://codepen.io/jfcorugedo/pen/bBPWaO?q=3d+turn&limit=all&type=type-pens
you see that it also uses the perspective tag. It is used that you can see the rotation of the box (like in your case).
If you remove it, it looks like your code. It works only on the container because the object you want to flip is wrapped in it.
If you have more questions just ask :)

Weird background glitch when using animation on the page in Chrome

If i have an animated element followed by another non-animated element, banding effect and various color shifting bugs appear in Chrome. Hard to see, but i recorded a video(if you zoom in on the page, the color shifts, easier to see): https://d26dzxoao6i3hh.cloudfront.net/items/1w1k2e3v0g04142U2A3H/Screen%20Recording%202017-10-30%20at%2011.35%20PM.mov
header {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #263238;
}
header a {
animation: scroll-down-anim 1s infinite;
}
#keyframes scroll-down-anim {
0% {
transform: translateY(0);
}
100% {
transform: translateY(10px);
}
}
<header>
Animated element
</header>
<p>if i remove this, the glitch disappears</p>
Any ideas how to fix this? If i remove the <p> element, it works. Also works on any other browser, like Safari.
Well this actually works for me, so I strongly suspect that it's just your graphics card or version of Chrome that's having issues.
However I would suggest that the reason it's happening is that the translate style forces Chrome to render using the GPU and having the P tag there is giving it a hard time.
If you were to force the P tag to use the same translation too then that might fix the issue for you, like this:
p {
transform: translateY(0);
}
it has nothing to do with chrome or your codes
Its your gpu ! specially if you have a m series Gpu (laptop to be exact)
so what happens is when you're using a ratio or a resolution higher or lower than your monitors native settings you put too much pressure on the gpu !
Update your graphics software by the os itself or bring the resolution back to its factory resolution

transform: scale() firefox text issue

I want to use css-transforms to scale a text on hover to another size. It works very well in all browsers (even IE!), but firefox has a strange problem with the font. The animation + scale works but the text in the scaled element becomes a bit unsharp and then after a few milliseconds it becomes sharp again.
I made a simple example where you can reproduce it.
HTML:
<div class="container">
<div class="scale">
Now that we know who you are, I know who I am. I'm not a mistake! It all makes sense! In a comic, you know how you can tell who the arch-villain's going to be? He's the exact opposite of the hero. And most times they're friends, like you and me! I should've known way back when... You know why, David? Because of the kids. They called me Mr Glass.
</div>
</div>
CSS:
.container {
height: 300px;
width: 300px;
margin-left: 100px;
margin-top: 100px;
}
div.scale {
transition: 0.1s linear;
}
div.scale:hover {
transform: scale(1.5);
}
Any help would be cool!
Thanks in advance
I tried scaling it to 2 and it works. It seems there is a issue when scaling with numbers which have fractional digits. I'm going to report this bug to the mozilla team.
It appears that by adding translateZ(0) the blurry effect disappears.
div.scale:hover {
transform: scale(1.5) translateZ(0);
}
This way it forces a 2D transform.

Positions fixed doesn't work when using -webkit-transform

I am using -webkit-transform (and -moz-transform / -o-transform) to rotate a div. Also have position fixed added so the div scrols down with the user.
In Firefox it works fine, but in webkit based browsers it's broken. After using the -webkit-transform, the position fixed doesn't work anymore! How is that possible?
The CSS Transforms spec explains this behavior. Elements with transforms act as a containing block for fixed position descendants, so position:fixed under something with a transform no longer has fixed behavior.
They do work when applied to the same element; the element will be positioned as fixed, and then transformed.
After some research, there has been a bug report on the Chromium website about this issue, so far Webkit browsers can't render these two effects together at the same time.
I would suggest adding some Webkit only CSS into your stylesheet and making the transformed div an image and using it as the background.
#media screen and (-webkit-min-device-pixel-ratio:0) {
/* Webkit-specific CSS here (Chrome and Safari) */
#transformed_div {
/* styles here, background image etc */
}
}
So for now you'll have to do it the old fashioned way, until Webkit browsers catch up to FF.
EDIT: As of 10/24/2012 the bug has not been resolved.
This appears to not be a bug, but an aspect of the specification due to the two effects requiring separate coordinate systems and stacking orders. As explained in this answer.
Something (a bit hacky) that worked for me is to position:sticky instead:
.fixed {
position: sticky;
}
For anyone who finds their background images are disappearing in Chrome because of the same issue with background-attachment: fixed; - this was my solution:
// run js if Chrome is being used
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
// set background-attachment back to the default of 'scroll'
$('.imagebg').css('background-attachment', 'scroll');
// move the background-position according to the div's y position
$(window).scroll(function(){
scrollTop = $(window).scrollTop();
photoTop = $('.imagebg').offset().top;
distance = (photoTop - scrollTop);
$('.imagebg').css('background-position', 'center ' + (distance*-1) + 'px');
});
}
August 2016 and fixed position & animation / transform is still a problem. The only solution that worked for me – was to create an animation for the child element that takes longer time.
Actually I found another way to fix this "bug":
I have container element which hold page with css3 animations. When the page completed the animation, the css3 property has value: transform: translate(0,0);. So, I just removed this line, and everything worked as it should - position: fixed is displayed properly. When css class is applied to translate the page, translate property is added and css3 animation worked as well.
Example:
.page {
top: 50px;
position: absolute;
transition: ease 0.6s all;
/* -webkit-transform: translate(0, 0); */
/* transform: translate(0,0); */
}
.page.hide {
-webkit-transform: translate(100%, 0);
transform: translate(-100%, 0);
}
Demo:
http://jsfiddle.net/ZWcD9/
I had this issue whilst trying to implement react-color with react-swipeable-views (rsw). The problem for me was that rsw applies translate(-100%, 0) to a tab panel which breaks the default fixed position div added over the full screen which when clicked closes the color picker model.
For me the solution was to apply the opposite transform to the fixed element (in this case translate(100%, 0) which fixed my issue. I'm not sure if this is useful in other cases but thought I would share anyway.
Here is an example showing what I've described above:
https://codepen.io/relativemc/pen/VwweEez
on my phonegap project the webkit transform -webkit-transform: translateZ(0); worked like a charm.
It was already working in chrome and safari just not the mobile browser.
also there can be one more issue is WRAPPER DIVs are not completed in some cases. we apply clear class in case of floating DIVs.
<div class="Clear"></div> .Clear, .Clearfix{clear:both;}
Probably due to a bug in Chrome as I can't replicate in Safari nor Firefox, but this works in Chrome 40.0.2214.111 http://jsbin.com/hacame/1/edit?html,css,output
It's a very particular structure so it's by no means a universally applicable one-lined css fix, but perhaps someone can tinker with it to get it working in Safari and Firefox.
I just added transform: unset; to my fixed header and that worked for me!
I am also using framer motion with Next.js and having the same problem with my fixed header and this seems to fix it easily.
.header {
position: fixed;
transform: unset;
}
Setting fixed element to transform:unset; is working for me.
Adding the -webkit-transform to the fixed element solved the issue for me.
.fixed_element {
-webkit-transform: translateZ(0);
position: fixed;
....
}
Here is what works for me on all tested browsers and mobile devices (Chrome, IE, Firefox, Safari, iPad, iphone 5 and 6, Android).
img.ui-li-thumb {
position: absolute;
left: 1px;
top: 50%;
-ms-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}
the fixed position of an element is broken if you apply transform to any ancestor.
<div style='position:fixed;-.*-transform:scale(2)'>...</div> //ok
<div style='-.*-transform:scale(2)'>
<div style='position:fixed'>...</div> // broken
</div>
If you can use javascript as an option this can be a workaround for positioning a position fixed element relavtive to the window when it's inside a transformed element:
let fixedEl // some node that you is position
// fixed inside of an element that has a transform
const rect = fixedEl.getBoundingClientRect()
const distanceFromWindowTop = rect.top
const distanceFromWindwoLeft = rect.left
let top = fixedEl.offsetTop
let left = fixedEl.offsetLeft
if(distanceFromWindowTop !== relativeTop) {
top = -distanceFromWindowTop
fixedEl.style.top = `${top}px`
}
if(distanceFromWindowLeft !== relativeLeft) {
left = -distanceFromWindowLeft
fixedEl.style.left = `${left}px`
}
Granted you will also have to adjust your heights and width because fixedEl will be calculating it's with based on it's container. That depends on your use case but this will allow you to predictably set the something position fixed, regardless of it's container.
Add a dynamic class while the element transforms.$('#elementId').addClass('transformed').
Then go on to declare in css,
.translatX(#x) {
-webkit-transform: translateX(#X);
transform: translateX(#x);
//All other subsidaries as -moz-transform, -o-transform and -ms-transform
}
then
#elementId {
-webkit-transform: none;
transform: none;
}
then
.transformed {
#elementId {
.translateX(#neededValue);
}
}
Now position: fixed when provided with a top and z-index property values on a child element just work fine and stay fixed until the parent element transforms. When the transformation is reverted the child element pops as fixed again. This should easen the situation if you are actually using a navigation sidebar that toggles open and closes upon a click, and you have a tab-set which should stay sticky as you scroll down the page.
in my case I found out we can't use transform: translateX() before transform:translateY().if we want to use both we should use transform:translate( , ).
If you're animating back to the original position where all translates are 0, you can use this solution where you set transform: unset;:
100% {
opacity: 1;
visibility: visible;
/* Use unset to allow fixed elements instead of translate3d(0, 0, 0) */
transform: unset;
}
If you work with React, you can wrap the element with fixed position in a Portal, and this way it will work fine
Please don't up vote, because this is not exact answer, but could help someone because it's fast way just to turn off the transformation.
If you really don't need the transformation on the parent and you want your fixed position working again:
#element_with_transform {
-webkit-transform: none;
transform: none;
}

can i tilt an image easily using HTML or CSS?

some designs on the Apple's user's webpage show a photo that is tilted slightly, like at a 5 or 10 degree angle. while this is no big deal, it does make the webpage totally different from "all the rest".
is it true that currently using HTML or CSS, this can't be done yet?
like the big photo in the middle:
alt text http://img7.imageshack.us/img7/383/phototilt.png
(the program lets you choose photos and then create the page (html and jpg) dynamically for you)
CCS 3 will offer this possibility, but it's still not cross-browser and you cannot do it with traditional HTML + CSS... yet.
Websites having a tilted image do it by rotating it in, say, Photoshop and making its background transparent. That's the whole trick there's to it.
Tip: save that picture to your HD and see by yourself. That's probably just an squared image with transparent background, or maybe it has the current background cut nicely to fit there.
You can do it, but only in Firefox 3.5+ and Safari 3.2+ (and recent webkit based browsers). Both provide browser specific CSS extensions for skew: -moz-transform and -webkit-transform respectively.
Here's a nice example that builds a 3d looking cube out of divs: (from http://www.fofronline.com/2009-04/3d-cube-using-css-transformations/)
<div class="cube">
<div class="topFace">
<div>
Content
</div>
</div>
<div class="leftFace">
Content
</div>
<div class="rightFace">
Content
</div>
</div>
And CSS:
.cube {
position: relative;
top: 200px;
}
.rightFace,
.leftFace,
.topFace div {
padding: 10px;
width: 180px;
height: 180px;
}
.rightFace,
.leftFace,
.topFace {
position: absolute;
}
.leftFace {
-webkit-transform: skewY(30deg);
-moz-transform: skewY(30deg);
background-color: #ccc;
}
.rightFace {
-webkit-transform: skewY(-30deg);
-moz-transform: skewY(-30deg);
background-color: #ddd;
left: 200px;
}
Yes, with CSS3 you can:
-webkit-transform: rotate(20deg);
-moz-transform: rotate(20deg);
-ms-transform: rotate(20deg);
-o-transform: rotate(20deg);
transform: rotate(20deg);
Supported by all the modern browsers and IE9+.
See CSS transform on MDN for more information.
To my knowledge you can not do that. Are you sure the image you are thinking of isn't tilted in Photoshop or similar and just added to the page like that?
You can use Apple specific CSS attributes (soon to be ratified, and then they'll remove the webkit prefixes for them) to do this and animation effects, but it will only show up in Safari and Chrome right now. Still, they look quite pretty and CSS is simple to do.
Right now it's probably just done in Photoshop, and nicely anti-aliased there as well, so that it has a consistent cross-browser appearance.
We are doing something similar at work, we have to do it on the fly.
You can't do it with just html/css, however we are using an image library through a php script to generate them automatically, and then make the background transparent.
Use a PHP GD Library. Makes things so much easier.
No. You can't.
Tilting images and text is still JavaScript juju.
Edit: Or, at least, you couldn't with CSS2. Starting with CSS3, there's the transform property, which includes rotations.