Blurry text after using CSS transform: scale(); in Chrome - google-chrome

Seems like there has been a recent update to Google Chrome that causes blurry text after doing a transform: scale(). Specifically I'm doing this:
#-webkit-keyframes bounceIn {
0% {
opacity: 0;
-webkit-transform: scale(.3);
}
50% {
opacity: 1;
-webkit-transform: scale(1.05);
}
70% {
-webkit-transform: scale(.9);
}
100% {
-webkit-transform: scale(1);
}
}
If you visit http://rourkery.com in Chrome, you should see the problem on the main text area. It didn't used to do this and it doesn't seem to effect other webkit browsers (like Safari). There were some other posts about people experiencing a similar issue with 3d transforms, but can't find anything about 2d transforms like this.
Any ideas would be appreciated, thanks!

I have had this problem a number of times and there seems to be 2 ways of fixing it (shown below). You can use either of these properties to fix the rendering, or both at the same time.
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;
TranslateZ also works as it is a hack to add hardware acceleration to the animation.
transform: translateZ(0);
Both of these properties fix the problem that you are having but some people also like to add
-webkit-font-smoothing: subpixel-antialiased;
to their animated object. I find that it can change the rendering of a web font but feel free to experiment with that method too.

After trying everything else here with no luck, what finally fixed this issue for me was removing the will-change: transform; property. For some reason it caused horribly blurry looking scaling in Chrome, but not Firefox.

To improve the blurriness, esp. on Chrome, try doing this:
transform: perspective(1px) translateZ(0);
backface-visibility: hidden;
UPDATE: Perspective adds distance between the user and the z-plane, which technically scales the object, making the blurriness seem 'permanent'. The perspective(1px) above is like duck-tape because we're matching the blurriness we're trying to solve. You might have better luck with the css below:
transform: translateZ(0);
backface-visibility: hidden;

I found that adjusting the scale ratio helped slightly.
Using scale(1.048) over (1.05) seemed to generate a better approximation to a whole-pixel font size, reducing the sub-pixel blurring.
I also used translateZ(0) which seems to adjust Chrome's final rounding step in the transform animation. This is a plus for my onhover usage because it increases speed and reduces visual noise. For an onclick function however, I wouldn't use it because, the transformed font doesn't appear to be as crispy.

Instead of
transform: scale(1.5);
using
zoom : 150%;
fixes the text blurring problem in Chrome.

This must be a bug with Chrome (Version 56.0.2924.87), but the below fixes the bluriness for me when changing css properties in the console('.0'). I'll report it.
filter: blur(.0px)

Sunderls lead me to the answer. Except filter: scale does not exist, but filter: blur does.
Apply the next declarations to the elements that appear blurred (in my case they were inside a transformed element):
backface-visibility: hidden;
-webkit-filter: blur(0);
It almost worked perfectly. "Almost" because i'm using a transition and while in transition, elements don't look perfect, but once the transition is done, they do.

I found out, that the problem occures on relative transforms in any way. translateX(50%), scale(1.1) or what ever. providing absolute values always works (does not produce blurry text(ures)).
None of the solutions mentions here worked, and I think there is not solution, yet (using Chrome 62.0.3202.94 while I am writing this).
In my case transform: translateY(-50%) translateX(-50%) causes the blur (I want to center a dialog).
To reach a bit more "absolute" values, I had to set decimal values to transform: translateY(-50.09%) translateX(-50.09%).
NOTE
I am quite sure, that this values vary on different screen sizes. I just wanted to share my experiences, in case it helps someone.

In my case following code caused blurry font:
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
and just adding zoom property fixed it for me. Play around with zoom, following worked for me:
zoom: 97%;

I have found a much better and clean solution:
.element{
transform:scale(0.5)
transform-origin: 100% 0;
}
or
.element{
transform:scale(0.5)
transform-origin: 0% 0;
}
Thanks to this post:
Preventing blurry rendering with transform: scale

I have this same problem. I fixed this using:
.element {
display: table
}

Another fix to try i just found for blurry transforms (translate3d, scaleX) on Chrome is to set the element as
"display: inline-table;".
It seems to force pixel rounding in some case (on the X axis).
I read subpixel positioning under Chrome was intended and devs won't fix it.

