Blueprint: Text blurry in popover when zoomed in Chrome

Created on 29 Dec 2016  路  25Comments  路  Source: palantir/blueprint

Bug report

  • __Package version(s)__: 1.2.2
  • __Browser and OS versions__: Chrome 54.0.2840.87

Steps to reproduce

  1. Go to http://blueprintjs.com/docs/#components.menu.js.submenu
  2. Zoom the browser window (Ctrl + '+' or Ctrl + mousewheel)

Actual behavior

The text in the dropdown menu is blurry

zoom

Expected behavior

The text should be crisp

Discussion

I've done some research and found that Chrome just doesn't handle subpixel font rendering very well when GPU optimization is enabled. Tether uses the transform attribute to enable GPU optimization for positioning the element but it can be disabled by passing a config option:

{ optimizations: { gpu: false } }

There's some discussion here: https://github.com/HubSpot/tether/pull/163 but no definite solution. The simplest solution from a blueprint perspective is to expose the Tether gpu option on the popover component but one might also argue this is something Tether should fix.

What do you guys think?

P3 core in discussion

Most helpful comment

Since this is still an issue (see #2391), I just want to note for others that my definitive solution (for 2.x) is to turn off gpuAcceleration in Popovers, like thus:

  • Popover: modifiers={{computeStyle: {gpuAcceleration: false}}}
  • Components that use Popover: popoverProps={{modifiers: {computeStyle: {gpuAcceleration: false}}}}

Short of somehow setting the global popper.defaults (not sure how to do this), it's easy enough to create wrapper components that inject these props each instance. Something like:

const MyMenu = (props) => {
    const popoverProps = props.popoverProps || {};
    popoverProps.modifiers = {computeStyle: {gpuAcceleration: false}};
    return <Menu {...props} popoverProps={popoverProps}/>
};

All 25 comments

Lo, for when the Half Pixel Problem rears its ugly head the Web Developer beats a hasty retreat.

We deal with Chrome's subpixel font rendering issues constantly (particularly with icons) and the best attitude seems to be "oh well." You just can't win every half pixel. There's basically nothing we or Tether can do about the occasional render on the half-pixel, particularly if you're gonna go zooming the browser window. Sorry!

@Binck360 does disabling the gpu acceleration fix things for you? The Popover props API is already somewhat large so a part of me hates to make it even larger, but if it fixes real issues, I don't think adding a tetherOptimizations prop or something would hurt.

I'm also seeing this at normal zoom level (100%) on Chrome on Mac:

image

Does it still do subpixel font rendering at a normal zoom level?

It also fixes itself if i zoom out/zoom back in or vise versa

Experiencing the same problem that @styu mentions on Chrome 55 for Mac. Normal zoom level. It doesn't completely fix itself when I zoom out/in, but it does get a little better.

I'm seeing this as well. Safari is more pronounced than Chrome. Latest versions.

As suggested before I'd really like to solve this issue by extending the Popover API with gpuOptimization,
and subsequently add the following option to createTetherOptions :

optimizations: { gpu: false }
at https://github.com/palantir/blueprint/blob/master/packages/core/src/common/tetherUtils.ts#L52

are you guys happy with this suggestion? If we can agree on this approach, then I'll create a PR

@Binck360 I think it'd be better to add a tetherOptions: Partial<ITetherOptions> prop that would get spread on top of our default tether options. We could then deprecate the constraints prop.

Latest master at 100% zoom feels fine. Not perfect, but fine.

On Safari:

On non-Retina display:

image

On Retina display:

image

On Chrome

On non-Retina display:

image

On Retina display:

image

On Firefox

On non-Retina display:

image

On Retina display:

image

Latest master at 120% zoom on Safari is still blurry, not nearly as blurry as, say, the Table in #742. The text here is plenty legible:

image

@Binck360 LMK if I'm not capturing the severity of this issue to its full extent. But absent further information, this issue feels more like a P3 to me. I could look into it further, but there's a slew of other higher-priority issues to attend to as well. @giladgray @llorca - thoughts?

@cmslewis agree with you. I personally can't repro now, and also don't see the issue with your latest screenshots. Sounds like another Chrome bug that was fixed, so I'm okay with deprioritizing

Why deprioritize instead of close?

This issue looks eminently closable so I'm going to do that. It'll always be here if we need it. 馃殺

Still can't repro on Mac, but was able to repro on Windows with Chrome 57 at 100% zoom. I only saw the issue with popovers and tooltips. Table and dialogs, which also use transforms, don't seem to be affected.

I was able to fix it in the inspector by giving translateX and translateY (from .pt-transition-container) even values. I'd assume than rounding it would be enough, but no, it has to be even numbers. Why?? 馃槚

FWIW, Chrome on Mac doesn't require even values. Simple rounding is fine.

Might be a Chrome bug still, looks like the Framer folks are hitting the same problem: https://bugs.chromium.org/p/chromium/issues/detail?id=740459

Just wondering if this has a recommended resolution, of if there are any better alternative React menu systems out there. I'm getting blurry text in Chrome, but only for this component, so I don't think it's just an issue with Chrome. Nothing else appears blurry. Maybe it's related to Tether/Popper?

Definitely hitting this in Chrome 64 on Windows 10. I use a system-wide text zoom, as do many people these days because screen resolutions are getting higher and higher, so I don't think this can be dismissed with "Oh too bad, you use a zoom."

As @rheinheimer mentioned, I see this only with Popover, so blaming it on Chrome doesn't feel right either.

I first noticed the issue with the dropdown menu here: http://blueprintjs.com/docs/v2/#core/components/menu.dropdown-menus

If I open the menu, the text is noticeably blurry:

dropdown-menu-blurry

If I hover over "Settings", the text gets clear (well, clearer):

dropdown-menu-clear

Since this is still an issue (see #2391), I just want to note for others that my definitive solution (for 2.x) is to turn off gpuAcceleration in Popovers, like thus:

  • Popover: modifiers={{computeStyle: {gpuAcceleration: false}}}
  • Components that use Popover: popoverProps={{modifiers: {computeStyle: {gpuAcceleration: false}}}}

Short of somehow setting the global popper.defaults (not sure how to do this), it's easy enough to create wrapper components that inject these props each instance. Something like:

const MyMenu = (props) => {
    const popoverProps = props.popoverProps || {};
    popoverProps.modifiers = {computeStyle: {gpuAcceleration: false}};
    return <Menu {...props} popoverProps={popoverProps}/>
};

@rheinheimer thanks for the comment! awesome to know this can be resolved. you can quite easily change the default prop values (and the code should handle merging with a given modifiers prop):

Popover.defaultProps.modifiers = { computeStyle: { gpuAcceleration: false } };

I just want to (finally) confirm @giladgray's solution, and that you just need to set this once in your main js file.

Edit: As far as I can tell, this also propagates to anything that takes popoverProps as an argument.

Note that if a modifiers props is given to a Popover or Tooltip component, the defaultProps won't take effect. I wonder if we have some API for this kind of global configuration

I also have the same issue as @KagamiChan with Tooltips. @giladgray I recommend re-opening this issue until it can be definitively resolved.

Note that if a modifiers props is given to a Popover or Tooltip component, the defaultProps won't take effect. I wonder if we have some API for this kind of global configuration

Yep. This solution does not work for ContextMenu component while it overrides Popover.modifiers with custom POPPER_MODIFIERS constant

My popover text is blurry at regular scale and becomes sharper when I zoom in actually. Running latest chrome on windows 10.

@adidahiya Is there an update on this? I'm on Windows 10, latest Chrome and I'm seeing blurry text on the docs site with no zoom.

hacked the popper code to get it to work. prepended translateZ(0). This is windows 10 & chrome. will probably write some intercept before render to catch the style and rewrite, but for now this is what did it in popper module:

 if (gpuAcceleration && prefixedProperty) {
    styles[prefixedProperty] = `translateZ(0) translate3d(${left}px, ${top}px, 0)`;
    styles[sideA] = 0;
    styles[sideB] = 0;
    styles.willChange = 'transform';
}

it's still a thing for popper... https://github.com/popperjs/popper-core/issues/682

Any update or fix?

Was this page helpful?
0 / 5 - 0 ratings