I have to make a speech bubble of sorts, and I've been provided an SVG for the part of the bubble that would point to the speaker. I'm trying to make the box itself a regular bordered div (this div will have dynamic height and width based on its contents, however the SVG will remain the same size).
I've done something similar to this stackblitz example:
But when using external monitors or even a Windows PC with a 2560x1440 monitor the SVG doesn't look fully aligned.
The problem is even more evident when using browser zoom. This is how it looks on that Windows PC at 75% zoom:
Here it looks like the border is reduced to 1px width, so the SVG path looks not only not aligned but also the incorrect size.
Is there a way to make the SVG behave the same way as the border-width so that they are always aligned and the same size? Maybe some other way to achieve the same effect?
CodePudding user response:
The Browser doesn't render sub-pixels on borders
but does on SVG
. That means at 125% DPI Scaling your border is technically 2.5px, but get's rounded down to 2px.
One way to solve this, it by adding resolution media queries
.
@media (min-resolution: 120dpi) {
.box {
border-width: 2.5px;
}
}
Demo: https://stackblitz.com/edit/angular-ivy-vbqtnz
Here is a short list of the scaling levels and the corresponding dpi values:
- Smaller 100% (default) = 96 dpi
- Medium 125% = 120 dpi
- Larger 150% = 144 dpi
- Extra Large 200% = 192 dpi
CodePudding user response:
I'm not sure there is much you can do about this. SVGs have behaviour, around scaling and anti-aliasing, that is different to how browsers handle border width scaling.
One solution - that you probably won't like much - is to get the SVG to behave similarly to how the borders behave, by turning off anti-aliasing. You can do this by adding shape-rendering="crispEdges"
to the <path>
.
<path
d="M43 37L38 37C38 37 34 29.6686 26 22.4215C18 15.1745 7.5 8.34577 5 10.3566C2.5 12.3674 5.5 15.8864 6 24.9351C6.5 33.9838 5 37 5 37L0 37"
stroke="currentcolor"
stroke-width="2"
shape-rendering="crispEdges"
/>
The SVG stroke will stay much closer to the border width in size. But the curvy shape of the path will now look unpleasantly "jaggy".
My advice: switch the whole speech bubble to the same technique. Either both HTML, or both SVG.
Or just live with the slight difference.