👨一文讲透等比例缩放响应式-px2rem-px2vw

效果

页面宽度为 2000px,里面有个正方形卡片,长宽比为 1:1 ,长宽都是 500px。还有个长方形卡片长宽比为 3:1,长度为 1500px, 宽度为 500px。

等比例缩放

等比例响应式的效果是,当页面宽度变成了原来的 1/2,里面的所有内容尺寸都缩小为 1/2。

当页面的宽度变成了原来的 2 倍,里面的所有尺寸都放大成 2 倍。

要达到这样的效果,可以采用 px 转 rem 的方式,或者 px 转 vw 的方式。

PX TO REM

什么是 Rem?

说到 rem,就离不开 emremem 是 CSS 中常用的两个单位,用于定义元素的尺寸、间距、字体大小等。它们都属于相对单位,与绝对单位(如 px、cm 等)不同。

em 是相对于元素当前字体大小的单位。它的值会根据使用它的元素的字体大小而变化。

  • 如果一个元素的字体大小是 16px,那么 1em 等于 16px
  • 2em 就等于 2 * 16px,也就是 32px

rem 是相对于根元素(即 HTML 元素)的字体大小。无论嵌套多少层,rem 都只基于根元素的字体大小计算。

  • 如果根元素的字体大小是 16px(这是浏览器的默认值),那么 1rem 等于 16px
  • 2rem 就等于 2 * 16px,也就是 32px

em 相对当前元素的字体大小,有继承和累积效应。**rem** 相对根元素的字体大小,没有累积效应,更加一致和可预测。

我们这里使用rem,为的是全局的尺寸都参考同一个标准。当 rem 变大两倍,全局的尺寸也都变大两倍;当 rem 变小两倍,全局的尺寸也都变小两倍。

举个例子:

现在有个这样的样式代码

css 复制代码
html {
  font-size: 16px;
}

.header {
  font-size: 1.5rem; /* 24px, 因为 1.5 * 16px = 24px */
  padding: 1rem; /* 16px */
}

.content {
  font-size: 1rem; /* 16px */
  margin: 2rem; /* 32px, 因为 2 * 16px = 32px */
}

现在假设需要将整体尺寸放大两倍,可以通过调整根元素的字体大小:

css 复制代码
html {
  font-size: 32px; /* 将根元素的字体大小放大到 32px */
}

.header {
  font-size: 1.5rem; /* 48px, 因为 1.5 * 32px = 48px */
  padding: 1rem; /* 32px */
}

.content {
  font-size: 1rem; /* 32px */
  margin: 2rem; /* 64px, 因为 2 * 32px = 64px */
}

通过这种方法,不需要逐个修改每个元素的大小,只需一次调整根元素的字体大小,就能够全局地影响到所有使用 rem 单位的尺寸。这种做法在响应式设计中特别有用,可以方便地调整整体布局和尺寸,以适应不同的屏幕尺寸和设备。

现代化 CSS:postcss-pxtorem

原理

postcss 是一个用 JavaScript 编写的 CSS 处理工具。它允许你使用插件来转换和优化 CSS 代码,从而提升开发效率和代码质量。PostCSS 的强大之处在于它的插件系统,你可以根据需要选择和组合各种插件来满足特定的需求。

简单来说,postcss 就是 css 代码的预处理工具,将 css 代码做一系列的加工处理,并且通过插件扩展各种各样的加工流程。

autoprefixer插件可以给 css 属性加上各种浏览器的前缀,tailwind插件通过读取类名,生成对应的 css 类代码,还有这篇文章要讲的postcss-pxtorem,它的作用是将 css 代码中的 px 单位全部换算成 rem。

postcss-pxtorem 转换单位的换算原理是什么,比如:它怎么知道 16px 要转成 1rem,而不是 2rem 呢?

换算原理很简单,

如果页面根节点(html 节点)的font-size为 16px,说明1rem=16px; 那postcss-pxtorem转换就是下面这样:

javascript 复制代码
8px => 0.5rem
16px => 1rem
24px => 1.5rem
32px => 2rem

