Text color different on retina vs thunderbolt display


#1

I created a syntax theme on my retina macbook pro, but I noticed that it looks very different when I connect my lappy to my thunderbolt display (specifically the text colors). Is there a way to fix this so that what I see on my thunderbolt is the same as what I see on retina?


#2

As you might have already noticed, the two look exactly the same :stuck_out_tongue:

I suspect the reason why they look differently for you is that every display shows colors differently - this is not something specific to atom, but just a physical hardware thing. Furthermore, you can set different color profiles for different monitors (see System Preferences -> Displays -> Color) which can further add to that.

Colors are a very delicate and difficult issue, but if your monitors are set up correctly and you have roughly comparable monitors then there shouldn’t be TOO much of a difference.
Usually, apple’s monitors are pretty good and have a very high contrast - if you have a non-apple external display then it might not be able to provide the same level of contrast and colors that the retina display does (especially if it’s a non-glaring display). From what I understand, though, you have a cinema display (so an external display made by apple)? If that is the case, the difference SHOULD be minimal - you might want to check out color profiles and calibration, although that can be very difficult to do.


#3

@BlackWolf
At first, I also thought it was the difference in colors between my retina macbook pro screen and my thunderbolt display. But by adding -webkit-font-smoothing: antialiased to my editor styles, my display text colors match my retina text colors. The only downside is that now the font is too thin. Maybe I need to look into font rendering?


#4

Which version of OS X are you running? Maybe it’s an OS font rendering thing? As far as I know OS X renders fonts differently on retina displays, but I do have a retina display and I have not seen this behaviour so far.

But to be honest, I am not really a big expert on font rendering and stuff, so I guess I can’t help you there :frowning:


#5

My macbook pro is running Mavericks (10.9.3) :S


#6

TL; DR. Is that because of the color fringing associated with subpixel antialiasing (which is the default)? Most people don’t notice it, some people hate it, and you seem to be in some middle ground.

If I inspect my Atom (0.95.0), I see -webkit-font-smoothing: auto on text. Does that match what you see?
I would verify that -webkit-font-smoothing: subpixel-antialiased reproduces the problematic output you saw before. I can’t really check myself, since I’m not sensitive enough to notice the effects on color.

If that’s the case, searching webkit-font-smoothing will give you lots to read, and tons of debates over what’s better.

About font width: it appears that OS X makes the font bolder when using subpixel antialiasing. But most people fiddling with this seem to dislike it, because that’s not how those fonts are designed to look. I’d just look at how to increase the font weight or pick another font — people seem to use all sort of hacks for that (I’m no web designer though, I can’t really judge).


#7

@Blaisorblade
I believe -webkit-font-smoothing: subpixel-antialiased is indeed the default for OS X, as I have manually applied the style and the text remained the same. The problem is, I love how subpixel-antialiased looks on retina, but I hate it without retina. I also noticed that even google fonts uses font smoothing subpixel-antialised.


#8

@N0ctis I see your point. Let me guess how this could be doable. (I’m ignoring the original request because it seems different). But warning: I’m no expert web developer, so don’t trust the above too much. It’s just a somewhat educated guess. And I’m assuming you (or somebody else) knows JavaScript/DOM/Atom better than me.

If there were a way to detect a display for the editor, you could add the right class to your editor, say with $('html').toggleClass('on-non-retina'), and then have a conditional stylesheet on that class, making -webkit-font-smoothing: antialiased conditional to that. (Kudos to the layout-manager package for the idea).

window.screen might allow detecting the display, as it contains screen resolutions.
Now you just need to hook your code to some event, so that it’s called when a window is created or moved. I’m thinking of the events window.onresize and window.onload; a key combo might be more robust though, because for instance I fear onresize might not be invoked if you just drag your window to the other display and do not resize it (didn’t try though). I was looking for onmove, but found nothing which matches precisely (ondrag? onchange?) — but I guess you’ll know better.


#9

Just to add to that, modern browsers (and I guess the chromium that atom uses) allow you to use window.devicePixelRatio … if this is >1 the screen is assumed to be “retina” (it’s actually 2 for a apple retina screen and 1 for a non-retina screen). Maybe that helps!


#10

@BlackWolf: yes, that seems perfect!

On my displays, that’s available and it’s 1 on my external display and 2 on my Retina one. It’s also updated correctly after dragging an Atom window to another screen. Finally, using that expresses the correct program logic (as opposed to looking at the screen resolution, guessing from that which is the current display, and taking action using that, which is the only hack I was implicitly proposing).

Does that work for the OP? I think if you get this done, the solution might be worth sharing.


#11

The problem is not detecting when the display is retina or not, but rather how to get the colors I see on retina on my thunderbolt display.

Detecting when the screen is retina can be solved simply by using a media query:

@media (-webkit-min-device-pixel-ratio: 2) { /* Retina Styles Here */ }

#12

I see! (Indeed, no expert web developer here). I’ll give it a shot, but I suspect this should be my last post on the topic.

Given this:

Then I’d try disabling it on Thunderbolt, with the reverse media query. Since the resulting font is too thin, I’d maybe add a text stroke (idea stolen from http://const.fr/chrome-webfonts-antialiasing-fixed/). Something like:

@media (-webkit-max-device-pixel-ratio: 1) {
  html {
    -webkit-font-smoothing: antialiased;
    -webkit-text-stroke-width: .03em;
  }
}

But I’m not sure that’s what you actually want. 0.5em above would match (for me) the font width of subpixel antialiasing on Thunderbolt, while .03em matches the width of subpixel antialiasing on Retina. Since the font width (at least on a dark theme) seems to correlate with brightness (for obvious reasons), I’ve tried to reproduce the width of Retina on the non-Retina display.
(What’s confusing is that in your screenshot, the fonts appear sharper on the non-Retina display. Which sounds wrong here).

A bit of interesting background on Apple subpixel antialiasing, which might be useful here: http://www.joelonsoftware.com/items/2007/06/12.html.


#13

I was hoping to avoid using -webkit-text-stroke-width since it is more of a hack than a real solution. Although it does increase the “weight” of the text, as a side-effect it also makes the text a little blurry. For the time being I will use the webkit-text-stroke-width hack until I find a stable solution, in which case I will be sure to post back here. Thank you everyone, for your thoughts and input thus far.