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

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

前言

随着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
    }
  ],
})
  1. cssnano-preset-advanced: cssnano的高级优化
  2. 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;*/
}
  1. postcss-import: 主要功有是解决@import引入路径问题。使用这个插件,可以让你很轻易的使用本地文件、node_modules或者web_modules的文件。这个插件配合postcss-url让你引入文件变得更轻松
  2. postcss-url: 该插件主要用来处理文件,比如图片文件、字体文件等引用路径的处理。
  3. 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,   // 横屏时使用的视窗宽度
}),
  1. 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.
}),
  1. 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
  1. 那么需要在项目的入口文件中(比如 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;
  }
  1. 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;
}
*/
  1. autoprefixer: 是用来自动处理浏览器前缀的一个插件。如果你配置了postcss-cssnext或者postcss-preset-env,其中就已具备了autoprefixer的功能,不需要再额外安装。在配置的时候,未显示的配置相关参数的话,表示使用的是Browserslist指定的列表参数,你也可以项目根目录创建.browserslistrc文件来指定last 2 versions 或者 > 5%,如下:
    .browserslistrc
> 1%
last 2 versions

  1. 如此一来,你在编码时不再需要考虑任何浏览器前缀的问题,可以专心撸码。这也是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;
}
  1. 效果:
  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;
}
  1. 效果:
  2. 使用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

目录
相关文章
|
9天前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
33 9
|
14天前
|
前端开发 JavaScript Android开发
前端框架趋势:React Native在跨平台开发中的优势与挑战
【10月更文挑战第27天】React Native 是跨平台开发领域的佼佼者,凭借其独特的跨平台能力和高效的开发体验,成为许多开发者的首选。本文探讨了 React Native 的优势与挑战,包括跨平台开发能力、原生组件渲染、性能优化及调试复杂性等问题,并通过代码示例展示了其实际应用。
40 2
|
15天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略
|
15天前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
28 2
|
15天前
|
前端开发 JavaScript 数据管理
React与Vue:两大前端框架的较量与选择策略
【10月更文挑战第23天】React与Vue:两大前端框架的较量与选择策略
|
14天前
|
前端开发 Android开发 开发者
前端框架趋势:React Native在跨平台开发中的优势与挑战
【10月更文挑战第26天】近年来,React Native凭借其跨平台开发能力在移动应用开发领域迅速崛起。本文将探讨React Native的优势与挑战,并通过示例代码展示其应用实践。React Native允许开发者使用同一套代码库同时构建iOS和Android应用,提高开发效率,降低维护成本。它具备接近原生应用的性能和用户体验,但也面临平台差异、原生功能支持和第三方库兼容性等挑战。
27 0
|
15天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】 React与Vue:前端框架的巅峰对决与选择策略
|
2月前
|
JavaScript
webpack打包TS
webpack打包TS
131 60
|
1月前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
1月前
|
前端开发 JavaScript
ES6模块化和webpack打包
【10月更文挑战第5天】