It's doing my eyes in!
looks fine in IE and Firefox
Chrome(Above)
Running version 39 of chrome,
only appears blurry in a modal box, does not make any difference if I change the font family.
This is the CSS (for label "Start") the browser renders the following
box-sizing: border-box;
color: rgb(85, 85, 85);
cursor: default;
display: block;
float: left;
font-family: sans-serif;
font-size: 12px;
font-weight: 600;
height: 24px;
line-height: 17.142858505249px;
margin-bottom: 0px;
margin-top: 0px;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
padding-top: 7px;
position: relative;
text-align: right;
visibility: visible;
width: 89.65625px;
Is it the browser or CSS?
--UPDATE---
Ok looks like its this CSS
.md-modal {
position: fixed;
top: 50%;
left: 50%;
width: 50%;
max-width: 630px;
min-width: 320px;
height: auto !important;
z-index: 2000;
visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transform: translateX(-50%) translateY(-50%); <--- This line
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
However if I take it out my modal no longer centres?
I fixed this issue by subtracting 0.5px from the value of the Y-axis. So instead of doing:
transform: translateX(-50%) translateY(-50%);
I did this:
transform: translateX(-50%) translateY(calc(-50% - .5px));
This solved it for me and I find this a cleaner solution then fiddling around with the percentage or using Javascript.
I experienced the same issue on chrome after applying translate transform to one of my elements. It seems to be a bug on chrome. The only thing that worked for me was this:
#the_element_that_you_applied_translate_to {
-webkit-filter: blur(0.000001px);
}
An Other solution can be turning smooth font rendering on:
#the_element_that_you_applied_translate_to {
-webkit-font-smoothing: antialiased;
}
This fiddle tests out a few different solutions from:
CSS transition effect makes image blurry / moves image 1px, in Chrome?
WebKit: Blurry text with css scale + translate3d
http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/
Test Output
Fix 0
-webkit-transform: translateZ(0);
transform: translateZ(0);
Fix 3
-webkit-transform: translate3d(0,0,0) !important;
transform: translate3d(0,0,0) !important;
The only correct way to solve this:
This problem arises from the fact of using % values to align the divs using css transforms. This results in decimals subpixel values, which your screen cannot render correctly. The solution is to normalize the resulting transformation matrix.
Might work better for fixed divs that don´t do transforming animation. But if you do animate you could use a after end callback to this function to correct the final state.
So:
matrix (1,0,0,1,-375,-451.5) would become matrix (1,0,0,1,-375,-451)
I call this method before the .show() of jquery... Or maybe just once in the application ( depends on your case) , you might need to also call this on the resize event etc..
function roundCssTransformMatrix(element){
var el = document.getElementById(element);
el.style.transform=""; //resets the redifined matrix to allow recalculation, the original style should be defined in the class not inline.
var mx = window.getComputedStyle(el, null); //gets the current computed style
mx = mx.getPropertyValue("-webkit-transform") ||
mx.getPropertyValue("-moz-transform") ||
mx.getPropertyValue("-ms-transform") ||
mx.getPropertyValue("-o-transform") ||
mx.getPropertyValue("transform") || false;
var values = mx.replace(/ |\(|\)|matrix/g,"").split(",");
for(var v in values) { values[v]=v>4?Math.ceil(values[v]):values[v]; }
$("#"+element).css({transform:"matrix("+values.join()+")"});
}
and call it
roundCssTransformMatrix("MyElementDivId");
$("#MyElementDivId").show();
Beautiful isn't it?
If you need to update on resize you could do it with:
$( window ).resize(function() {
roundCssTransformMatrix("MyElementDivId");
});
For this to work, all the parent must "be aligned / normalized"
because if you by instance have the body with x=10.1px left, and the
child is 10px .. the issue wont disapear because of the parent having residual decimals on their matrix
So you must apply this function to the each element that is a parent and
uses transform.
You can see this live script here: https://jsbin.com/fobana/edit?html,css,js,output
Thanks for the CSS example. It seems translateX(50%) and translateY(50%) are calculating a pixel value with a decimal place (eg, 0.5px) which causes subpixel rendering.
There are many fixes for this but if you want to retain the quality of the text, your best solution right now is to use -webkit-font-smoothing: subpixel-antialiased; on .md-modal to force the render state for webkit browsers like Chrome and Safari.
I ended up fixing this by removing these lines:
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
It took me a while to find a solution that I wouldn't bother using, so I'll post it here.
The problem for me was that the child div had width and height properties with a combination that caused the problem.
As I changed the height for another value, it just worked!
This probably has to do with the other answers, but I didn't want to use any JS or change the transform property to fix it.
Here is a live example: JSFIDDLE
If you want to center something, better use flexbox. It will help you position without having blurred text.
Add this to parent div of that element you want to center:
display: flex;
justify-content: center;
align-items: center;
Hope this helps.
Seems Chrome 78 still has this bug https://bugs.chromium.org/p/chromium/issues/detail?id=521364.
Building upon previous answers, I found the CSS below gave me the sharpest display on a translated modal:
transform: translate(calc(-50% - .4px), calc(-50% - .4px));
EDIT:
For IE11 compatibility:
transform: translateX(-50%) translateX(-0.4px) translateY(-50%) translateY(-0.4px);
For modal boxes, this css will help:
-webkit-transform: translate3d(-50%, -51%, 0);
-moz-transform: translate3d(-50%, -51%, 0);
transform: translate3d(-50%, -51%, 0);
Instead of placing Y axis at 50%, make it 51%. This helps in my cse.
If you have a different positioning, play around, but usually 1% up/down fixes blurry content.
TLDR
I faced this problem a few days ago. I almost went crazy trying to sharpen the fonts in Chrome. I have read all posts in this thread and in all other posts regarding sharpening fonts in Chrome. Even the message "The only correct way to solve this" did not help in my case. What helped?
It is worth mentioning that the problem occurred in the following div:
position: sticky;
left: 16%;
And the 'sticky' attribute turned out to be the biggest problem. For sticky elements, we set the position as for 'absolute' elements - using attributes the 'left', 'top' etc. And here is the problem: with not integer values of the 'left' the font is rendered dramatically blurry, with integers it is much better.
What is the solution?
position: sticky;
left: 0;
margin-left: 16%;
And that's all. Chrome will handle the percentage 'margin' and the fonts will look sharp.
I know this is an old issue but since i stumbled across it in 2022 I thought I just tell someone who needs this how I solved it in my situation:
I had a modal with a textarea in it and in Chrome it was displayed blurry, but only when the textarea was overflowing.
My modal - NOT the textarea itself - had overflow: hidden; so I just removed that.
Adding a CSS transition to the parent element of the parent element of my blurry element (which was using transformX which was causing blurriness) actually cancelled out the offending blurriness.
The similar issue happened for me.
I tried with all the suggested methods none worked fine. However,finally I resolved it.
As there is an issue with google chrome having font-weight:600 or more.
Try changing the font-family to font-family:"Webly Sleek SemiBold","Helvetica";
The font-weight property will work fine for it.
Another cause may be that you are not providing the needed font weights that you are utilizing.
For example, if you want to use both Lato or Roboto you want to include more than just the standard weight. This example applies if you are using Google Font API:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,900|Roboto:500,700">
Note: Lato is available in 100, 300, 400, 700, and 900 font-weight, but I had to specify 900 for my 700 text to become crisp...not sure why.
For now, I found only one good solution:
transform: translate(-50%, -50.1%)
0.1% - in general user can't see this
Hope chrome will fix it - the bug exists since 2014))))
If you do not want implementing any special js or custom solution and the only what you want to achieve is center your div, and the width and height does not have fixed size, you can simply use this:
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
If one of sizes is fixed, you can try this approach:
position: absolute;
left: 50%;
translate: transformX(-50%);
top: 0;
bottom: 0;
margin: auto;
It fixes the problem with blurred font in chrome.
You can solve this issue by putting:
transform: inherit;
The best way I've found to resolve this issue which appears to only be an issue in Chrome and only on specific screen sizes, is to replace all transform:translate(-50%,50%) definitions with alternate solutions. Using any other solution may solve it on your screen, but not on another.
Transform definitions are usually used to center elements. Rather than using a transform definition, find another way to center your element, problem will be solved. In our case, we had a fixed div we wanted centered, with a max-width of 1800px and bottom set to 0px;
#cntr{position:fixed;left:50%;bottom:0;width:100%;max-width:1800px;transform:translateX(-50%);-ms-transform:translateX(-50%);-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-o-transform:translateX(-50%);text-align:center;}
Lot of definitions in there to cover all browsers. Changed to this to resolve it :
#cntr{position:fixed;left:0;right:0;margin:auto;bottom:0;width:100%;max-width:1800px;text-align:center;}
A lot less code, cleaner, faster, and worked 100%, without needing to edit any HTML.
Definitions that now center the fixed pos div are: left:0;right:0;margin:auto;
No translate required, no decimal point placed divs.
For those still trying to find a solution to this, setting background fixed it for me for some reason.
background: #fff;
I found that applying the translate3d(0, 0, 0) fix as JSuar suggested worked in Chrome but not Safari.
The one thing that did work across browsers was to give the element I was centring (using transform: translate(50%, -50%)) an even pixel width — changing the width from 425px to 426px made the text sharp again.
The issue often happens with position: fixed; and transform: translate(...) when the width and height of the element are not a round even number.
One of the solutions is to round up the numbers programmatically. Example:
function roundToEven(x) {
const rounded = Math.round(x)
return rounded % 2 ? rounded + 1 : rounded
}
const element = document.getElementById('element-id')
const rect = element.getBoundingClientRect()
element.style.width = roundToEven(rect.width) + 'px'
element.style.height = roundToEven(rect.height) + 'px'
You should choose your font with corresponding font weight which you want if you want thin, regular and bold text. You should choose font with weight 100 | 400 | 700 example: like below
Font weight is not only number. File should be available in server or directory.
Each font weight is separate file.
If you force to change regular font into bold without resource, it showing with blurry. I hope you get it.
#import
url('https://fonts.googleapis.com/css2?family=Roboto:wght#100;400;700&display=swap');
Just in case anyone is having this issue using the Roboto font from Google. My text was looking sort of blurry. I noticed that I wasn't importing the correct font-weight from Google. I needed 700 but wasn't including it.
https://fonts.googleapis.com/css2?family=Roboto:wght#300;400;500&display=swap
vs
https://fonts.googleapis.com/css2?family=Roboto:wght#300;400;500;700&display=swap
I had this issue with my site as well, using a similar setup.
The issue appears because of a 0.5px difference.
An easy fix is to change the top property from 50% to calc(50% - .5px)
Related
The incorrect scaled size happens in Webkit browsers, i.e. Chrome, Safari. Chrome version I am using is 68.
Demo: Codepen Link
Code as requested by #Kaiido
HTML:
<div class="test1"></div>
<div class="test2"></div>
CSS:
.test1 {
z-index: 100;
position: fixed;
top: 10px;
left: 10px;
width: 1px;
height: 1px;
background: blue;
transform-origin: top left;
transform: scale(100, 100);
}
.test2 {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: red;
}
In the link above, if you zoom in/out of chrome, you would see the scale size does not necessary match the fixed size of the .test2 div. I would expect the final size of the scale(100, 100) to be exactly the same as the one with width:100px; height: 100px upon scaling but obviously this is not the case.
I have also tested this in both retina mac and pc. It is the same behavior in Chrome. However same code is tested in Firefox and is working correctly.
Is this some sort of bug or am I missing something? Thanks.
It is a bug... caused by the fact these browsers round coordinates to avoid antialiasing.
So when you set your zoom level to 120%, the small square should actually be rendered as a 1.2px*1.2px square prior transform.
But webkit browsers will round this value to 1px, even before they apply the transformation (I think FF also does but probably after transform).
So you won't see a change until you get to zoom 150%, where now it will get rounded to 2px and your blue square will get bigger than the same 100px*100px.
Only at 200% will they match again.
Not much to do to circumvent this, apart letting them know, and avoiding playing with such small elements ;-) (using a 10px*10px square and dividing the transform zoom level by 10 would prevent this bug).
Have caught similar case on mobile Chrome. Scaling 1px value to some width by CSS transform after ~100px result become totally wrong and become worser as continue. In my case this was a js-based range control, where I scale its 'progress' visual part from 1px (base) to current user touchX position by transform: scaleX(touchX);
My vision of problem is based on understanding of CSS units evaluations (https://webplatform.github.io/docs/tutorials/understanding-css-units/): there is sort of eager integer equation for antialiasing on screens with fractional window.devicePixelRatio. Android often has a 2.3, 2.6 DPRs, and it may changes when user changes display's zoom system settings.
My solution involves javascript, so may be inappropriate for you, still may be useful:
fixedWidth = (devicePixelRatio * originalWidth) / Math.round(devicePixelRatio);
Actually I have found what has caused the problem. My question is now why adding transform to your html, body breaks the position: fixed?
Original problem
The most simple CSS task seems to fail for me: position: fixed does not keep the position of the element relative to the view point. Consider the following stylesheet:
.stay-there-dammit {
position: fixed;
right: 0px;
left: 0px;
z-index: 1030;
}
For the first time the page loads, the positioning is correct. But any changes to viewport such as scrolling or resizing doesn't affect the positioning of .stay-there-dammit element. So to speak it doesn't adapt its position to the new viewport.
Strangely enough this site which shows how position: fixed should work, actually work in my browser with no problems whatsoever!
So the question is: Is there anything that might break fixed positioning?
Btw. I use Bootstrap 3.
UPDATE:
It seems that it was the transform set by some third-party application on html,body that broke the position: fixed. Here is what I had to remove:
html, body {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3, mirror=1);
-webkit-transform: scale(1, 1);
-moz-transform: scale(1, 1);
-ms-transform: scale(1, 1);
-o-transform: scale(1, 1);
transform: scale(1, 1);
}
It seems that the following question addresses the same issue:
Positions fixed doesn't work when using -webkit-transform
BUT WHY?
Regarding the why, a quick quote from this article by meyer:
A transformed element creates a containing block even for descendants that have been set to position: fixed. In other words, the containing block for a fixed-position descendant of a transformed element is the transformed element, not the viewport
It's a quirky behavior that's been around since 2011.
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); */
}
Hi there I am working on this site - http://smudgedigital.com/animation-projects/ and have an issue with the gallery on the projects page. The images should all be a circle and when rolled over the the image should remain a circle and have a hover black state.
However despite the site working fine I have recently noticed that the circles are no longer circles in google chrome. The are in fact square on all states.
I have looked through this site to find any answers but none of them seem to work. I have tried using the border radius code for all browsers;
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%;
but it does not seem to pick it up, even when I use the !important tag. I have also tried using pixels instead of percent. When I use the inspect element tool I can add this;
.view img {
display: block;
position: relative;
border-radius: 100%;
}
and it works on the normal state, but when I put it into my site css it does not appear.
I have seen some people say that google just doesnt understand the overflow: hidden property and it has nothing to do with the border radius, however overflow: hidden does appear.
Any help would be greatly appreciated. I have built the site on wordpress.
Thanks,
This looks to be a known bug in Chrome I'm afraid. It's related to transition mainly, and how the order of parent/child becomes when the DOM is being painted during a transition:
https://code.google.com/p/chromium/issues/detail?id=157218
As an alternative you could maybe make the entire circle including border and shadow increase in size. However I don't think that is the effect you want.
Please also see this thread on Stack Overflow: Bug with transform: scale and overflow: hidden in Chrome
Added
.view-first img {
transition: all 0.2s linear;
border-radius: 100%; /* added new */
}
removed
.view{
overflow:hidden; /* removed */
}
I am creating a slider with custom "prev/next" navigation-arrows.
All the animations works fine. I use the transform: scale() to scale up the arrows when hovering and it all works fine. I just have one problem..
I want to prevent the arrow images to scale too.
I think I have tried everything: I've used somekind of :before/:after (see below) and it worked pretty good. But not in Safari (No transition when hover).
http://jsfiddle.net/XF4Qj/5/
Then I tried something else: Putting a span inside the arrow container, and when the arrow container was scaled up, the span was scaled down, but it didn't looked good at all (See below).
http://jsfiddle.net/Ajngc/1/
I have tried for hours, but I cannot get it to work in all major browsers.
So the question is: How to I prevent the arrow-images from scaling too, and just preserve their original dimensions?
It's only the white circle that schould be scaled up, and not the background image.
I've created a third fiddle, which has all the working code from my slider-arrow-functions:
http://jsfiddle.net/Ajngc/2/
Could be really great if someone could help me with this.
Thank you very much
- Jesper
Instead of transform()ing those elements, why not just change the size? See this updated fiddle.
.arrow:hover {
width: 50px;
height: 50px;
top: -5px;
bottom: -5px;
}
.prev:hover {
left: 35px;
}
.next:hover {
right: 35px;
}