Nuxt3配置postcss-pxtorem

作者:linkyang
标签:nuxt3、前端、前端框架
发布时间:2024年05月31日 23:50:44
更新时间:2025年02月26日 23:50:44

postcss-pxtorem是一款自动将px转化为rem的插件,通常在移动端使用较多,但是在pc端使用postcss-pxtorem来兼容不同的分辨率效果也还不错。

  1. 首先安装postcss-pxtorem
    bash
    npm install postcss-pxtorem --save-dev
    
  2. 然后再nuxt.config.ts中配置下postcss
json
  postcss: {
    plugins: {
      //配置autoprefixer,自动添加浏览器前缀,解决css兼容性问题
      'autoprefixer': {
        overrideBrowserslist: ['last 2 versions', 'iOS >= 8', 'Android >= 4', 'ie >= 9'],
      },
      //配置pxtorem,将px转换为rem
      'postcss-pxtorem': {
        rootValue: 16, // 根元素字体大小
        unitPrecision: 100, // 转换成rem单位的小数点后的保留位数
        selectorBlackList: [], // 忽略转换正则匹配项
        propList: ["*"], // 需要转换的属性列表,*表示全部
        replace: true,  // 是否替换包含rem的规则
        minPixelValue: 1, // 设置要替换的最小像素值
        selectorBalckList: [], // 需要排除转换rem的选择器
        mediaQuery: false, // 是否转换媒体查询中的px
      },
    },
  },

示例我使用了autoprefixer这个插件来自动添加css样式前缀,解决一些浏览器的样式兼容问题。这里我们主要看postcss-pxtorem的配置。配置完以后,我们打开项目的控制台就可以发现px单位被自动转化成了rem。

但是我们缩放网页和缩放浏览器宽高页面并没有自适应,所以我们可以引入amfe-flexible这个插件,他会根据我的网页宽度, 动态设置html的font-size,将1rem设为viewWidth/10,也就是说10rem等于全屏宽度

注意我在postcss配置中并没有按照屏幕宽度的十分之一来设置元素的字体大小,所以我在引入之后需要对amfe-flexible进行一些修改

  1. 编写Nuxt插件,引入amfe-flexible

在项目plugins目录下新建rem.client.ts文件,将amfe-flexible源码放入defineNuxtPlugin函数当中。

在plugins目录下的插件会自动导入,这里我们文件以.client.ts结尾,是规定这个插件在客户端执行,如果不这么命名,则需要在nuxt.config.ts中配置插件的运行环境 详见,我们这里必须在客户端运行。

js
import { defineNuxtPlugin } from '#app'

export default defineNuxtPlugin((nuxtApp) => {
  (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.5px 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))
})

如果你在之前的rootValue中配置根元素字体大小为屏幕宽度的十分之一的话那么到此就可以结束了,如果是全程跟我一样的配置的话,那么还需要修改下rem.client.ts文件。找到setRemUnit函数,

js
 function setRemUnit() {
     var rem = docEl.clientWidth / 120 //将10改为120(因为我的屏幕宽度为1920,rootValue为16,1920/16= 120 所以我的120rem就是全屏)
     docEl.style.fontSize = rem + 'px'
 }

注意:postcss-pxtorem无法转化行内样式

所以我们再编写行内样式的时候可以直接使用rem单位。我们可以在vscode中安装px to rem & rpx & vw (cssrem),然后在设置、拓展、cssrem configuration中设置下页面宽度和根元素字体大小,这样在编写样式的时候就会自动提示转化后的rem。

登录后可查看并参与评论

Gitee 登录

目录导航

暂无目录