Appearance
多端适配方案
概述
多端适配是指让应用能够在不同设备、不同平台、不同屏幕尺寸上正常运行,提供一致的用户体验。
响应式设计
1. 媒体查询
css
/* 移动端优先 */
.container {
width: 100%;
padding: 16px;
}
/* 平板 */
@media (min-width: 768px) {
.container {
width: 750px;
margin: 0 auto;
}
}
/* 桌面 */
@media (min-width: 1024px) {
.container {
width: 960px;
}
}
/* 大屏 */
@media (min-width: 1440px) {
.container {
width: 1200px;
}
}2. Flexbox 布局
css
.container {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.item {
flex: 1 1 300px; /* 最小宽度 300px */
max-width: 100%;
}3. Grid 布局
css
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 16px;
}移动端适配
1. Viewport 设置
html
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
>2. rem 适配方案
javascript
// 设置根元素字体大小
function setRem() {
const baseSize = 16
const designWidth = 375
const clientWidth = document.documentElement.clientWidth
const scale = clientWidth / designWidth
document.documentElement.style.fontSize = baseSize * scale + 'px'
}
window.addEventListener('resize', setRem)
setRem()3. vw/vh 方案
css
/* 设计稿宽度 375px */
.element {
width: 375px; /* 设计稿尺寸 */
width: 100vw; /* 视口宽度 */
font-size: 16px;
font-size: 4.267vw; /* 16 / 375 * 100 */
}4. PostCSS 插件
javascript
// postcss.config.js
module.exports = {
plugins: {
'postcss-px-to-viewport': {
viewportWidth: 375,
viewportHeight: 667,
unitPrecision: 5,
viewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false
}
}
}跨平台开发
1. Uni-app
vue
<template>
<view class="container">
<text>{{ message }}</text>
</view>
</template>
<script>
export default {
data() {
return {
message: 'Hello Uni-app'
}
}
}
</script>
<style>
.container {
padding: 20rpx;
}
</style>2. Taro
jsx
import { View, Text } from '@tarojs/components'
function Index() {
return (
<View className="container">
<Text>Hello Taro</Text>
</View>
)
}3. React Native
jsx
import { View, Text, StyleSheet } from 'react-native'
function App() {
return (
<View style={styles.container}>
<Text>Hello React Native</Text>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})平台差异处理
1. 条件编译
javascript
// #ifdef H5
console.log('H5 平台')
// #endif
// #ifdef MP-WEIXIN
console.log('微信小程序')
// #endif
// #ifdef APP-PLUS
console.log('App 平台')
// #endif2. 平台判断
javascript
function getPlatform() {
const ua = navigator.userAgent
if (/MicroMessenger/i.test(ua)) {
return 'wechat'
}
if (/Android/i.test(ua)) {
return 'android'
}
if (/iPhone|iPad|iPod/i.test(ua)) {
return 'ios'
}
return 'pc'
}3. 样式适配
scss
@mixin mobile {
@media (max-width: 768px) {
@content;
}
}
@mixin tablet {
@media (min-width: 769px) and (max-width: 1024px) {
@content;
}
}
@mixin desktop {
@media (min-width: 1025px) {
@content;
}
}
.container {
padding: 16px;
@include mobile {
padding: 8px;
}
@include tablet {
padding: 12px;
}
}最佳实践
1. 设计原则
- 移动优先设计
- 渐进增强
- 优雅降级
2. 性能优化
- 图片懒加载
- 按需加载资源
- 使用 CDN 加速
- 压缩资源文件
3. 用户体验
- 触摸友好的交互
- 合理的字体大小
- 适当的点击区域
- 流畅的动画效果
常见问题
如何处理 1px 边框问题?
css
.hairline {
position: relative;
}
.hairline::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
background: #ddd;
transform: scaleY(0.5);
transform-origin: 0 0;
}如何处理安全区域?
css
.container {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}