Skip to content

Mobile Adaptation Best Practices ​

Professional mobile adaptation solutions to ensure Vant applications render perfectly on various devices.

Goal: make your UI look great from 320px to large phones—without hacks.

📱 Viewport Configuration ​

Basic Viewport Setup ​

The first step in mobile adaptation is correctly configuring the viewport.

html
<!-- Standard viewport configuration -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Parameter Description:

  • width=device-width: Viewport width equals device screen width
  • initial-scale=1.0: Initial zoom ratio is 1, no scaling
  • maximum-scale=1.0: Maximum zoom ratio is 1
  • user-scalable=no: Disable manual scaling by users

Dynamic Viewport Adjustment ​

javascript
// Dynamic viewport setting
function setViewport() {
  const viewport = document.querySelector('meta[name="viewport"]')
  const scale = 1 / window.devicePixelRatio
  
  if (viewport) {
    viewport.content = `width=device-width, initial-scale=${scale}, maximum-scale=${scale}, user-scalable=no`
  }
}

// Set on page load
window.addEventListener('load', setViewport)

// Reset on screen rotation
window.addEventListener('orientationchange', () => {
  setTimeout(setViewport, 100)
})

📐 Size Adaptation Solutions ​

1. Rem Adaptation Solution ​

Based on relative units of root element font size, this is currently the most mainstream mobile adaptation solution.

Install Dependencies:

bash
npm install postcss-pxtorem lib-flexible -S

PostCSS Configuration:

javascript
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 37.5, // Design width/10 (375/10)
      unitPrecision: 5, // rem precision to 5 decimal places
      propList: ['*'], // Convert all properties
      selectorBlackList: ['.van-'], // Ignore vant components
      replace: true,
      mediaQuery: false,
      minPixelValue: 2 // Don't convert values less than 2px
    }
  }
}

Import flexible:

javascript
// main.js
import 'lib-flexible'

// Or set manually
function setRem() {
  const baseSize = 37.5 // Base size
  const scale = document.documentElement.clientWidth / 375
  document.documentElement.style.fontSize = Math.min(scale * baseSize, 54) + 'px'
}

setRem()
window.addEventListener('resize', setRem)

2. Vw Adaptation Solution ​

Based on CSS viewport width units, more precise and modern.

Install Dependencies:

bash
npm install postcss-px-to-viewport-8-plugin -D

PostCSS Configuration:

javascript
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport-8-plugin': {
      viewportWidth: 375, // Design width
      viewportHeight: 667, // Design height
      unitPrecision: 3, // Decimal places after conversion
      viewportUnit: 'vw', // Viewport unit to convert to
      selectorBlackList: ['.ignore', '.hairlines'], // Class names not to convert
      minPixelValue: 1, // Don't convert values less than 1px
      mediaQuery: false, // Don't convert in media queries
      exclude: [/node_modules/] // Exclude node_modules
    }
  }
}

3. Responsive Solution ​

Traditional responsive design based on CSS media queries.

css
/* Breakpoint system */
/* Mobile */
@media (max-width: 767px) {
  .container {
    padding: 16px;
    font-size: 14px;
  }
}

/* Tablet */
@media (min-width: 768px) and (max-width: 1023px) {
  .container {
    padding: 24px;
    font-size: 16px;
  }
}

/* Desktop */
@media (min-width: 1024px) {
  .container {
    padding: 32px;
    font-size: 18px;
    max-width: 1200px;
    margin: 0 auto;
  }
}

🎨 Vant Component Adaptation ​

CSS Variable Customization ​

css
/* Mobile-optimized Vant variables */
:root {
  /* Font sizes */
  --van-font-size-xs: 10px;
  --van-font-size-sm: 12px;
  --van-font-size-md: 14px;
  --van-font-size-lg: 16px;
  
  /* Spacing system */
  --van-padding-xs: 8px;
  --van-padding-sm: 12px;
  --van-padding-md: 16px;
  --van-padding-lg: 24px;
  
  /* Component heights */
  --van-button-default-height: 44px;
  --van-cell-line-height: 24px;
  --van-nav-bar-height: 46px;
}

/* Small screen adaptation (< 375px) */
@media (max-width: 374px) {
  :root {
    --van-font-size-md: 13px;
    --van-padding-md: 14px;
    --van-button-default-height: 40px;
  }
}

/* Large screen adaptation (> 414px) */
@media (min-width: 415px) {
  :root {
    --van-font-size-md: 15px;
    --van-padding-md: 18px;
    --van-button-default-height: 48px;
  }
}

Component Size Adaptation ​

