📱 响应式与移动端适配
媒体查询、rem/vw 方案、1px 问题的可交互演示
1. 媒体查询与断点
大屏设备 (≥1201px)
2. rem 响应式方案
计算公式: fontSize = (clientWidth / 750) × 100
转换规则: 设计稿 100px = 1rem
宽度: 3.5rem (设计稿 350px)
宽度: 5rem (设计稿 500px)
字体: 0.28rem (设计稿 28px)
function setRem() {
const designWidth = 750;
const clientWidth = document.documentElement.clientWidth;
const rem = (clientWidth / designWidth) * 100;
document.documentElement.style.fontSize = rem + 'px';
}
window.addEventListener('resize', setRem);
setRem();
.box {
width: 3.5rem;
font-size: 0.28rem;
}
3. vw 响应式方案 (推荐)
转换公式: 1px = (100 / 750)vw ≈ 0.1333vw (基于 750px 设计稿)
优势: 无需 JS 计算,纯 CSS 实现,性能更好
宽度: 50vw = 视口宽度的 50%
宽度: 30vw
字体: 3vw
.box {
width: 46.67vw;
padding: 2.67vw;
font-size: 3.73vw;
}
module.exports = {
plugins: {
'postcss-px-to-viewport': {
viewportWidth: 750,
unitPrecision: 5,
minPixelValue: 1
}
}
};
4. 移动端 1px 边框问题
问题: 在 Retina 屏 (DPR=2/3) 上,1px 的 CSS 像素会被渲染为 2px/3px 的物理像素,看起来很粗
解决方案: transform: scale、伪元素、border-image、box-shadow
普通 1px 边框
border: 1px solid
transform: scale 方案
0.5px 边框效果
伪元素方案
更精确的 1px 效果
box-shadow 方案
box-shadow: 0 0 0 1px
.border-1px {
position: relative;
}
.border-1px::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
border: 1px solid #333;
transform: scale(0.5);
transform-origin: 0 0;
}
.border-1px {
box-shadow: 0 0 0 1px #333;
}
@media (-webkit-min-device-pixel-ratio: 2) {
.border-1px::after {
transform: scale(0.5);
}
}
@media (-webkit-min-device-pixel-ratio: 3) {
.border-1px::after {
width: 300%;
height: 300%;
transform: scale(0.333);
}
}
5. 响应式单位对比
| 单位 |
说明 |
使用场景 |
| px |
绝对单位 |
固定尺寸元素 |
| % |
相对父元素 |
容器尺寸 |
| rem |
相对根元素 font-size |
整体缩放 (需 JS) |
| em |
相对当前元素 font-size |
组件内部间距 |
| vw/vh |
视口宽度/高度的 1% |
响应式布局 (推荐) |
| vmin/vmax |
vw 和 vh 中较小/大值 |
保持纵横比 |