Try using zoom: 101%; for complex designs when you can't use a combination of zoom + scale.

2019 UpdateThe Chrome display bug is still unfixed and though no fault of the patrons, none of the suggestions offered in the entirety of this website help to resolve the issue. I can concur that I have tried every single one of them in vain: only 1 comes close and that's the css rule: filter:blur(0); which eliminates the shifting of a container by 1px but does not resolve the blurred display bug of the container itself and any content it may have.
Here's the reality: there literally is no fix to this problem so here is a work around for fluid websites
CASE
I'm currently developing a fluid website and have 3 divs, all centered with hover effects and sharing percentage values in both the width and position. The Chrome bug occurs on the center container which is set to left:50%; and transform:translateX(-50%); a common setting.
EXAMPLE: First the HTML...
<div id="box1" class="box">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry"s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
</div>
<div id="box2" class="box">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry"s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
</div>
<div id="box3" class="box">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry"s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
</div>
Here's the CSS where the Chrome bug occurs...
*{margin:0; padding:0; border:0; outline:0; box-sizing:border-box; background:#505050;}
.box {position:absolute; border:1px solid #fff; border-radius:10px; width:26%; background:#8e1515; padding:25px; top:20px; font-size:12pt; color:#fff; overflow:hidden; text-align:center; transition:0.5s ease-in-out;}
.box:hover {background:#191616;}
.box:active {background:#191616;}
.box:focus {background:#191616;}
#box1 {left:5%;}
#box2 {left:50%; transform:translateX(-50%);} /* Bugged */
#box3 {right:5%;}
Here's the fixed css...
*{margin:0; padding:0; border:0; outline:0; box-sizing:border-box; background:#505050;}
.box {position:absolute; border:1px solid #fff; border-radius:10px; width:26%; background:#8e1515; padding:25px; top:20px; font-size:12pt; color:#fff; overflow:hidden; text-align:center; transition:0.5s ease-in-out;}
.box:hover {background:#191616;}
.box:active {background:#191616;}
.box:focus {background:#191616;}
#box1 {left:5%;}
#box2 {left:37%;} /* Fixed */
#box3 {right:5%;}
Bugged fiddle: https://jsfiddle.net/m9bgrunx/2/
Fixed fiddle: https://jsfiddle.net/uoc6e2dm/2/
As you can see a small amount of tweaking to the CSS should reduce or eliminate the requirement to use transform for positioning. This could also apply to fixed width websites as well as fluid.

It's important to add that this issue arises if the element which is being translated has a height with an odd number of pixels. So, if you have control over the height of the element, setting it to an even number will make the content appear crisp

None of above worked for me.
I had this animation for popups:
#keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.05, 1.05, 1.05);
}
to {
transform: scale3d(1, 1, 1);
}
}
In my case blurry effect was gone after applying this rule:
-webkit-perspective: 1000; even though it is marked as unused in Chrome inspector.

None of the above worked for me.
It worked when I added perspective
ie from
transform : translate3d(-10px,-20px,0) scale3d(0.7,0.7, 1)
i changed to
transform : perspective(1px) translate3d(-10px,-20px,0) scale3d(0.7,0.7, 1)

I used a combination of all answers and this is what worked for me in the end:
.modal .modal--transition {
display: inline-table;
transform: perspective(1px) scale(1) translateZ(0);
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
}

My solution was:
display: initial;
Then it was crispy sharp

I was facing the blurry text issue on Chrome but not on Firefox when I used transform: translate(-50%,-50%).
Well, I really tried a lot of workarounds like:
transform: perspective(1px);
filter: blur(0);
transform: translateZ(0);
backface-visibility: hidden;
None of these worked to me.
Finally, I made the height and width of the element even. It resolved the issue for me!!!
Note: It might depend from use case to use case. But surely worth a try!

I have tried a lot of examples from these answers unfortunately nothing help for
Chrome Version 81.0.4044.138
I have added to transforming element instead
transform-origin: 50% 50%;
this one
transform-origin: 51% 51%;
it helps for me

This is what worked for me:
body { perspective: 1px; }

I fixed my case by adding:
transform: perspective(-1px)

I removed this from my code - transform-style: preserve-3d;
and added this- transform: perspective(1px) translateZ(0);
the blur went away!

FOR CHORME:
I´ve tried all suggestions here. But diden't work.
My college found a great solution, that works better:
You should NOT scale past 1.0
And include translateZ(0) in the hover but NOT in the none-hover/initial position.
Example:
a {
transition: all 500ms cubic-bezier(0.165, 0.840, 0.440, 1.000);
transform: scale(0.8, 0.8);
}
a:hover {
transform: translateZ(0)scale(1.0, 1.0);
}

In Chrome 74.0.3729.169, current as of 5-25-19, there doesn't seem to be any fix for blurring occurring at certain browser zoom levels caused by the transform. Even a simple TransformY(50px) will blur the element. This doesn't occur in current versions of Firefox, Edge or Safari, and it doesn't seem to occur at all zoom levels.

I have a div that has a small perspective shift on it to give a subtle 3D effect. The text in the div was blurring and I tried all the suggestions here to no avail.
Oddly, I found that setting 'filter: inherit;' on the text elements vastly improved the clarity. Though I can't understand why.
Here's my code in case it helps:
Html:
<div id="NavContainer">
<div id="Nav">
<label>Title</label>
<nav>
home
link1
link2
</nav>
</div>
</div>
Css:
#NavContainer {
position: absolute;
z-index: 1;
top: 0;
left: 20px;
right: 20px;
perspective: 80vw;
perspective-origin: top center;
}
#Nav {
text-align: right;
transform: rotateX(-5deg);
}
#Nav > nav > a,
#Nav > label {
display: inline-block;
filter: inherit;
}
#Nav > label {
float: left;
font-weight: bold;
}

For me the problem was that my elements were using transformStyle: preserve-3d. I realized that this wasn't actually needed for the app and removing it fixed the blurriness.

It will be difficult to solve with only css.
So I solved it with jquery.
This is my CSS.
.trY {
top: 50%;
transform: translateY(-50%);
}
.trX {
left: 50%;
transform: translateX(-50%);
}
.trXY {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
and this is my jquery.
function tr_init() {
$(".trY, .trX, .trXY").each(function () {
if ($(this).outerWidth() % 2 != 0) {
var fixed_width = Math.ceil($(this).outerWidth() / 2) * 2;
$(this).css("width", fixed_width);
}
if ($(this).outerHeight() % 2 != 0) {
var fixed_height = Math.ceil($(this).outerHeight() / 2) * 2;
$(this).css("height", fixed_height);
}
})}

Just to add to the fix craze, putting {border:1px solid #???} around the badly looking object fixes the issue for me.
In case you have a stable background colour, consider this too.
This is so dumb noone thought about mentioning I guess, eh eh.

Related

Trying to zoom in on image over hover

I am creating a website for a project and got stuck with an issue.
I was trying to implement the hover feature, where when I hover over the image it gets zoomed in. That part works nicely, however, I was having an issue when I hover over the last book in the first row. When I hover over that, the entire screen becomes glitchy. This feature is not working as I hoped, i.e. smooth and good to work with. I have attached the image and the code I have.
Thanks for any help!
.books img{
width:200px;
height:300px;
}
.books img:hover {
position: relative;
left: 45px;
width: 300px;
height: 400px;
display: block;
}
I found some code online using -mox-transform and -webkit-transform, however, I have never worked with that before. This seemed complex for me. Any suggestions if I should learn how that works instead of perfecting the above code?
By increasing the width and height on hover the surrounding layout must adapt to that size change. The browser must move the surrounding elements to provide the space for the larger element, that is why it is glitchy.
If you want to do it properly, you will probably have to use transform, as you mentioned.
For your use case it should not be hard. Try this:
.books img {
width: 200px;
height: 300px;
transition: transform 200ms; /* optional transition with 200ms duration */
}
.books img:hover {
transform: scale(1.1); /* scale to 110% */
}
All you need to use is scale property to scale the image. Change your code to this
.books img:hover {
transform: scale(1.5);
}
This should do what you are looking for.
Use transform CSS Property with scale() which is used to increase or decrease the size of an element
.books img:hover {
transform: scale(1.2);
}

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 :)

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.

How to fix blurry Image on transform scale

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);
}

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;
}