如果页面根节点font-size为 32px,那转换过程就是这样:

javascript 复制代码
8px => 0.25rem  // 8px / 32px = 0.25
16px => 0.5rem  // 16px / 32px = 0.5
24px => 0.75rem // 24px / 32px = 0.75
32px => 1rem    // 32px / 32px = 1

很简单吧?

只要单位变成 rem,响应式就好做了,怎么做?动态修改根节点的 font-size 就好了!

当页面宽度变成了原来的 2 倍,就将根节点的 font-size 变成原来的 2 倍,页面中各种 DOM 尺寸自然就变成了原来的 2 倍。

当页面宽度变成了原来的 X 倍,就将根节点的 font-size变成原来的 X 倍,页面中各种 DOM 尺寸自然就变成了原来的 X 倍。

css 代码一旦 build,代码中的数值就不可变了,即原来的 width: 2rem;,无论页面宽度如何变化,代码依旧是width: 2rem;

这就是postcss-pxtorem的基本原理了

配置步骤:

安装依赖:

shell 复制代码
npm i postcss postcss-loader postcss-pxtorem -D

配置 webpack:

javascript 复制代码
export default {
  module:{
    rules:[
      {
        test: /\.css$/,
        use:['style-loader','css-loader','postcss-loader']
      }
    ]
  }
}

配置 postcss.config.js :

javascript 复制代码
module.exports = {
  plugins: [
    'postcss-pxtorem':{
      rootValue: 37.5, // 一般取设计稿的1/10
      unitPrecision: 5, // 转换后的小数位数
      propList: ['*'], // 需要进行转换的属性列表
      selectorBlackList: [], // 不进行转换的选择器列表
      replace: true, // 替换而不是添加 fallback
      mediaQuery: false, // 不转换媒体查询中的 px
      minPixelValue: 0 // 需要进行转换的最小像素值
    }
  ]
}

文件入口:

javascript 复制代码
function setRemUnit() {
	//将页面的十分之一作为1rem。
	const rem = document.body.clientWidth / 10;
	document.querySelector("html")!.style.fontSize = rem + "px";
}

window.addEventListener("resize", setRemUnit);
window.addEventListener("load", setRemUnit);

在配置 postcss-pxtorem时,难点是确定 rootValue到底是多少,以及为什么一般取设计稿宽度的 1/10 作为根节点的 font-size。这里试着将其讲清楚

上文说到postcss-pxtorem在转换单位的时候,是以根节点的font-size作为计算标准的,font-size的值决定了最终得到的数值大小,那么这个 font-size多少合适呢?

理论上任意数值均可!!

我们的目的是做等比例响应式,即页面上的元素尺寸随着页面宽度的变化而变化就行了,至于具体 width1rem 还是 2rem,并没有什么关系

证明:

现在postcss-pxtorem根据font-size: Apx转换 css 代码中的单位(A 为未知数),并且设计稿的宽度为 Bpx(B 为未知数)

现在有 css 代码:

css 复制代码
.header {
  width: Apx;
  height: 2Apx;
  border-radius: 0.1Apx;
}

经过转换后得到:

css 复制代码
.header {
  width: 1rem;
  height: 2rem;
  border-radius: 0.1rem;
}

当页面的宽度为 Bpx,那根节点的字体大小为 Apx,不用修改。

当页面的宽度为 Ypx(Y 为未知数),根节点的字体大小应该是 (Y/B) * A px,现在页面元素的尺寸为原来的(Y/B)

遵循一个原则,页面的宽度变成了多少倍,根节点的字体大小就变成多少倍

证毕

小结

通过上面的证明,可以看到,根节点的大小 Apx 可以为任意值,和设计稿宽度没有任何关系,且依旧保持了等比例的响应式缩放。

那么,上面为什么又说取设计稿的 1/10呢?因为这样做计算简单。

小小证明一下:假设的条件同上,现在令根节点的字体大小为(B/10)px, 当页面宽度为Ypx时,根节点的字体大小应该改成(Y/B) * (B/10)px=>(Y/10)px,即当前页面宽度的 1/10。证毕

