background

  • Existing equipment
  • The device: 1024 * 768
  • Android Large screen: 1920*1080
  • Vue Version scaffolding CLI2.0
  • Has developed an iPad version that will need to be compatible with larger Android screens

The problem

  • Default to iPad size development, fixed to write px dead.
  • To accommodate different sizes, viewport page compression technology was used to zoom in on the large Android screen
  • As a result of amplification, will lead to part of the picture, buttons appear fluff, or fuzzy situation

The solution

Train of thought

Using REM unit technology, dynamic setting of font size to achieve the compatibility of different devices.

The specific process

  • Use postCSS-PxTOREM dynamic units to convert all px units from the original iPad version to REM version
  • At build time, generate two different versions of rem project according to the specified width parameter
  • The width of the current browser is judged by the home page, and the FONT size of HTML is dynamically set, so that REM dynamically analyzes the corresponding size

disadvantages

  • You need to deploy two sets of environments, so why not just one?
  • Because many of the code styles are written directly in the VUE page, it is not possible to dynamically load different CSS in different environments

Integrate REM flow

Installing a plug-in

npm i postcss-pxtorem -D
Copy the code

configuration

  • Since the postCSS is integrated, only.postcssrc.js needs to be configured

.postcssrc.js

//.postcssrc.js 
// This parameter is not set by default
console.log("process.env.BUILD_DEVICE----",process.env.BUILD_DEVICE)
const deviceWidth = (process.env.BUILD_DEVICE == "bigScreen")?130:98
console.log("deviceWidth----",deviceWidth)
module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {},
    / / note
    // Android large screen uses 1092 * 1080, need to set 130
    // Note that the size of the costume is 1024*768, you need to set 98
    "postcss-pxtorem": {
      rootValue: deviceWidth,
      unitPrecision: 5.propList: [The '*'].selectorBlackList: [].replace: true.mediaQuery: false.minPixelValue: 12,}}}Copy the code

package.json

//package.json
// Start the project add BUILD_DEVICE device type iPad and bigScreen
 "build-dev": "cross-env RUN_TYPE=build BUILD_TYPE=dev BUILD_DEVICE=ipad npm run webpack-build"."build-dev-bigScreen": "cross-env RUN_TYPE=build BUILD_TYPE=dev BUILD_DEVICE=bigScreen npm run webpack-build".Copy the code

Webpack.base.conf.js // Add parameters to the mapping

 plugins: [
    new webpack.DefinePlugin({
      'process.env.BUILD_DEVICE':JSON.stringify(process.env.BUILD_DEVICE),
    }),
  ],
  Process.env.build_device = process.env.build_device = process.env.build_device
Copy the code

Use Flexible to dynamically calculate the font-size value corresponding to the current REM

//rem.js
// Each time the page zooms in and out, the load will recalculate the corresponding font size to affect the corresponding REM value
(function flexible (window.document) {
    var docEl = document.documentElement
    var dpr = window.devicePixelRatio || 1
  
    // adjust body font size
    function setBodyFontSize () {
      if (document.body) {
        document.body.style.fontSize = (12 * dpr) + 'px'
      }
      else {
        document.addEventListener('DOMContentLoaded', setBodyFontSize)
      }
    }
    setBodyFontSize();
  
    // set 1rem = viewWidth / 10
    function setRemUnit () {
      var rem = docEl.clientWidth / 10
      docEl.style.fontSize = rem + 'px'
    }
  
    setRemUnit()
  
    // reset rem unit on page resize
    window.addEventListener('resize', setRemUnit)
    window.addEventListener('pageshow'.function (e) {
      if (e.persisted) {
        setRemUnit()
      }
    })
  
    / / detect 0.5 px supports
    if (dpr >= 2) {
      var fakeBody = document.createElement('body')
      var testElement = document.createElement('div')
      testElement.style.border = '.5px solid transparent'
      fakeBody.appendChild(testElement)
      docEl.appendChild(fakeBody)
      if (testElement.offsetHeight === 1) {
        docEl.classList.add('hairlines')
      }
      docEl.removeChild(fakeBody)
    }
  }(window.document))
Copy the code

Index.html into rem. Js

<! DOCTYPEhtml>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = 0">
    <meta http-equiv="pragram" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
    <meta http-equiv="Expires" content="0">
    <title>XXXX</title>
  </head>
  <body>
    <div id="app"></div> 
    <script src="http://xxxxxxx:17280/commonJS/rem.js"></script>
  </body>
</html>
Copy the code