Skip to content

多端适配方案

概述

多端适配是指让应用能够在不同设备、不同平台、不同屏幕尺寸上正常运行,提供一致的用户体验。

响应式设计

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 平台')
// #endif

2. 平台判断

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);
}

相关资源

基于 VitePress 的本地知识库