PX TO VW

什么是 VW

vwvh 是 CSS 中的视口单位,用于相对于视口(浏览器窗口)尺寸来设置元素的尺寸。它们在响应式设计中非常有用,能够根据视口的大小动态调整元素的尺寸,从而实现更灵活和自适应的布局。

  • vw(viewport width):表示视口宽度的 1%。例如,如果视口宽度是 1000px,那么 1vw 等于 10px。
  • vh(viewport height):表示视口高度的 1%。例如,如果视口高度是 1000px,那么 1vh 等于 10px。

假设视口的宽度是 1200px,高度是 800px:

  • 50vw 等于 600px(即视口宽度的 50%)
  • 50vh 等于 400px(即视口高度的 50%)
css 复制代码
.box {
  width: 50vw; /* 视口宽度的 50% */
  height: 50vh; /* 视口高度的 50% */
  background-color: lightblue;
}

在响应式页面设计中,使用 vwvh 单位可以确保元素根据视口的大小进行调整,从而在不同设备和屏幕尺寸下都能保持良好的布局。设置字体大小时,使用 vw 可以使文本在不同屏幕尺寸下相对稳定。

比如:

css 复制代码
.text {
  font-size: 2vw; /* 字体大小是视口宽度的 2% */
}

现代化 CSS 工具:postcss-pxtoview

postcss-px-to-viewport 也是一个 PostCSS 插件,它可以将 CSS 中的 px 单位自动转换为基于视口单位(vw, vh, vmin, vmax)的单位。这对于实现响应式设计特别有用,因为它可以根据视口大小动态调整元素的尺寸。

原理

假设你有一个 CSS 文件 styles.css,内容如下:

css 复制代码
.header {
  width: 500px;
  height: 250px;
}

.footer {
  width: 100%;
  max-width: 1000px;
  min-height: 50px;
  margin: 0 auto;
}

通过配置 postcss-px-to-viewport,它会将 px 单位转换为 vw 单位。假设页面宽度为 500px,转换后的结果可能如下:

css 复制代码
.header {
  width: 100vw; 
  height: 50vw; 
}

.footer {
  width: 100%;
  max-width: 200vw;
  min-height: 0.1vw;
  margin: 0 auto;
}

单位换算的逻辑是依据当前设置的页面宽度来计算的,当前页面宽度为 500px,那么原先的 500px 自然就转换成 100vw 了,以及 250px,自然就转换成了 50vw

很简单。

配置步骤

安装依赖:

shell 复制代码
npm i postcss postcss-loader postcss-px-to-viewport -D

配置 webpack:

javascript 复制代码
export default {
  module:{
    rules:[
      {
        test: /\.css$/,
        use:['style-loader','css-loader','postcss-loader']
      }
    ]
  }
}

配置 postcss.config.js

javascript 复制代码
module.exports = {
  plugins: {
    'tailwindcss': {},
    'postcss-px-to-viewport': {
      viewportWidth: 500, //设计稿的宽度
      unitPrecision: 5,
      viewportUnit: 'vw',
      selectorBlackList: ['.ignore', '.hairlines'],
      minPixelValue: 1,
      mediaQuery: false,
    }
  }
}

这里viewportWidth的值和设计稿的宽度保持一致就好了。等代码转换的时候,参考标准就是设计稿的宽度了。

转成了 vw 后,就天然支持响应式了。假设一个元素的宽度为 10vw,相当于页面宽度的 10%,当页面的宽度增加了原来的 2 倍,而元素的宽度依旧是整个页面宽度的 10%,相当于也扩大了 2 倍。

这个配置相比于 pxtorem 的方案更简单,也更好懂。

总结

这篇文章讲了页面元素等比例缩放的两个方案: px 转 rem 的方式,以及 px 转 vw 的方式,从概念,原理,然后再讲到配置,深入浅出,通俗易懂。是一篇努力让小白和资深前端都有收获的文章。

欢迎留言评论,以及转发。

相关推荐
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼3 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風7 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#