Reputation: 5760
EDIT 2016-07-04(Since this question is getting popular): This is a bug in Chrome. Developers are actively working on a fix.
EDIT 2017-05-14 The bug seems to be fixed, the fix will be introduced in Chrome 60
EDIT 2018-05-04 A fix has been merged, but the bug still appears to be present.
So I have this very ugly-looking window that is centered on the screen by this CSS:
.popup
{
position: fixed;
top: 0;
bottom: 0;
transform: translate(-50%, -50%);
}
However, it looks like this on Chrome (the font looks really blurry):
But like this on Firefox:
When I remove the transform
rule, the text looks nice and crispy again, but then it's no longer correctly centered.
When I go to chrome://flags
and execute #disable-direct-write
it looks nicer, but users are obviously not going to do that and it doesn't solve the problem.
How can I make my font look nice while still having the window centered?
My chrome version is 44.0.2403.155
I have a three.js
demo using WebGL that renders on a background canvas. When I disable the demo, the problem no longer occurs.
JSFiddle without the background.
Upvotes: 37
Views: 22023
Reputation: 1
I don't have a pure CSS solution but in my case I was able to resolve this issue by forcing "pixel-perfect" alignment. I'm suspecting that Chromimum based browsers don't handle CSS transforms as elegantly as Firefox. Below is my solution:
/**
* Gets the nearest CSS pixel position that aligns with a device pixel.
* @param {{x: number, y: number}} position Element position in CSS pixels.
* @returns {{x: number, y: number}} An object containing the "pixel-perfect" x and y position.
*/
function roundToNearestPhysicalPixel(position) {
// Reference: https://web.dev/articles/device-pixel-content-box
// Device pixel ratio: number of physical pixels needed to form a single CSS pixel.
const fracPixels = devicePixelRatio % 1;
const cssPixelRoundingIncrement = 1 / fracPixels;
const inc = cssPixelRoundingIncrement;
return {x: Math.round(position.x / inc) * inc, y: Math.round(position.y / inc) * inc};
}
In my case, I was transforming an element to match the user's mouse position using JavaScript. I know this won't help most people but I think it explains the symptoms - essentially we are observing an issue with "pixel snapping".
Upvotes: 0
Reputation: 2023
The only solution that worked for me:
Translates can cause blur due to result not being rounded to the nearest pixels, so rounding the div height to an even number fixes it.
We can't do it in CSS as it doesn't know yet its final height, so we have to do it after rendering. Using Jquery is a breeze:
$(window).on("load", function() {
if($('.popup').height()%2==1) $('.popup').height( 2*Math.round($('.popup').height()/2 ) ) ;
if($('.popup').width()%2==1) $('.popup').width( 2*Math.round($('.popup').width()/2 ) ) ;
});
Credits: https://stackoverflow.com/a/57382347/1136132
Upvotes: 1
Reputation: 119
First of all add overflow: hiddden
to the parent element of the modal, if that's not enough add this to modal's style : display: contents
Happy coding, love from Mauritania
Upvotes: 0
Reputation: 635
A suggestion from a related discussion solved the issue for me: https://stackoverflow.com/a/46117022/7375996
Using calc with some offset solved the issue in my case:
transform: translate(calc(-50% + 0.5px), calc(-50% + 0.5px));
Upvotes: 16
Reputation: 141
I've tried different solutions in different, sometimes scary, combinations:
translate3d
instead of translateY
zoom:2; transform: scale(0.5);
or zoom:0.5; transform: scale(2);
transform: translate(calc(-50% + 0.5px), calc(-50% + 0.5px));
-webkit-filter: blur(0);
perspective: 1000px
scale(1.0, 1.0)
-webkit-font-smoothing: subpixel-antialiased;
none of them work in july 2019.
The only solution i found for modals, that should be centered - to use a flexbox aligment instead of transform: translate.
.modal__container {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
}
.modal {
box-sizing: border-box;
max-width: 80%;
max-height: 80%;
padding: 20px;
overflow-y: auto;
background: #fff;
}
<div class="modal__container">
<div class="modal">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
Upvotes: 11
Reputation: 1140
2019-04-15, still happening to me in Chrome. Found that changing position: fixed
to absolute
fixed it:
.popup
{
position: absolute; <-- just like that
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Using absolute may or may not suit your particular case, just my 2 cents.
Upvotes: 1
Reputation: 21
The height of the elements must be even numbers https://prnt.sc/mtxxa2
Upvotes: 1
Reputation: 3618
Use a normalization of the transform after your animation:
Or We scale the texture with zoom double, then scale down again. In some cases this cannot be applied due to other complex transformations or translations, and is not perfect.
...{
zoom:2;
-webkit-transform: scale(0.5);
transform: scale(0.5);
}
Upvotes: 1
Reputation: 2938
I tried every solution and only this is working for me (chrome 53)
dialog {
position: fixed;
top: 50%;
transform: translate(0, -50%);
}
Upvotes: -1
Reputation: 3187
Problem in half of pixel.
Try: transform: translate(-50%, -51%);
It will work!
Upvotes: 5
Reputation: 8572
I found out -webkit-filter: blur(0)
could fix your blurry font in Chrome on Windows:
#projectPopup {
...
-webkit-filter: blur(0);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
Upvotes: 3