
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
qz-scale-viewport
Advanced tools
移动端设计稿完美缩放适配解决方案 - Perfect scaling solution for mobile design drafts
移动端设计稿完美缩放适配解决方案 - Perfect scaling solution for mobile design drafts
npm install qz-scale-viewport
# 或
yarn add qz-scale-viewport
# 或
pnpm add qz-scale-viewport
<div id="wrapper">
<div id="content">
<!-- 按750px设计稿正常开发 -->
<div class="header" data-scale-sticky>Header</div>
<div class="main">Main Content</div>
<div class="footer" data-scale-fixed>Footer Actions</div>
</div>
</div>
data-scale-sticky 和 data-scale-fixed 适合标记 content 下的直接子元素,用于在缩放场景下稳定支持顶部吸附和底部固定层。
import { createScaleViewport } from 'qz-scale-viewport';
// 获取DOM元素
const wrapper = document.getElementById('wrapper');
const content = document.getElementById('content');
// 创建缩放实例
const scaleViewport = createScaleViewport(
{ content, wrapper },
{
designWidth: 750, // 设计稿宽度
pcWidth: 390, // PC端显示宽度
mobileBreakpoint: 768, // 移动端断点
debug: true // 开启调试日志
}
);
import { ScaleViewport, ScaleViewportConfig, ScaleViewportElements } from 'qz-scale-viewport';
const elements: ScaleViewportElements = {
content: document.getElementById('content') as HTMLElement,
wrapper: document.getElementById('wrapper') as HTMLElement
};
const config: ScaleViewportConfig = {
designWidth: 750,
pcWidth: 390,
mobileBreakpoint: 768,
debug: process.env.NODE_ENV === 'development'
};
const scaleViewport = new ScaleViewport(elements, config);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body, html {
height: 100vh;
overflow-x: hidden;
}
#wrapper {
height: 100vh;
display: flex;
justify-content: center;
align-items: flex-start;
position: relative;
background-color: #f0f0f0;
}
#content {
/* 宽度和缩放由 ScaleViewport 自动设置 */
background-color: white;
}
/* 示例:sticky 定位完美支持 */
.sticky-header {
position: sticky;
top: 0;
background: white;
z-index: 100;
}
.fixed-footer {
position: fixed;
bottom: 0;
width: 100%;
z-index: 100;
}
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
designWidth | number | - | 设计稿宽度(必需) |
pcWidth | number | - | PC端目标显示宽度(必需) |
mobileBreakpoint | number | 768 | 移动端断点,小于等于此值视为移动端 |
debug | boolean | false | 是否启用调试日志 |
| 参数 | 类型 | 说明 |
|---|---|---|
content | HTMLElement | 内容容器元素,设计稿内容的直接容器 |
wrapper | HTMLElement | 外层包装元素,用于居中和定位 |
// 获取当前缩放比例
const scale = scaleViewport.getCurrentScale();
// 获取当前是否为移动端
const isMobile = scaleViewport.isMobile();
// 获取当前视觉宽度
const visualWidth = scaleViewport.getVisualWidth();
// 手动刷新缩放(DOM结构变化时)
scaleViewport.refresh();
// 更新配置
scaleViewport.updateConfig({ pcWidth: 400 });
// 销毁实例
scaleViewport.destroy();
content.addEventListener('scalechange', (event) => {
const { scale, isMobile, visualWidth } = event.detail;
console.log('缩放变化:', { scale, isMobile, visualWidth });
});
<template>
<div ref="wrapper" class="wrapper">
<div ref="content" class="content">
<!-- 按750px设计稿开发 -->
<div class="page">
<header class="header">Header</header>
<main class="main">Content</main>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { createScaleViewport } from 'qz-scale-viewport';
const wrapper = ref();
const content = ref();
let scaleViewport = null;
onMounted(() => {
scaleViewport = createScaleViewport(
{
content: content.value,
wrapper: wrapper.value
},
{
designWidth: 750,
pcWidth: 390,
debug: true
}
);
});
onUnmounted(() => {
scaleViewport?.destroy();
});
</script>
import React, { useRef, useEffect } from 'react';
import { createScaleViewport } from 'qz-scale-viewport';
function App() {
const wrapperRef = useRef();
const contentRef = useRef();
const scaleViewportRef = useRef();
useEffect(() => {
scaleViewportRef.current = createScaleViewport(
{
content: contentRef.current,
wrapper: wrapperRef.current
},
{
designWidth: 750,
pcWidth: 390,
debug: process.env.NODE_ENV === 'development'
}
);
return () => {
scaleViewportRef.current?.destroy();
};
}, []);
return (
<div ref={wrapperRef} className="wrapper">
<div ref={contentRef} className="content">
{/* 按750px设计稿开发 */}
<header>Header</header>
<main>Content</main>
</div>
</div>
);
}
position: sticky 正常工作overflow: auto 滚动正常// 当显示弹窗时禁用内容滚动
function showPopup() {
document.getElementById('content').style.overflow = 'hidden';
// 显示UI库弹窗
showVantPopup();
}
function hidePopup() {
document.getElementById('content').style.overflow = 'auto';
// 隐藏UI库弹窗
hideVantPopup();
}
// 根据用户偏好动态调整PC端宽度
const userPreference = getUserPreference();
scaleViewport.updateConfig({
pcWidth: userPreference.pcWidth || 390
});
A: rem和vw方案会改变字体大小和布局逻辑,而scale方案保持设计稿的原始尺寸,只是视觉缩放,确保100%还原设计稿。
A: 当弹窗显示时,将content的overflow设为hidden,禁用滚动即可解决。
A: 支持,会根据当前视口宽度自动调整缩放比例。
MIT License - 详见 LICENSE 文件
由秦篆 (Qin Zhuan) 用爱发电制作 ✨
个人博客:qinzhuan.top
如果这个库帮到了你,请给个 ⭐️ 支持一下!
FAQs
移动端设计稿完美缩放适配解决方案 - Perfect scaling solution for mobile design drafts
We found that qz-scale-viewport demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.