I am making a website with a multipage google-doc-like user interface and want to allow the user to "zoom" or change the scale of everything on the page with "zoom in" and "zoom out" buttons. At first I tried to achieve this by styling everything using rem units and using this js:
$(document).ready(function() {
var fontSize = parseInt($("html").css("font-size"), 10);
$("#in").on("click", function() {
fontSize += 0.5;
$("html").css("font-size", fontSize + "px");
});
$("#out").on("click", function() {
fontSize -= 0.5;
$("html").css("font-size", fontSize + "px");
});
});
This works, but the problem is that there are many divs on the page (laid out in a single vertical column), so if you are scrolled in the middle of the page and then click the zoom function, causing them all to resize, it produces a scrolling effect as the divs get smaller or bigger and therefore get pushed further up or down on the page. This is disorienting if the content you were viewing before zooming is no longer on the page after the zoom. Here is a codepen demonstrating this.
Next, I tried zooming using the transform scale() css property and adjusting the transform-origin to be centered on the user's scroll position:
var zoom = 1;
$("#in").on("click", function () {
var x = window.innerWidth / 2;
var y = $(window).scrollTop() + $(window).height() / 2;
zoom += 0.2;
$(".container").css({
transformOrigin: x + "px " + y + "px",
transform: "scale(" + zoom + ")",
});
});
$("#out").on("click", function () {
var x = window.innerWidth / 2;
var y = $(window).scrollTop() + $(window).height() / 2;
zoom -= 0.2;
$(".container").css({
transformOrigin: x + "px " + y + "px",
transform: "scale(" + zoom + ")",
});
});
The problem with this is that portions of the pages get cut off when you zoom as the viewport doesn't expand to accommodate the scaled divs. Here is a codepen to demonstrate this approach.
I've searched extensively and can't seem to find a good solution to the problem. I have also considered using the "zoom" css function but from what I understand this is not supported and behaves differently in different browsers.
Any ideas would be much appreciated! Thanks