Fullscreen Page Adaptation
To install all solutions, please refer to Solutions Installation
Applicable Scenarios
The page size matches the screen's viewport, and the project page needs to be fully displayed on the screen while maintaining the UI design's dimensions and proportions.
Solution
Use postcss-pxtorem
to convert page units to rem (relative to the root element's font size). Then calculate an appropriate scaling ratio based on the UI design dimensions and the screen size to ensure the page is fully displayed while preserving the design proportions.
TIP
Note: Areas requiring adaptive layout within the page need manual style adjustments.
Install This Hook Separately
shell
npm install @havue/use-full-screen-adapt --save
shell
yarn add @havue/use-full-screen-adapt
shell
pnpm install @havue/use-full-screen-adapt
Steps
Install postcss-pxtorem
bash
npm install -D postcss-pxtorem
Configure Environment Variables
Edit .env
file:
env
# UI design width
VITE_UI_DESIGN_WIDTH = 1280
# UI design height
VITE_UI_DESIGN_HEIGHT = 740
# postcss-pxtorem rootValue
VITE_PXTOREM_ROOTVALUE = 100
Configure postcss-pxtorem
Edit `.postcssrc.cjs
js
// PostCSS plugins
const autoPrefixer = require('autoprefixer')
const pxtorem = require('postcss-pxtorem')
const vite = require('vite')
module.exports = ({ env }) => {
const envObj = vite.loadEnv(env, './')
return {
plugins: [
autoPrefixer(),
pxtorem({
rootValue: Number(envObj.VITE_PXTOREM_ROOTVALUE) || 16, // Root element font size
unitPrecision: 5,
propList: ['*'],
replace: true,
mediaQuery: true,
minPixelValue: 1
})
]
}
}
Implement Dynamic Root Font Size Adjustment
ts
import { useFullScreenAdapt } from 'havue'
// or
import { useFullScreenAdapt } from '@havue/hooks'
// or
import { useFullScreenAdapt } from '@havue/use-full-screen-adapt'
ts
/**
* 根据UI设计尺寸,以及当前屏幕尺寸,计算合适的根元素字体大小 | Calculate the appropriate font size for the root element based on the UI design dimensions and the current screen size
* @param uiWidth UI设计宽度 | UI design width
* @param uiHeight UI设计高度 | UI design height
* @param pxtoremRootValue postcss-pxtorem的rootValue值 | rootValue for postcss-pxtorem
* @param stopOnInput 在input聚焦时,停止计算根元素字体大小,固定页面尺寸 | While inputting focus, stop calculating the root font size and fix the page size
*/
export function useFullScreenAdapt(
uiWidth: number,
uiHeight: number,
pxtoremRootValue: number = 16,
stopOnInput: boolean = false
) {
const docEl = document.documentElement
let isStopAdapt: boolean = false
const stop = () => (isStopAdapt = true)
const resume = () => (isStopAdapt = false)
function setBodyFontSize() {
if (document.body) {
setRemUnit()
if (stopOnInput) {
stopAdaptOnInputFocused(stop, resume)
}
} else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize()
/** 更改根元素字体大小 | Change the root font size */
function setRemUnit() {
if (isStopAdapt) {
return
}
/** UI 设计比例 | UI Design aspect ratio */
const uiRatio = uiWidth / uiHeight
const { clientWidth, clientHeight } = docEl
/** 屏幕宽高比例 | Screen aspect ratio */
const screenRatio = clientWidth / clientHeight
let targetWidth = clientWidth
if (uiRatio > screenRatio) {
const targetHeight = clientWidth / uiRatio
targetWidth = targetHeight * uiRatio
} else {
targetWidth = uiRatio * clientHeight
}
const rem = (targetWidth * pxtoremRootValue) / uiWidth
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
return {
stop,
resume
}
}
/**
* 输入时,暂停根元素字体自适应计算 | When typing, pause the root element font adaptation calculation
* @param onFocus
* @param onBlur
*/
export function stopAdaptOnInputFocused(onFocus: (e?: FocusEvent) => void, onBlur: (e?: FocusEvent) => void) {
const docEl = document.documentElement
let oldBodyWidth: string
let oldBodyHeight: string
docEl.addEventListener(
'focus',
function (e) {
const target = e.target as HTMLElement
if (target.tagName === 'INPUT') {
onFocus()
const { clientWidth, clientHeight } = docEl
oldBodyWidth = docEl.style.width
oldBodyHeight = docEl.style.height
docEl.style.width = `${clientWidth}px`
docEl.style.height = `${clientHeight}px`
}
},
{ capture: true }
)
docEl.addEventListener(
'blur',
function (e) {
const target = e.target as HTMLElement
if (target.tagName === 'INPUT') {
onBlur()
docEl.style.width = oldBodyWidth
docEl.style.height = oldBodyHeight
}
},
{ capture: true }
)
}
Skip this step if already installed.
Use in Entry File (main.ts)
ts
useFullScreenAdapt(Number(import.meta.env.VITE_UI_DESIGN_WIDTH), Number(import.meta.env.VITE_UI_DESIGN_HEIGHT), Number(import.meta.env.VITE_PXTOREM_ROOTVALUE) || 16)