Working on a website today I found myself in the position (haha...) that a logo that I wanted to fix to the viewport didn't stick anymore. In my research to resolve this problem I learned that position: fixed won't fix to viewport if the ancestor element has a transform on it (see positions-fixed-doesnt-work-when-using-webkit-transform).
I made sure not to have any transforms on my element (or it's ancestors), I even tried to remove all child elements (which happen to have transforms and animations on them) – but I still didn't manage to get things going.
I am sort of clueless right now, so I made a jsfiddle for others to look at. The element that needs fixing is the bright red .titles element: http://jsfiddle.net/ZWcD9/90/
remove transfrom from body
body {
width: 100%;
/* -webkit-transform: translateZ(0); */
/* transform: translateZ(0); */
}
Related
Sometimes my sidebar with position: fixed scrolls with page. It happens only in Chrome. I think something wrong happening with viewport (I also have lazy loading implemented, maybe it impacts on viewport). I decided to apply transform: translateZ(0) to the sidebar element. Issue seems to be gone but I can not understand how transform impacts on elements with fixed position?
I have read a lot of information about how it works before asking this question but I can't understand how it solves the problem, maybe there's a need to fix elements which cause viewport overflow? Thanks a lot and sorry for my English.
position: fixed will always position the element relative to the initial window viewport, except when one of the element's ancestors has a transform property, in which case that ancestor behaves like the new viewport:
.container {
transform: translateZ(0); // the "new" viewport
.child {
position: fixed;
top: 1rem; // 1rem relatively to .container
}
}
So when you gave the container a transform property, it acted as the relative container to the fixed child and sorted your issue.
Check out Mozilla's CSS/position docs - they explain the subject well.
I am using the css properties perspective and transform to create a 3D world in html. In Google Chrome everything works without problems, but in Microsoft Edge there is something buggy in it... I narrowed it down using this jsfiddle: https://jsfiddle.net/uke8bsvk/12/
The third variant in the fiddle is where it goes wrong. It is working fine in Google Chrome, but in Microsoft Edge somehow the red div does not respond well to hovering it with the mouse by changing its color to green. It only responds to hovering it with the mouse close to the bottom of the red div.
In the fourth variant I removed transform-style: preserve-3d for the red div and everything works fine again.
Does anyone have an idea what's going on here and how to solve it?
PS. In my real case, I sometimes have a child div for which preserving 3d is necessary and sometimes I do not have a child div. It is not really an option to use the obvious dirty work around of setting and removing transform-style: preserve-3d dependent on the presence of a child div.
I found a relatively clean trick/work around to 'solve' the problem: just add an extra child div, make it invisible and rotate it out of plane with transform: rotateX( 1deg ). See jsfiddle: https://jsfiddle.net/uke8bsvk/13/
You need to prefix the 3d properties in your css, using Autoprefixer. You can do it on the site itself or add it as an extension to your code editor of choice.
It will add some of these prefixes to your code as so:
-webkit-transform-origin: bottom left;
transform-origin: bottom left;
-webkit-transform: rotateX( 30deg );
transform: rotateX( 30deg );
background: red;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
Here is an updated Fiddle.
You should prefix each and every one of your projects for the web.
okey, simple css flip
.container
.flipper.A
.front
.back
.flipper.B
.front
.back
it's important for me, that .front and .back both have negative top and left absolute position
and .flipper dimensions is 0x0
when flipper A is rotatedY 180deg, so .back is visible, it incorrectly interacts with other .flippers if their positions intersect. For example, i click on links in flipper B, but can't click on links in flipper A, if A is over B
working example is here http://jsfiddle.net/attenzione/g2at2/ - you almost can click on test 1, instead click on test 3
such situation only appear on webkit browser
any help with it? is this webkit bug?
Just bring the div that you want to be in front towards the front (in 3d space)
CSS
div.flipped {
-webkit-transform: rotateY(180deg) translateZ(-1px);
z-index: 2;
}
the translateZ moves it towards you
corrected fiddle
Is there a reason why your inner .block has absolute positioning? This is what is causing the issue. If you must use absolute positioning on the inner block then there are two ways round this.
You could overflow hidden the outer element (.flipper)
Or you could add pointer-events:none on the unflipped element, bear in mind this only works back to IE9
You should really try not to use absolute positioning though as it isn't needed.
There seems to be an issue with my page here:
http://www.lonewulf.eu
When hovering over the thumbnails the image moves a bit on the right, and it only happens on Chrome.
My css:
.img{
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter:alpha(opacity=50);
-moz-opacity: 0.5;
opacity: 0.5;
-khtml-opacity: 0.5;
display:block;
border:1px solid #121212;
}
.img:hover{
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter:alpha(opacity=100);
-moz-opacity: 1;
opacity: 1;
-khtml-opacity: 1;
display:block;
}
Another solution would be to use
-webkit-backface-visibility: hidden;
on the hover element that has the opacity.
Backface-visibility relates to transform, so #Beskow's has got something to do with it. Since it is a webkit specific problem you only need to specify the backface-visibility for webkit. There are other vendor prefixes.
See http://css-tricks.com/almanac/properties/b/backface-visibility/ for more info.
For some reason Chrome interprets the position of elements without an opacity of 1 in a different way. If you apply the CSS attribute position:relative to your a.img elements there will be no more left/right movement as their opacity varies.
I had the same problem, I fixed it with css transform rotate.
Like this:
-webkit-transform: rotate(0);
-moz-transform: rotate(0);
transform: rotate(0);
It works fine in major browsers.
Another solution that fixed this issue for me was to add the rule:
will-change: opacity;
In my particular case this avoided a similar pixel-jumping issue that translateZ(0) introduced in Internet Explorer, despite fixing things in Chrome.
Most of the other solutions suggested here that involve transforms (eg. translateZ(0), rotate(0), translate3d(0px,0px,0px), etc) work by handing painting of the element over to the GPU, allowing more efficient rendering. will-change provides a hint to the browser that has presumably a similar effect (allowing the browser to render the transition more efficiently), but feels less hacky (since it's explicitly addressing the problem rather than just nudging the browser to use the GPU).
Having said that, it's worth bearing in mind that browser support is not as good for will-change (though if the issue is with Chrome only then this might be a good thing!), and in some situations it can introduce problems of its own, but still, it's another possible solution to this issue.
I was need apply both backface-visibility and transform rules to prevent this glitch.
Like this:
a {-webkit-transform: rotate(0);}
a img {-webkit-backface-visibility: hidden;}
I had a similar issue with (non-opacity) filters on hover. Fixed by adding a rule to the base class with:
filter: brightness(1.01);
backface-visibility (or -webkit-backface-visibility) only fixed the issue in Chrome for me. To fix in both Firefox and Chrome I used the following combination of above answers.
//fixes image jiggle issue, please do not remove
img {
-webkit-backface-visibility: hidden; //Webkit fix
transform: translate3d(0px,0px,0px); //Firefox fix
}
I encountered a similar issue in Safari 8.0.2, where images would jitter as their opacity transitioned. None of the fixes posted here worked, however the following did:
-webkit-transform: translateZ(0);
All credit to this answer via this subsequent answer
I ran into this issue with images in a grid each image was nested in an that had display: inline-block declared. The solution that Jamland posted above worked to correct the issue when the display: inline-block; was declare on the parent element.
I had another grid where the images were in an unordered list and I was able to just declared display: block; and a width on the parent list item and declared backface-visibility: hidden; on the image element and there doesn't seem to be any position shift on hover.
li { width: 33.33333333%; display: block; }
li img { backface-visibility: hidden; }
The solution alpipego was served me in this problem.
Use -webkit-backface-visibility: hidden;
With this the image no move in hover opacity transition
/* fix error hover image opacity*/
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
I had trouble with all the other solutions here, as they require changes to the CSS that may break other things -- position:relative requires me to completely rethink how I'm positioning my elements, transform:rotate(0) can interfere with existing transforms and gives wonky little transition effects when I have a transition-duration set, and backface-visibility won't work if I ever actually need a backface (and requires a whole lot of prefixing.)
The laziest solution I found is to just set an opacity on my element which is very close to, but not quite, 1. This is only a problem if opacity's 1, so it's not going to break or interfere with any of my other styles:
opacity:0.99999999;
Having marked Rick Giner's answer as correct I then found out it did not fix the issue.
In my case I have responsive width images contained within a max-width div. Once the site width crosses that max width the images move on hover (using css transform).
The fix in my case was to simply amend the max width to a multiple of three, three columns in this case, and it fixed it perfectly.
I noticed you had opacity included in your CSS. I had the same exact issue with Chrome (the image moving on hover) .. all I did was disable the opacity and it was solved, no more images moving.
.yourclass:hover {
/* opacity: 0.6; */
}
Had the same issue, My fix was putting the class before the src in the img tab.
I've been building a prism rotation effect using 3D transforms. The transform-origin-z property seemed best for transforming the faces of the prism, but Safari 5 and Mobile Safari inexplicably stretch my element, even when no transform is applied. Firefox 12 and Chrome 18 work correctly.
Live Demo
Full Prism Demo
I'm interested in understanding why this happens. Should I avoid transform-origin-z entirely, or is there some workaround for Safari and Mobile Safari?
<style>
/* other browser prefixes omitted for brevity */
.container {
margin: 50px;
border: 2px solid #00f;
height: 50px;
-webkit-perspective: 500px;
}
.face {
height: 50px;
background-color: rgba(255,0,0,0.5);
-webkit-transform-origin: center center -25px;
-webkit-transform: translate3d(0,0,0);
}
</style>
<div class="container">
<div class="face"></div>
</div>
it seems like this is a bug in Safari.
Chrome moves the transformation-center over the Z-axis, Safari leaves this center were it was, but moves the object itself over the Z-axis.
The object therefore is zoomed in Safari, and seems bigger.
I would avoid the transform-origin (on Z-axis) for now and work with translate-Z to produce the same effect.
Example:
http://jsfiddle.net/willemvb/GuhcC/3/
I believe the following explanation answers the "why" Safari is doing what it is
I do not have access to Safari for testing, but as I read the specifications for the perspective property (the same spec page you point to), it states:
The ‘perspective’ property applies the same transform as the
perspective() transform function, except that it applies only
to the positioned or transformed children of the element, not to the
transform on the element itself.
Update on how I read the above spec
The ‘perspective’ property applies the same transform as the perspective() transform function
This tells me a perspective transform is going to be done just as if transform: perspective(500px) were applied in this case.
except that it applies only to the positioned or transformed children of the element
This tells me the perspective transform is going to be applied to child elements, in this case .face. Here, there seems to be some ambiguity. Is this saying the perspective should only be applied if another transform is done on the child element? And, does the tranform-origin property count as a transform being done to the child (especially since it is this value that relates directly to the perspective transform)? It is at this point of ambiguity that the browsers seem to differ. Safari is doing the perspective transform because the child element has tranform-origin set to -25px, whereas the others apparently are not (at least, not until the actual other transform does something else to the .face during the animation).
not to the transform on the element itself
This tells me the z=0 of .container is irrelevant, because the transform from this property is not affecting .container, but rather .container's children (i.e. .face).
So Safari appears to be taking the position that your .face always has a transform applied because you have set .container to have -webkit-perspective: 500px;, so there is always a perspective transform being applied to the child elements (.face in your case).
Note that if you take away the animation, and apply an actual transform: perspective(500px) to the .face you will see the same result in Firefox or Chrome as what you experience in Safari with your code.
So I think actually, Safari may be doing it correctly, and Firefox and Chrome perhaps are not. The spec has some ambiguity. The other two browsers perhaps should be still applying the perspective transform based off .container like Safari does, but certainly appear to not be, whereas Safari obviously appears to be.
To eliminate the issue (not have it "stick out" when "at rest"), you probably need to
Animate the transform-origin itself at the beginning of your animation (and reset to 0 afterwards), OR...
Animate the perspective value itself to be 0 when "at rest" and 500px when animating.
My guess is #1 will be easier to implement, but I don't know for sure.
I don't know why this worked for me. Seem to work on all browsers. Basically I think I am canceling the css declarations effect.
.container {
perspective: 500px;
transform-origin: 50% 50% 25px;
}