Using CSS, how can I apply more than one transform?
Example: In the following, only the translation is applied, not the rotation.
li:nth-child(2) {
transform: rotate(15deg);
transform: translate(-20px,0px);
}
You have to put them on one line like this:
li:nth-child(2) {
transform: rotate(15deg) translate(-20px,0px);
}
When you have multiple transform directives, only the last one will be applied. It's like any other CSS rule.
Keep in mind multiple transform one line directives are applied from right to left.
This: transform: scale(1,1.5) rotate(90deg);
and: transform: rotate(90deg) scale(1,1.5);
will not produce the same result:
.orderOne, .orderTwo {
font-family: sans-serif;
font-size: 22px;
color: #000;
display: inline-block;
}
.orderOne {
transform: scale(1, 1.5) rotate(90deg);
}
.orderTwo {
transform: rotate(90deg) scale(1, 1.5);
}
<div class="orderOne">
A
</div>
<div class="orderTwo">
A
</div>
I'm adding this answer not because it's likely to be helpful but just because it's true.
In addition to using the existing answers explaining how to make more than one translation by chaining them, you can also construct the 4x4 matrix yourself
I grabbed the following image from some random site I found while googling which shows rotational matrices:
Rotation around x axis:
Rotation around y axis:
Rotation around z axis:
I couldn't find a good example of translation, so assuming I remember/understand it right, translation:
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[x y z 1]
See more at the Wikipedia article on transformation as well as the Pragamatic CSS3 tutorial which explains it rather well. Another guide I found which explains arbitrary rotation matrices is Egon Rath's notes on matrices
Matrix multiplication works between these 4x4 matrices of course, so to perform a rotation followed by a translation, you make the appropriate rotation matrix and multiply it by the translation matrix.
This can give you a bit more freedom to get it just right, and will also make it pretty much completely impossible for anyone to understand what it's doing, including you in five minutes.
But, you know, it works.
Edit: I just realized that I missed mentioning probably the most important and practical use of this, which is to incrementally create complex 3D transformations via JavaScript, where things will make a bit more sense.
You can also apply multiple transforms using an extra layer of markup e.g.:
<h3 class="rotated-heading">
<span class="scaled-up">Hey!</span>
</h3>
<style type="text/css">
.rotated-heading
{
transform: rotate(10deg);
}
.scaled-up
{
transform: scale(1.5);
}
</style>
This can be really useful when animating elements with transforms using Javascript.
You can apply more than one transform like this:
li:nth-of-type(2){
transform : translate(-20px, 0px) rotate(15deg);
}
Some time in the future, (now available, see updates below) we can write it like this:
li:nth-child(2) {
rotate: 15deg;
translate:-20px 0px;
}
This will become especially useful when applying individual classes on an element:
<div class="teaser important"></div>
.teaser{rotate:10deg;}
.important{scale:1.5 1.5;}
This syntax is defined in the in-progress CSS Transforms Level 2 specification, but can't find anything about current browser support other then chrome canary. Hope some day i'll come back and update browser support here ;)
Found the info in this article which you might want to check out regarding workarounds for current browsers.
UPDATE: feature has landed in firefox 72
UPDATE: now available in chrome 104, edge 104, safari 14.1, see https://web.dev/css-individual-transform-properties/#:~:text=support%20these%20properties.-,Browser%20support,-%3A
Lesson I`ve learnt.
If you are using style's React css, don't include semicolons, even in the end of it because it is included automatically and internally by React.
Just like:
style={
transform: "rotate(90deg) scaleX(-1)",
}
It's an old question but turned out to be very relevant to me recently. I found 'transform: matrix(..)' more convenient to use.
So for the issue in question, the below example applies ~15deg rotation and translation of 20px to the right (for convenience) on the x-axis.
.matrixTransform {
transform-origin: top left;
transform: matrix(0.965,0.258,-0.258,0.965,20,0);
font-size: 30px;
}
.combinedTransform {
transform-origin: top left;
transform: rotate(15deg) translateX(20px);
font-size: 30px;
}
<div class=matrixTransform>A</div>
<div class=combinedTransform>B</div>
From what I gather this particular transform uses initial 4 parameters to represent transformations e.g. scale, rotate. And seem to be in rows by columns order.
The remaining two are translations in the x and y axis respectively.
I found Wolfram Alpha cheat sheet (calculator) very useful.
Just start from there that in CSS, if you repeat 2 values or more, always last one gets applied, unless using !important tag, but at the same time avoid using !important as much as you can, so in your case that's the problem, so the second transform override the first one in this case...
So how you can do what you want then?...
Don't worry, transform accepts multiple values at the same time... So this code below will work:
li:nth-child(2) {
transform: rotate(15deg) translate(-20px, 0px); //multiple
}
If you like to play around with transform run the iframe from MDN below:
<iframe src="https://interactive-examples.mdn.mozilla.net/pages/css/transform.html" class="interactive " width="100%" frameborder="0" height="250"></iframe>
Look at the link below for more info:
<< CSS transform >>
Transform Rotate and Translate in single line css:-How?
div.className{
transform : rotate(270deg) translate(-50%, 0);
-webkit-transform: rotate(270deg) translate(-50%, -50%);
-moz-transform: rotate(270deg) translate(-50%, -50%);
-ms-transform: rotate(270deg) translate(-50%, -50%);
-o-transform: rotate(270deg) translate(-50%, -50%);
float:left;
position:absolute;
top:50%;
left:50%;
}
<html>
<head>
</head>
<body>
<div class="className">
<span style="font-size:50px">A</span>
</div>
</body>
</html>
Related
The two blocks behave differently when applying tailwind's "rotate(**deg)" and vanilla css "transform: rotate(**deg)". Please just hover the blue blocks to reproduce.
https://play.tailwindcss.com/Rgf2GJ6mim
Since I sometimes use css in #layer utilities to write nested styles, so could someone please help me understand this? Big Thanks!!
Despite it looks like both examples do the same thing it's not quite true. Let's find out the difference. All classes in your example are same but the last one
hover:[transform:rotate(1020deg)] generates this
.hover\:\[transform\:rotate\(1020deg\)\]:hover {
transform: rotate(1020deg);
}
while hover:rotate-[1020deg] this
.hover\:rotate-\[1020deg\]:hover {
--tw-rotate: 1020deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
Or if you fill in Tailwind variables with its values it all comes to comparison between
.hover\:\[transform\:rotate\(1020deg\)\]:hover {
transform: rotate(1020deg);
}
// and
.hover\:rotate-\[1020deg\]:hover {
transform: translate(0, 0) rotate(1020deg) skewX(0) skewY(0) scaleX(1) scaleY(1);
}
We're forgot about one VERY important class - rotate-0. It actually sets the starting point of CSS transition
.rotate-0 {
--tw-rotate: 0deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
Just remove rotate-0 from both of your examples and now there is no difference in transition. So what is happening?
It all comes in CSS transition from state 1 to state 2. (Let's remove last
parts with skew and scale)
First example - from translate(0, 0) rotate(0deg) to rotate(1020deg)
Second - from translate(0, 0) rotate(0deg) to
translate(0, 0) rotate(1020deg)
MDN says
The transform functions are multiplied in order from left to right, meaning that composite transforms are effectively applied in order from right to left.
See example: red square just rotating. Yellow - rotates but returns back to default position even on hover we do NOT changing translate property. We're assuming it will left the same but this is not how CSS transition works. When there are multiple transform occurrence the last one will override previous. That's why translate is not applied anymore on hover - we're "erasing" it. In order to fix it we need to keep translate on hover (blue example)
.example {
width: 60px;
height: 60px;
margin: 40px;
transition: 1000ms;
}
.example-1 {
background-color: red;
transform: rotate(0);
}
.example-2 {
background-color: yellowgreen;
transform: translate(100px) rotate(0deg);
}
.example-3 {
background-color: blue;
transform: translate(100px) rotate(0);
}
.example-1:hover {
transform: rotate(45deg);
}
.example-2:hover {
transform: rotate(45deg);
}
.example-3:hover {
background-color: blue;
transform: translate(100px) rotate(45deg);
}
<div class="example example-1"></div>
<div class="example example-2"></div>
<div class="example example-3"></div>
And that's exactly what happening in your example - you are missing translate function in compiled CSS and changing the default state of transformed object (it is not transitioning anymore - it just places the new state). We need to keep the order of the chaining functions in transform property to ensure everything will work as expected
So, few ways to fix it in Tailwind keeping initial state (rotate-0 class), both requires to change hover:[transform:rotate(1020deg)] class
First - add missing translate function - change class into hover:[transform:translate(0,0)_rotate(1020deg)]
Second - not so obvious - change --tw-rotate variable value, basically convert class into hover:[--tw-rotate:1020deg]
And finally as I said - just remove initial state (rotate-0) but sometimes it is not an option
See examples
It's not the best explanation but I tried to point you in some direction where the difference comes from
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.
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.
Why was decided to add all transform properties to one css property?
Instead of:
.element {
transform: translateX(50%) rotateZ(45deg) scale(0.8);
}
could be written:
.element {
translate-x: 50%;
rotate-z: 45deg;
scale: 0.8;
}
Why was chosen first variant? Is this somehow connected with transformation matrix? Or prefixes?
When you write media queries for example, you need to copy the entire transform property (not DRY), in other case, it will be overwritten. The same problem when creating transitions, toggling states, etc... That's really uncomfortable.
An explanation of what is happening behind the scene is welcome.
Because it's not just a set of properties, it's a list, where the transformations are applied in order, and a single transform type can occur more than once in the list.
So you can for example do:
div {
height:100px;
width: 100px;
}
.one {
background-color:red;
transform:translate(50%,5%) scale(0.5)
rotate(45deg) translate(50px,10px)
}
.two {
background-color:blue;
transform:scale(0.5) translate(50%,5%)
rotate(45deg) translate(50px,10px)
}
<div class="one"></div>
<div class="two"></div>
And you can see that the X-position of the diamond is affected by the order in which the transforms are applied.
I'm having a strange problem where rendering an emoji rotated to certain angles results in the emoji failing to appear.
This seems consistent across browsers, so I'm struggling to pinpoint the issue or a reasonable solution.
The code:
<style type="text/css">
.container {
background-color: #55d;
height: 500px;
padding: 50px;
width: 500px;
}
.text {
color: #fff;
font-size:2em;
margin: 100px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
}
</style>
<div class="container">
<div class="text">This is some text 😂</div>
</div>
See http://codepen.io/anon/pen/ORgQjb for a working example, note that changing the rotation, even to 44.5 degrees will bring the emoji back.
Does anyone have a suggestion as to why this occurs, or any workarounds?
Update
Thanks to Paulie_D and some digging, it seems this issue only manifests itself on OSX (all browsers), and not Windows (tried IE/Firefox/Chrome).
I sure don't know why it happens, but after some tinkering, I do have a couple of fixes to share.
Webkit
If a Webkit-only fix is sufficient (e.g., if you're building an Electron app), you only need to add the CSS transform perspective(0), which has no visible effect, other than causing emoji to actually render.
So:
transform: rotate(45deg) perspective(0);
instead of:
transform: rotate(45deg);
Here's a fork of your example demonstrating that fix:
https://codepen.io/troywarr/pen/yEgEdr
and a reduced test case including a reference emoji to illustrate that perspective(0) doesn't change the emoji's appearance:
https://codepen.io/troywarr/pen/aKpKmx
Cross-browser
If you need a cross-browser fix, you can use a CSS animation that rotates starting at 45 degrees (or whichever multiple of 45 degrees that you need to fix) but is eternally paused:
#keyframes spin {
0% {
transform: rotate(45deg);
}
}
.working-rotated-thing {
animation: spin 1ms; /* animation-duration must be > 0 */
animation-play-state: paused;
}
Here's a fork of your example demonstrating that fix (note that I enabled Autoprefixer to avoid messing with vendor prefixes):
https://codepen.io/troywarr/pen/mKRKZB
and a reduced test case:
https://codepen.io/troywarr/pen/oyByMx
This seems to work across browsers; I checked the latest Chrome, Firefox, and Safari in macOS High Sierra, and all were well.