Unit PX adaptation scheme

1. Two plug-in solutions

Methods: Use lib-flexible and PostCSS-Pxtorem plug-ins

lib-flexible

As can be seen from the flexible. Js file of Lib-flexible, its basic principle is to dynamically obtain the width of the screen and change the font size value of the root element when the screen size changes, so that REM units can adapt to the screen.

The main process includes:

  1. Dynamic rewrite<meta>Document-level metadata element tag, where the tag attribute key value pair has
  • Name =” viewPort “tells the browser how to properly render a Web page
  • Content =”width=device-width The string width-device is used to indicate the device width
  • Initial-scale =1 Sets the initial scale value of the page to 100%
  • Maximum-scale =1 allows the user to scale up to 100%
  • Minimum-scale =1 allows the user to scale at a minimum of 100%
  • User-scalable =no Does not allow users to scale
  1. Get the screen width from JS:docEl.getBoundingClientRect().width
  2. to<html>The root element dynamically sets the data-dPR and font size attributes
  3. Listen for page resize and pagesHow events to dynamically change the font size value of the root element
  4. Because rem units are the font size of the root element, elements on a page can be adapted to the screen using REM units
  5. In addition, throughwindow['lib']Cache and expose rem2PX and PX2REM methods.

Therefore, the plugin will automatically set the HTML font size to the width of the screen divided by 10, i.e. 1rem equals the font size of the root HTML node. In daily development, if our design (i.e. the user screen) is 750px wide, then one rem should equal 75px. When the width of an element is 150px, we define the element in CSS width: 2rem. It is worth noting that it stops working when the resolution is greater than a certain value.

For more details, please refer to Flexible for H5 Page Terminal adaptation

postcss-pxtorem

With lib-Flexible, you can scale the screen width and add the font size to the root node. You’ve already adapted the unit PX. However, it is often desirable to automatically convert px units to REM units, since many designs are px units (not necessarily, many cutout designs support switching px/ PT/DP/REM units).

In general, if we want to develop in px units and have the plugin automatically convert to REM units for us to relate to the font size of the root node, we need to use some other methods:

  1. The editor plug-in directly converts input PX units into REM units in a visually visible way. Not recommended. Easy to develop but difficult to maintain.
  2. Use CSS processors such as Sass, Less, and PostCSS to convert automatically at compile time.

Postcss – Pxtorem is a postCSS plug-in with the following configuration

module.exports = {
  plugins: {
    autoprefixer: {},
    'postcss-pxtorem': {
      rootValue: 75.// The font size of the root element
      propList: [The '*'].// Attributes that need to be transformed. * represents all attributes,}}};Copy the code

PostCSS plugin and PostCSS-px2REM, these two plug-ins are the same, but the configuration of the specific details are different.

var px2rem = require('postcss-px2rem');

module.exports = {
  module: {
    loaders: [{test: /\.css$/,
        loader: 'style-loader! css-loader! postcss-loader',}]},postcss: function() {
    return [px2rem({ remUnit: 75})]; }};Copy the code

Deficiencies of the scheme

  1. Two plug-ins may be required, or additional tools may be required to convert design units
  2. The REM unit is essentially a unit relative to the HTML element font, which can have side effects when used for layout

Since viewPort units are compatible with many browsers, lib-flexible is a transition solution that can be abandoned, and there are problems with both current and previous versions. It is recommended that you start using viewPort instead.

2. A plug-in solution (recommended)

Method: Use postCSs-px-to-viewPort plugin

The postCSs-px-to-viewPort plugin uses viewPort instead of lib-flexible. It converts PX directly to vw for adaptation.

PostCSS, by the way, is not strictly a CSS preprocessor, but a tool for converting CSS code with JavaScript tools and plug-ins. It works by taking the style source code and handing it over to the compiler plug-in, and then printing the CSS content. Therefore, you only need to configure the parameters to convert.

The Vue CLI uses PostCSS. You can configure PostCSS via.postcssrc or any of the postCSs-load-config supported configuration sources. Can also through the vue. Config. Js in the CSS. LoaderOptions. Postcss configuration postcss – loader. The original Vue CLI

The first configuration: the.postcssrc file

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      unitToConvert: 'px'.// The unit to convert
      viewportWidth: 375.// Width of UI design draft
      unitPrecision: 5.// The precision of the conversion, i.e. the number of decimal places
      propList: [The '*'].// Specify the unit of the CSS property to be converted. * indicates that all CSS properties are converted
      viewportUnit: 'vw'.// Specify the window unit to convert to, default vw
      fontViewportUnit: 'vw'.// Specify the window unit to convert the font to, default vw
      selectorBlackList: ['wrap'].// Specify the class name that is not converted to window units,
      minPixelValue: 1.// The default value is 1, and the conversion is not performed if the value is less than or equal to 1px
      mediaQuery: true.// Whether the media query is also converted in the CSS code, the default is false
      replace: true.// Whether to replace the attribute value directly after conversion
      exclude: [/node_modules/].// Sets the file to be ignored and the re to match the directory name
      landscape: false.// Whether to handle landscape,}}};Copy the code

The second configuration: the vue.config.js file

module.exports = {
  css: {
    loaderOptions: {
      postcss: {
        plugins: [
          require('postcss-px-to-viewport') ({unitToConvert: 'px'.viewportWidth: 350.unitPrecision: 5.propList: [The '*'].viewportUnit: 'vw'.fontViewportUnit: 'vw'.selectorBlackList: [].minPixelValue: 1.mediaQuery: false.replace: true.exclude: [/node_modules/].include: undefined.landscape: false.landscapeUnit: 'vw'.landscapeWidth: 568,}),],},},},},};Copy the code

3. Manually implement the scheme

Now that you know the principle, you can write a simple version of the adaptation by hand without plug-ins. The following is based on the 750px design draft.

@function px2vw($val) {
  @return ($val/750) * 100vw;
}
html {
  font-size: px2vw(100);
}
Copy the code

The above utilizes the SASS custom Function Directives, px2VW to convert any PX unit to a relative VW. Therefore, we can set the font size of the HTML to px2vw(100), which means that in the document sub-element, each rem represents 100px.

For example, if our design has elements 200px wide and 140px high, we can set width: 2rem and height: 1.4rem to fit the screen.

It is worth noting that the font may be enlarged as the screen enlarges, and we want to have a minimum font and a maximum font so we can add media queries.

@function px2vw($val) {
  @return ($val/750) * 100vw;
}
html {
  font-size: px2vw(100);
  @media screen and (min-width: 320px) {
    font-size: 64px;
  }
  @media screen and (max-width: 540px) {
    font-size: 108px; }}Copy the code

The downside of the solution is that there is still a px to REM conversion process at design time, unless using the editor plug-in or CSS processor mentioned above.