前端vw自适应解决方案,适用pc端以及移动端,适用webpack以及vite,适用vue以及react

前端自适应的终终终终终及解决方案,适用pc端以及移动端,适用webpack以及vite

前言

随着vw被越来越多的浏览器所支持,rem的自适应方案渐渐退出历史舞台,风靡一时的淘宝自适应解决方案lib-flexible也已被弃用。
接下来我们详细介绍一下如何通过打包配置,使得vw自适应的方案能一把梭所有的前端项目(vue\react\webpack\vite)

依赖

npm i postcss cssnano cssnano-preset-advanced postcss-aspect-ratio-mini postcs-preset-env postcss-import postcss-url postcss-px-to-viewport postcss-viewport-units postcss-write-svg -D
npm i viewport-units-buggyfill -S
"postcss": "^8.4.18", // postcss扮演一个框架的角色,是一个用javaScript工具和插件转换css代码的工具。postcss将css转换为javaScript可以操作的数据结构。这些数据可以由插件理解和转换,然后处理成各种需要的格式。其本身不对css进行处理,但是通过在该平台上集成插件,如cssnano、postcss-px-to-viewport等,就可以实现对css的处理和操作
"postcss-preset-env": "^7.8.2", // 是一个postcss插件,帮助您使用最新的css语法,它将新的css规范转换为更兼容的css,所以你不需要等待浏览器的支持。(之前同功能的postcss-cssnext插件被废弃, 推荐用postcss-preset-env)
"cssnano": "^5.1.13", // cssnano是构建于postcss的插件和生态之上的,主要用来压缩和清理css代码,确保最终生成的文件 对生产环境来说体积是最小的
"cssnano-preset-advanced": "^5.3.8", // cssnano的高级优化
"postcss-aspect-ratio-mini": "^1.1.0", // 主要用来处理元素容器的固定宽高比
"postcss-import": "^15.0.0", // 主要功有是解决@import引入路径问题。使用这个插件,可以让你很轻易的使用本地文件、node_modules或者web_modules的文件。这个插件配合postcss-url让你引入文件变得更轻松
"postcss-url": "^10.1.3", // 该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理。
"postcss-px-to-viewport": "^1.1.1", // 自适应的关键所在,将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的postcss插件.如果你的样式需要做根据视口大小来调整宽度,这个脚本可以将你css中的px单位转化为vw,1vw等于1/100视口宽度。
"postcss-viewport-units": "^0.1.6", // 插件主要是给css的属性添加content的属性,配合viewport-units-buggyfill库兼容一些不支持 vw、vh、vmax、vmin 这些 viewport 单位的浏览器所使用的。
"viewport-units-buggyfill": "^0.6.2", // 配合postcss-viewport-units兼容一些不支持 vw、vh、vmax、vmin 这些 viewport 单位的浏览器
"postcss-write-svg": "^3.0.1", // 这个库可以让你直接在css中写svg,也是处理移动端1px的解决方案,该插件主要使用的是border-image和background来做1px的相关处理
  1. postcss: postcss扮演一个框架的角色,是一个用javaScript工具和插件转换css代码的工具。postcss将css转换为javaScript可以操作的数据结构。这些数据可以由插件理解和转换,然后处理成各种需要的格式。其本身不对css进行处理,但是通过在该平台上集成插件,如cssnanopostcss-px-to-viewport等,就可以实现对css的处理和操作

  2. postcss-preset-env: 是一个postcss插件,帮助您使用最新的css语法,它将新的css规范转换为更兼容的css,所以你不需要等待浏览器的支持。(之前同功能的postcss-cssnext插件被废弃, 推荐用postcss-preset-env

  3. cssnano: cssnano是构建于postcss的插件和生态之上的,主要用来压缩和清理css代码,确保最终生成的文件 对生产环境来说体积是最小的

    注意

    1. 我们需要使用cssnano-preset-advanced让cssnano的特性支持最新的css特性,所以我们需要配置cssnano的预设,即cssnano-preset-advanced
    2. 由于cssnano-preset-advanced和cssnano都具有autoprefixer,事实上只需要一个即可,避免重复处理,所以把cssnano中的autoprefixer设置为false。
    3. z-index会被cssnano重新计算为1,这个巨坑,会导致之后设置z-index出现各种问题,所以需要禁用cssnano的zindex
    cssnano({
          
           // cssnano 是构建于 postcss 的插件和生态之上的,主要用来压缩和清理CSS代码,确保最终生成的文件对生产环境来说体积是最小的
      preset: [
        cssnanoPresetAdvanced,  // cssnano-preset-advanced是cssnano的高级优化
      	{
          
          
      	  autoprefixer: false, // 由于cssnano-preset-advanced和cssnano都具有autoprefixer,事实上只需要一个即可,避免重复处理,所以把cssnano中的autoprefixer设置为false。
      	  zindex: false // z-index会被cssnano重新计算为1,这个巨坑,会导致之后设置z-index出现各种问题,所以需要禁用cssnano的zindex
      	}
      ],
    })
    
  4. cssnano-preset-advanced: cssnano的高级优化

  5. postcss-aspect-ratio-mini: 主要用来处理元素容器的固定宽高比

    <div>
      <div className={styles.exampleItemTitle}>使用postcss-aspect-ratio-mini处理元素的尺寸固定为纵横比(宽高比)</div>
      <div className={styles.postcssAspectRatioMiniExample}>
        <img src={aaa} alt="" />
      </div>
    </div>
    
    .postcssAspectRatioMiniExample {
          
          
      width: 188px;
      height: 188px;
      border: 1px solid #000;
      position: relative;
      aspect-ratio: 1/1; /*使用postcss-aspect-ratio-mini来处理元素容器的固定宽高比。加上它有神奇的力量*/
    }
    
    .postcssAspectRatioMiniExample img {
          
          
      max-width:100%;
      max-height:100%;
      border: 1px solid #000;
      /*aspect-ratio: 16/9;*/
    }
    

    在这里插入图片描述

  6. postcss-import: 主要功有是解决@import引入路径问题。使用这个插件,可以让你很轻易的使用本地文件、node_modules或者web_modules的文件。这个插件配合postcss-url让你引入文件变得更轻松

    扫描二维码关注公众号,回复: 14626864 查看本文章
  7. postcss-url: 该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理。

  8. postcss-px-to-viewport: 自适应的关键所在,将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的postcss插件.如果你的样式需要做根据视口大小来调整宽度,这个脚本可以将你css中的px单位转化为vw,1vw等于1/100视口宽度。
    常用配置如下:

    postcssPxToViewport({
          
           // 实现px自动转vw实现自适应的关键插件,可以将px单位转换为视口单位的 (vw, vh, vmin, vmax) 
      viewportWidth: 1920, // 视口宽度,对应UI设计稿的视窗宽度
      viewporHeight: 1080, // 视口高度,对应UI设计稿的视窗高度
      unitToConvert: 'px',    // 需要转换的单位,默认为"px"
      viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
      fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
      unitPrecision: 6, // 指定px转换之后的精度,即小数点位数
      selectorBlackList: ['.ignore', '.hairlines'], // 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位
      exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
      // include: /\/src\//,     // 如果设置了include,那将只有匹配到的文件才会被转换 (exclude和include设置一个就行了)
      replace: true, //  是否转换后直接更换属性值,而不添加备用属性
      minPixelValue: 1, // 设置最小的转换数值,默认值1,小于或等于1px则不进行转换
      mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
      propList: ['*'], // 指定能转化为 vw 的css属性列表,*代表全部css属性的单位都进行转换
      // propList: ['*', '!font-size'],
      landscape: false,       // 是否根据 landscapeWidth 生成的媒体查询条件,处理横屏情况
      // landscapeUnit: 'vw',    // 横屏时使用的单位
      // landscapeWidth: 1125,   // 横屏时使用的视窗宽度
    }),
    
  9. postcss-viewport-units: 插件主要是给css的属性添加content的属性,配合viewport-units-buggyfill库兼容一些不支持 vw、vh、vmax、vmin 这些 viewport 单位的浏览器所使用的。

    需要注意的是: 当有元素的伪类使用了content的时候,会出现如下报错:
    xxx::before already has a ‘content’ property, give up to overwrite it
    在这里插入图片描述
    这时候我们就需要配置一下postcss-viewport-units的过滤规则,让其忽略伪类,不对伪类添加content属性

    postcssViewportUnits({
          
          
       filterRule: rule => rule.selector.includes('::after') && rule.selector.includes('::before') && rule.selector.includes(':after') && rule.selector.includes(':before'), // 解决有伪类使用content报错 already has a ‘content’ property, give up to overwrite it.
    }),
    
  10. viewport-units-buggyfill: 配合postcss-viewport-units兼容一些不支持 vw、vh、vmax、vmin 这些 viewport 单位的浏览器

    postcss-viewport-units与viewport-units-buggyfill的工作原理:
    postcss-viewport-units自动添加content属性, viewport-units-buggyfill再把根据content里的数据把vw单位转为px单位, 如下图
    在这里插入图片描述

    viewport-units-buggyfill的使用:
    viewport-units-buggyfill不属于postcss插件,因此不能在postcss的plugins中进行配置,它需要单独的引入,如下:

    • 方法1:
      如果不是npm的方式安装viewport-units-buggyfill,那么需要在index.html的head 中引入 viewport-units-buggyfill ,并在body 中配置
    <head>
        <script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
    </head>
    
    <body>
    <script>
    	window.onload = function () {
            
            
    		window.viewportUnitsBuggyfill.init({
            
            
    			hacks: window.viewportUnitsBuggyfillHacks
    		});
    	}
    </script>
    <body>
    
    
    • 方法2:
      如果是npm的方式安装了viewport-units-buggyfill
    npm install viewport-units-buggyfill -S
    

    那么需要在项目的入口文件中(比如 main.js),引入

    var hacks = require('viewport-units-buggyfill/viewport-units-buggyfill.hacks');
    require('viewport-units-buggyfill').init({
          
          
      hacks: hacks
    });
    

    viewport-units-buggyfill的兼容问题:
    使用了viewport-units-buggyfill后,它会占用content属性,因此会或多或少的造成一些副作用。如img元素和伪元素的使用::before 或::after。
    对于img,在部分浏览器中,content的写入会造成图片无法正常展示,这时候需要全局添加样式覆盖:

    /* 解决使用了viewport-units-buggyfill的img兼容问题 */
    	img {
          
          
    		content: normal !important;
    	}
    
  11. postcss-write-svg: 这个库可以让你直接在css中写svg,也是处理移动端1px的解决方案,该插件主要使用的是border-image和background来做1px的相关处理
    利用postcss-write-svg实现css中写1px直线的svg示例如下:

    /*1px示例*/
    /*使用postcss-write-svg绘制1px(仅限直线)*/
    @svg square {
          
          
      height: 1px;
      @rect {
          
          
        fill: var(--color, white);
        width: 100%;
        height: 50%;
      }
    }
    /*background的形式*/
    .onePxLineByPostcssWriteSvgExample {
          
          
      width: 100%;
      height: 20px;
      background: white svg(square param(--color red));
      background-size: 100% 1px;
      background-repeat: no-repeat;
      background-position: bottom left;
    }
    
    /*border-image的形式*/
    /*
    .onePxLineByPostcssWriteSvgExample {
      width: 100%;
      height: 20px;
      border-bottom: 1px solid transparent;
      border-image: svg(square param(--color $navbar-border-color)) 2 2 stretch;
    }
    */
    
  12. autoprefixer: 是用来自动处理浏览器前缀的一个插件。如果你配置了postcss-cssnext或者postcss-preset-env,其中就已具备了autoprefixer的功能,不需要再额外安装。在配置的时候,未显示的配置相关参数的话,表示使用的是Browserslist指定的列表参数,你也可以项目根目录创建.browserslistrc文件来指定last 2 versions 或者 > 5%,如下:
    .browserslistrc

    > 1%
    last 2 versions
    

    在这里插入图片描述
    如此一来,你在编码时不再需要考虑任何浏览器前缀的问题,可以专心撸码。这也是postcss最常用的一个插件之一。

备注:

  1. 实现自适应最主要的功能实际只需要postcss、postcss-px-to-viewport,其他依赖只是锦上添花或者是为了解决兼容问题,可根据自身情况选择是否安装
  2. 本文主要介绍配置自适应所需要的插件,其他插件如处理less的less和less-loader等插件,自行研究和下载

配置vite或者webpack打包工具

  • vite
    vite.config.js

    import {
          
           defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import path from 'path';
    // 自适应所需的插件
    // vite不支持require的引入方式,但是vite.config.js 即使不是es模块,也可以在里面使用impor,因为vite内部会自动转译
    import postcssPresetEnv from 'postcss-preset-env';
    import postcssImport from 'postcss-import';
    import postcssUrl from 'postcss-url';
    import postcssAspectRatioMini from 'postcss-aspect-ratio-mini';
    import postcssWriteSvg from 'postcss-write-svg';
    import postcssPxToViewport from 'postcss-px-to-viewport';
    import cssnano from 'cssnano';
    import cssnanoPresetAdvanced from 'cssnano-preset-advanced';
    import postcssViewportUnits from 'postcss-viewport-units';
    
    // https://vitejs.dev/config/
    export default defineConfig({
          
          
      plugins: [react()],
      css: {
          
          
        // css预处理器
        preprocessorOptions: {
          
          
          less: {
          
          
            charset: false,
            additionalData: '@import "./src/assets/style/global.less";',
            javascriptEnabled: true,
          },
        },
        // 自适应
        postcss: {
          
          
          plugins: [
            postcssPresetEnv, // 是一个postcss插件,帮助您使用最新的css语法,它将新的css规范转换为更兼容的css,所以你不需要等待浏览器的支持。(之前同功能的postcss-cssnext插件被废弃, 推荐用postcss-preset-env)
            postcssImport, // 主要功能是解决@import引入路径问题。使用这个插件,可以让你很轻松地使用本地文件、node_modules或者web_modules的文件。这个插件配合postcss-url让你引入文件变得更轻松
            postcssUrl, // 该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理
            postcssAspectRatioMini, // 主要用来处理元素大小固定为宽高比,通常用于img等元素上
            postcssWriteSvg({
          
           utf8: false }), // 这个插件可以让你直接在CSS中写svg,需要配合postcss一起用,我们可以利用这个插件,使用border-image和background来做1px的相关处理,解决移动端的1px问题,但仅适合直线(有圆角的建议用transform配合伪类实现)
            postcssPxToViewport({
          
           // 实现px自动转vw实现自适应的关键插件,可以将px单位转换为视口单位的 (vw, vh, vmin, vmax) 
              viewportWidth: 1920, // 视口宽度,对应UI设计稿的视窗宽度
              viewporHeight: 1080, // 视口高度,对应UI设计稿的视窗高度
              unitToConvert: 'px',    // 需要转换的单位,默认为"px"
              viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
              fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
              unitPrecision: 6, // 指定px转换之后的精度,即小数点位数
              selectorBlackList: ['.ignore', '.hairlines'], // 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位
              exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
              // include: /\/src\//,     // 如果设置了include,那将只有匹配到的文件才会被转换 (exclude和include设置一个就行了)
              replace: true, //  是否转换后直接更换属性值,而不添加备用属性
              minPixelValue: 1, // 设置最小的转换数值,默认值1,小于或等于1px则不进行转换
              mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
              propList: ['*'], // 指定能转化为 vw 的css属性列表,*代表全部css属性的单位都进行转换
              // propList: ['*', '!font-size'],
              landscape: false,       // 是否根据 landscapeWidth 生成的媒体查询条件,处理横屏情况
              // landscapeUnit: 'vw',    // 横屏时使用的单位
              // landscapeWidth: 1125,   // 横屏时使用的视窗宽度
            }),
            postcssViewportUnits({
          
           // 插件主要是给css的属性添加content的属性,配合viewport-units-buggyfill库兼容一些不支持 vw、vh、vmax、vmin 这些 viewport 单位的浏览器所使用的。
              filterRule: rule => rule.selector.includes('::after') && rule.selector.includes('::before') && rule.selector.includes(':after') && rule.selector.includes(':before'), // 解决有伪类使用content报错 already has a ‘content’ property, give up to overwrite it.
            }),
            cssnano({
          
           // cssnano 是构建于 postcss 的插件和生态之上的,主要用来压缩和清理CSS代码,确保最终生成的文件对生产环境来说体积是最小的
              preset: [
                cssnanoPresetAdvanced, // cssnano-preset-advanced是cssnano的高级优化
                {
          
          
                  autoprefixer: false, // 由于cssnano-preset-advanced和cssnano都具有autoprefixer,事实上只需要一个即可,避免重复处理,所以把cssnano中的autoprefixer设置为false。
                  zindex: false // z-index会被cssnano重新计算为1,这个巨坑,会导致之后设置z-index出现各种问题,所以需要禁用cssnano的zindex
                }
              ],
            })
          ]
        }
      },
      resolve: {
          
          
        alias: {
          
          
          '@': path.resolve(__dirname, './src')
        }
      }
    })
    
    

    main.js

    import hacks from 'viewport-units-buggyfill/viewport-units-buggyfill.hacks';
    import viewportUnitsBuggyfill from 'viewport-units-buggyfill';
    
    // viewport-units-buggyfill
    viewportUnitsBuggyfill.init({
          
          
      hacks: hacks
    });
    
    

    main.css

    /* 使用了viewport-units-buggyfill后,它会占用content属性,因此会或多或少的造成一些副作用。如img元素和伪元素的使用::before 或::after。*/
    /* 对于img,在部分浏览器中,content的写入会造成图片无法正常展示,这时候需要全局添加样式覆盖:*/
    img {
          
          
      content: normal !important;
    }
    
  • webpack
    webpack.config.js

    // 引入插件
    // 引入postCss插件
    const postcssPresetEnv = require('postcss-preset-env');
    const postcssAspectRatioMini = require('postcss-aspect-ratio-mini');
    const postcssPxToViewport = require('postcss-px-to-viewport-opt');
    const postcssWriteSvg = require('postcss-write-svg');
    const postcssPresetEnv = require('postcss-preset-env');
    const postcssViewportUnits = require('postcss-viewport-units');
    const cssnano = require('cssnano');
    
    // 配置插件
    // 引入postcss配置
    options: {
          
          
    	ident: 'postcss',
    	plugins: () => [
    	    postcssPresetEnv, // 是一个postcss插件,帮助您使用最新的css语法,它将新的css规范转换为更兼容的css,所以你不需要等待浏览器的支持。(之前同功能的postcss-cssnext插件被废弃, 推荐用postcss-preset-env)
    		postcssImport, // 主要功能是解决@import引入路径问题。使用这个插件,可以让你很轻松地使用本地文件、node_modules或者web_modules的文件。这个插件配合postcss-url让你引入文件变得更轻松
    		postcssUrl, // 该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理
            postcssAspectRatioMini, // 主要用来处理元素大小固定为宽高比,通常用于img等元素上
            postcssWriteSvg({
          
           utf8: false }), // 这个插件可以让你直接在CSS中写svg,需要配合postcss一起用,我们可以利用这个插件,使用border-image和background来做1px的相关处理,解决移动端的1px问题,但仅适合直线(有圆角的建议用transform配合伪类实现)
            postcssPxToViewport({
          
           // 实现px自动转vw实现自适应的关键插件,可以将px单位转换为视口单位的 (vw, vh, vmin, vmax) 
    		    viewportWidth: 1920, // 视口宽度,对应UI设计稿的视窗宽度
    		    viewporHeight: 1080, // 视口高度,对应UI设计稿的视窗高度
                unitToConvert: 'px',    // 需要转换的单位,默认为"px"
                viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
                fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
                unitPrecision: 6, // 指定px转换之后的精度,即小数点位数
                selectorBlackList: ['.ignore', '.hairlines'], // 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位
                exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
                // include: /\/src\//,     // 如果设置了include,那将只有匹配到的文件才会被转换 (exclude和include设置一个就行了)
                replace: true, //  是否转换后直接更换属性值,而不添加备用属性
                minPixelValue: 1, // 设置最小的转换数值,默认值1,小于或等于1px则不进行转换
                mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
                propList: ['*'], // 指定能转化为 vw 的css属性列表,*代表全部css属性的单位都进行转换
                // propList: ['*', '!font-size'],
                landscape: false,       // 是否根据 landscapeWidth 生成的媒体查询条件,处理横屏情况
                // landscapeUnit: 'vw',    // 横屏时使用的单位
                // landscapeWidth: 1125,   // 横屏时使用的视窗宽度
            }),
            postcssViewportUnits({
          
           // 插件主要是给css的属性添加content的属性,配合viewport-units-buggyfill库兼容一些不支持 vw、vh、vmax、vmin 这些 viewport 单位的浏览器所使用的。
              filterRule: rule => rule.selector.includes('::after') && rule.selector.includes('::before') && rule.selector.includes(':after') && rule.selector.includes(':before'), // 解决有伪类使用content报错 already has a ‘content’ property, give up to overwrite it.
            }),
            cssnano({
          
           // cssnano 是构建于 postcss 的插件和生态之上的,主要用来压缩和清理CSS代码,确保最终生成的文件对生产环境来说体积是最小的
              preset: [
                cssnanoPresetAdvanced, // cssnano-preset-advanced是cssnano的高级优化
                {
          
          
                  autoprefixer: false, // 由于cssnano-preset-advanced和cssnano都具有autoprefixer,事实上只需要一个即可,避免重复处理,所以把cssnano中的autoprefixer设置为false。
                  zindex: false // z-index会被cssnano重新计算为1,这个巨坑,会导致之后设置z-index出现各种问题,所以需要禁用cssnano的zindex
                }
              ],
            })
    	],
    }
    

    main.js

    const hacks = require('viewport-units-buggyfill/viewport-units-buggyfill.hacks');
    const viewportUnitsBuggyfill = require('viewport-units-buggyfill');
    
    // viewport-units-buggyfill
    viewportUnitsBuggyfill.init({
          
          
      hacks: hacks
    });
    
    

    main.css

    /* 使用了viewport-units-buggyfill后,它会占用content属性,因此会或多或少的造成一些副作用。如img元素和伪元素的使用::before 或::after。*/
    /* 对于img,在部分浏览器中,content的写入会造成图片无法正常展示,这时候需要全局添加样式覆盖:*/
    img {
          
          
      content: normal !important;
    }
    

效果

  1. px自动转成vw
    代码:

    .pxToVwExample {
          
          
      width: 100px;
      height: 100px;
      background-color: #000;
    }
    

    效果:
    在这里插入图片描述

  2. 1px
    代码:

    /*1px示例*/
    /*使用postcss-write-svg绘制1px(仅限直线)*/
    @svg square {
          
          
      height: 1px;
      @rect {
          
          
        fill: var(--color, white);
        width: 100%;
        height: 50%;
      }
    }
    /*background的形式*/
    .onePxLineByPostcssWriteSvgExample {
          
          
      width: 100%;
      height: 20px;
      background: white svg(square param(--color red));
      background-size: 100% 1px;
      background-repeat: no-repeat;
      background-position: bottom left;
    }
    
    /*border-image的形式*/
    /*
    .onePxLineByPostcssWriteSvgExample {
      width: 100%;
      height: 20px;
      border-bottom: 1px solid transparent;
       border-image: svg(square param(--color $navbar-border-color)) 2 2 stretch;
    }
    */
    
    
    /*使用伪类实现1px,会有一层阴影,效果比svg稍微差点*/
    .onePxLineByTransformExample {
          
          
      width: 100%;
      height: 20px;
      margin-top: 20px;
      position: relative;
    }
    .onePxLineByTransformExample:before {
          
          
      content: "";
      position: absolute;
      left: 0;
      bottom: 0;
      right: 0;
      height: 1px;
      border-top: 1px solid red;
      transform-origin: 0 0;
      transform: scaleY(1);
      z-index: 2;
    }
    

    效果:
    在这里插入图片描述

  3. 使用postcss-aspect-ratio-mini插件固定元素的宽高比

    <div>
      <div className={styles.exampleItemTitle}>使用postcss-aspect-ratio-mini处理元素的尺寸固定为纵横比(宽高比)</div>
      <div className={styles.postcssAspectRatioMiniExample}>
        <img src={aaa} alt="" />
      </div>
    </div>
    
    .postcssAspectRatioMiniExample {
          
          
      width: 188px;
      height: 188px;
      border: 1px solid #000;
      position: relative;
      aspect-ratio: 1/1; /*使用postcss-aspect-ratio-mini来处理元素容器的固定宽高比。加上它有神奇的力量*/
      /*aspect-ratio: 16/9;*/
    }
    
    .postcssAspectRatioMiniExample img {
          
          
      max-width:100%;
      max-height:100%;
      border: 1px solid #000;
      // aspect-ratio: 16/9;
    }
    

    在这里插入图片描述

vw实现自适应的优缺点

  • 优点:
    1. 不需要 js 做适配
    2. 方案灵活技能实现整体缩放又能实现局部不缩放
  • 缺点:
    1. 尺寸换算麻烦,不直观。
    2. px 转换成 vw 不一定能完全整除,因此有一定的像素差;
    3. 当容器使用 vw,margin 采用 px 时,很容易造成整体宽度超过 100vw,从而影响布局效果。可以避免,例如使用 padding 代替 margin,结合 calc()函数使用等等…

文章参考

https://blog.csdn.net/maxlee111/article/details/125203192
https://www.jianshu.com/p/9aa8f825d050
https://www.cnblogs.com/fengyuexuan/p/12576625.html
https://juejin.cn/post/6844903955755958285
https://blog.51cto.com/u_15581727/5176946
https://www.postcss.com.cn/
https://zhuanlan.zhihu.com/p/357492062
https://www.jianshu.com/p/9aa8f825d050
https://www.cssnano.cn/
https://github.com/evrone/postcss-px-to-viewport/blob/HEAD/README_CN.md
https://zhuanlan.zhihu.com/p/421015955
https://blog.csdn.net/weixin_33714884/article/details/88024232
https://blog.csdn.net/qq_17335549/article/details/126766952
https://blog.csdn.net/qq_43878324/article/details/122572539
https://segmentfault.com/a/1190000042432407
https://zhuanlan.zhihu.com/p/421015955

猜你喜欢

转载自blog.csdn.net/Boale_H/article/details/127575909