I have this small codepen: https://codepen.io/Ardeshir81/pen/Byoapav
This is the code snippet:
<style>
.root { transform-origin: top left; scale: 20 }
span {
background:red; position:absolute; opacity:0.3;
&.horizontal { width:50px; height:1px; }
&.vertical { width:1px; height:20px; }
}
</style>
<div class="root">
<span class="horizontal" style="transform: translateY(1.2px);"></span>
<span class="horizontal" style="transform: translateY(13.1px);"></span>
<span class="vertical" style="transform: translateX(-0.2px);"></span>
<span class="vertical" style="transform: translateX(27.4px);"></span>
Hello
</span>
<!-- REGISTERING FONT BELOW -->
<style>
@font-face {
src: url('https://aghardeshir.github.io/static-cloud/DINNextLTPro-BoldCondensed-1.ttf') format('truetype');
font-family: 'DINNextLTPro-BoldCondensed-1';
}
* {
font-family: 'DINNextLTPro-BoldCondensed-1'
}
</style>
All it does is register a font, write a simple text that says "Hello" and draws 4 spans around the text, that fits perfectly on my laptop monitor. It also scaled the whole thing 20 times so its obvious. As in picture below:
The codepen on my laptop monitor
But as soon as I attach an external monitor, on the same browser tab open, on the same monitor, and I checked the laptop monitor resolution stayed the same, but the text is off a bit. Those 4 spans no longer fit perfectly around it:
The codepen on my laptop monitor with external monitor attached
I found out adding a line-height: 18px makes it stable for this case. Also getting rid of scale: 20 makes it stable. But I am trying to understand why this happens.
As more information, I figured if I inspect the text in those different situations, the bounding box is also shifted just as text did (expected), but one of them has different width/height than the other. One says its 27 x 16, the other says 55 x 32. But there is obviously no way that one of them is half the size of the other.
I uploaded a video so you can see it in action: https://aghardeshir.github.io/random-temp/text-rendering-different-when-external-monitor-attached
I also tried turning off "graphics accelration" and it did not help. The other difference I noticed is when external monitor is attached, the pixel density is 192 dpi, but with standalone laptop monitor, its 96 dpi. I'm using Linux Fedora (with Wayland).
Just to emphasize, i'm not looking for ways to fix this, I'm just trying to understand why this happens. All the system behind this. On FireFox it renders the same with and without external monitor, it happens only on Chrome.
-
@herrstrietzel I can benefit from your insights a lot hereArdeshir Izadi– Ardeshir Izadi2025年07月14日 10:04:29 +00:00Commented Jul 14 at 10:04
-
This is indeed a mystery. It seems you used the Chrome browser on Windows. What happens in Firefox? Or if you have access to it, in Safari? It is clear the font moves, and it has something to do with the font height, but I cannot reproduce it.KIKO Software– KIKO Software2025年07月14日 10:57:24 +00:00Commented Jul 14 at 10:57
-
1Sorry no clue but I can see the same misaligned rendering on Windows in Firefox and Chromium. However you should specify a line-height anyway to avoid inconsistencies due too different defaults. Your current layout concept may not be very robust as you're combining pixel fractions with scaling. Most browsers will apply some rounding. Font element are usually rendered with some hinting (a pixel-grid fitting technology) which will also cause some tiny pixel roundings. Maybe your setup normalizes the pixel-density when 2 displays with different resolutions are plugged in?herrstrietzel– herrstrietzel2025年07月14日 17:08:02 +00:00Commented Jul 14 at 17:08
-
1@Ardeshir Izadi: maybe not feasible for your ultimate application. My point is both the HTML text and span elements underly quite a few defaults and precision limitation (e.g when fractions of pixels are uses like `0.1px). Rendering both text (ideally as path) and lines in a SVG would significantly facilitate the bounding-box calculations and provide a higher number precision. In you codepen you indeed encounter the same problems as the SVG element is placed as an inline element also inheriting default line-heights and other defaults that can prevent a predictable rendering.herrstrietzel– herrstrietzel2025年07月20日 19:12:29 +00:00Commented Jul 20 at 19:12
-
1@Ardeshir Izadi: See simplified codepen example As you can see the bounding coordinates calculation is a piece of cake as we have all data we need from the font-dataherrstrietzel– herrstrietzel2025年07月20日 20:19:23 +00:00Commented Jul 20 at 20:19