vue
<template>
  <div class="mobile-layout">
    <!-- Button group adaptation -->
    <div class="button-group">
      <van-button size="small">Small Button</van-button>
      <van-button size="normal">Normal Button</van-button>
      <van-button size="large">Large Button</van-button>
    </div>
    
    <!-- Grid layout adaptation -->
    <van-grid :column-num="gridColumns" :gutter="16">
      <van-grid-item v-for="item in 4" :key="item" :text="`Grid ${item}`" />
    </van-grid>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'

const screenWidth = ref(window.innerWidth)

// Responsive grid columns
const gridColumns = computed(() => {
  if (screenWidth.value < 375) return 2
  if (screenWidth.value < 414) return 3
  return 4
})

// Listen to screen size changes
const handleResize = () => {
  screenWidth.value = window.innerWidth
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})
</script>

📏 1px Border Solutions ​

Transform Scale Solution ​

css
/* Full border */
.hairline-border {
  position: relative;
}

.hairline-border::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 200%;
  border: 1px solid #ebedf0;
  transform: scale(0.5);
  transform-origin: 0 0;
  pointer-events: none;
  box-sizing: border-box;
}

/* Single border */
.hairline-top::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: #ebedf0;
  transform: scaleY(0.5);
  transform-origin: 0 0;
}

Box-shadow Solution ​

css
/* Use box-shadow to simulate borders */
.shadow-border {
  box-shadow: 0 0 0 0.5px #ebedf0 inset;
}

.shadow-border-bottom {
  box-shadow: 0 -0.5px 0 0 #ebedf0 inset;
}

🔧 Performance Optimization ​

Image Adaptation ​

html
<!-- Responsive images -->
<img 
  srcset="image@1x.jpg 1x, image@2x.jpg 2x, image@3x.jpg 3x" 
  src="image@1x.jpg" 
  alt="Responsive image"
>

<!-- Vant lazy loading -->
<van-image
  v-lazy="imageUrl"
  :width="100"
  :height="100"
  fit="cover"
/>

Touch Optimization ​

css
/* Touch feedback optimization */
.touch-element {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Scroll optimization */
.scroll-container {
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
}

/* Prevent page zoom */
.no-zoom {
  touch-action: manipulation;
}

📱 Device Compatibility ​

Common Device Breakpoints ​

Device TypeScreen WidthAdaptation Points
iPhone SE320pxMinimum width, compact layout
iPhone 12390pxMainstream size, standard layout
iPhone 12 Pro Max428pxLarge screen, spacious layout
Android Mainstream360pxUniversal adaptation size

Safe Area Adaptation ​

css
/* iOS notch adaptation */
.safe-area-top {
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
}

.safe-area-bottom {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

/* Full safe area */
.safe-area-full {
  padding: 
    env(safe-area-inset-top) 
    env(safe-area-inset-right) 
    env(safe-area-inset-bottom) 
    env(safe-area-inset-left);
}

🧪 Testing and Debugging ​

  1. Chrome DevTools

    • Device simulator
    • Responsive design mode
    • Network throttling test
  2. vConsole

    javascript
    // Mobile device debugging
    import VConsole from 'vconsole'
    
    if (process.env.NODE_ENV === 'development') {
      new VConsole()
    }
  3. Lighthouse

    • Mobile performance analysis
    • User experience evaluation
    • Best practice recommendations

Testing Checklist ​

  • [ ] Viewport configuration correct
  • [ ] Font size appropriate (minimum 12px)
  • [ ] Touch targets large enough (minimum 44px)
  • [ ] Portrait/landscape switching normal
  • [ ] 1px borders display correctly
  • [ ] Images load and display normally
  • [ ] Smooth scrolling performance
  • [ ] Complete safe area adaptation

💡 Best Practices Summary ​

  1. Choose appropriate adaptation solution: Recommend using Rem or Vw solutions
  2. Set reasonable viewport: Ensure correct viewport configuration
  3. Optimize touch experience: Set appropriate touch target sizes
  4. Handle 1px borders: Use transform or box-shadow solutions
  5. Test multiple devices: Ensure normal display on different devices
  6. Performance optimization: Reasonable use of image lazy loading and touch optimization

Through the above solutions, you can ensure that Vant applications provide excellent user experience on various mobile devices.


  • Getting Started: ./getting-started
  • Performance Optimization: ./performance-optimization
  • Theme Customization: ./theme-customization
  • TypeScript Guide: ./typescript-guide
  • Vue 3 Integration: ./vue3-integration
  • Components: ../products/
  • Contact & FAQ: ../contact/

Enterprise-level mobile solution based on Vant