CSS Transform Scaling Keeps Large-Screen Dashboards Pixel-Perfect Across Any Display
Screen adaptation is a common issue in front-end development. In large-screen visualization projects, screen adaptation technology is the core technical link that ensures consistency between design drafts and actual display effects. Current adaptation solutions mainly include viewport scaling, relative units, responsive layout, etc. This article mainly introduces how to use CSS3 transform scaling technology to achieve an adaptive adaptation solution for large-screen applications.
In the process of developing large-screen adaptation, there are two dimensions: the dimensions of the design draft and the dimensions of the screen. What we need to do is to ensure that our page can be fully displayed in its original proportions under different screen sizes. As shown below:
The first problem we need to think about is the page scaling ratio. The width scaling ratio is screen width / design draft width, and the height scaling ratio is screen height / design draft height. Once we have the scaling ratios, we can scale the entire page according to the smaller ratio.
const scaleX = innerWidth / width; // width is the design draft width
const scaleY = innerHeight / height; // height is the design draft height
el.style.transform = `scale(${Math.min(scaleX, scaleY)})`;
But there is a small problem here: the center point of the page scaling is incorrect. We need to set the transformOrigin.
el.style.transformOrigin = 'top left';
const scaleX = innerWidth / width;
const scaleY = innerHeight / height;
el.style.transform = `scale(${Math.min(scaleX, scaleY)})`;
At this point, the basic logic for large-screen adaptation is written. We need to encapsulate a function and then call this function when the screen changes to adapt to various screens.
function autoScale(selector, options) {
const el = document.querySelector(selector);
const { width, height } = options; // Pass in the width and height of the design draft
el.style.transformOrigin = 'top left';
function init() {
const scaleX = innerWidth / width;
const scaleY = innerHeight / height;
el.style.transform = `scale(${Math.min(scaleX, scaleY)})`;
}
init();
addEventListener('resize', init);
}
At this point, the page can basically be displayed with proportional scaling, but the page content is in the upper left corner of the screen and is not centered. Further optimization is needed. We can use X and Y translation to keep the page displayed in the center. Note: When using transform, you must write translate first, then scale, otherwise you will find it incorrect.
function autoScale(selector, options) {
const el = document.querySelector(selector);
const { width, height } = options;
el.style.transformOrigin = "top left";
function init() {
const scaleX = innerWidth / width;
const scaleY = innerHeight / height;
const left = (innerWidth - width * Math.min(scaleX, scaleY)) / 2;
const top = (innerHeight - height * Math.min(scaleX, scaleY)) / 2;
el.style.transform = `translate(${left}px, ${top}px) scale(${Math.min(scaleX, scaleY)})`;
}
init();
addEventListener("resize", init);
}
At this point, the large-screen adaptation solution is basically complete. For a smoother experience, further optimization is needed: because the resize event is triggered at a relatively high frequency, we need to add debouncing. Then you will find that each resize makes the page change rather abruptly, so we also need to add a transition effect.
function autoScale(selector, options) {
const el = document.querySelector(selector);
const { width, height } = options;
el.style.transformOrigin = "top left";
el.style.transition = 'transform .5s'
function init() {
const scaleX = innerWidth / width;
const scaleY = innerHeight / height;
const left = (innerWidth - width * Math.min(scaleX, scaleY)) / 2;
const top = (innerHeight - height * Math.min(scaleX, scaleY)) / 2;
el.style.transform = `translate(${left}px, ${top}px) scale(${Math.min(scaleX, scaleY)})`;
}
init();
addEventListener("resize", debounce(init));
}