A div
contains an SVG (D3 graph) and has its width
set to 100%
. The size cannot be set to a fixed point because the page should feel responsive.
Expected behaviour: When the user zooms in (ctrl +
), the SVG should become bigger, more readable.
Actual behaviour: The SVG shrinks because the surrounding elements (header, navigation etc) take up more space, which means less space for the SVG. Zooming out makes the SVG grow.
What I’ve tried:
/* JS */
document.documentElement.style.setProperty('--zoom-ratio', `${window.devicePixelRatio}`)
/* CSS */
.foo-container {
overflow: auto;
}
.foo {
width: calc(var(--zoom-ratio) * 100%);
}
This works, as long as someone uses a screen with a 1:1 pixel ratio. 4k laptop displays are often set to 200-250%, which means that the SVG uses more than twice as much space as it should. How can I fix this?
2
Answers
Sadly the provided answer didn't solve my problem but I found a hack that seems to work well enough. If someone finds a better solution in the future, I will mark that one as the correct answer. Until then, the following worked for me:
It uses
outerWidth
andinnerWidth
to figure out the ratio.innerWidth
is affected by zoom, whileouterWidth
isn't and system settings affect both, so the ratio stays the same.outerWidth
also includes browser borders and drag handles, which meansouterWidth / innerWidth
is slightly larger than1.0
if the browser is not in fullscreen mode. So the raw zoom ratio itself is not enough but I round it to an accuracy of1/16
, which seems to work decently well with modern UIs (needs more testing) and hopefully avoids floating point rounding issues better than something like1/10
.If the
resize
event is triggered (and zooming in/out triggers the event) the handler does a quick check if the ratio actually changed meaningfully (again, avoid float errors) and if it did it sets a CSS variable--zoom-ratio
that can then be used throughout the project. Don't forget to initialize it to1.0
in your CSS file.In my experience its best to have initial value calculated on the BOXSIZE/WindowSize and calculate the Content relative to the box/window
this will overcome issues of diferent devices accessing the content
than add listener to change the view on window size change
Example: