抛弃插件、一行CSS代码实现响应式布局

408 阅读3分钟

一、先贴代码

:root {
  --designWidth: 750;  /* 设计稿宽度(移动端一般为750px) */
  font-size: calc(100vw / var(--designWidth));  /* 令 `100vw / 750px` 得到 1rem 对应的 px 实际值 */
}

二、实机效果

三、实现

当我们谈响应式式布局技术方案,有两点非常重要:

  1. 还原设计稿尺寸,设计稿 750px => 手机设备100%宽度

  2. 优雅的使用方式。

众所周知,一项技术方案是否能够推广,不仅在于技术方案本身,更在于设计是否合理,使用是否便捷。

一、还原设计稿尺寸

过去业内有许多成熟的技术方案,其中比较出名的就是淘宝的amfe/lib-flexible,核心代码也很简单,通过监听窗口resize,将 1rem 锚定为屏幕宽度的 1/10

image.png

此时屏幕总宽度等于10rem

当设计稿总宽度为750px,其中的一个 ICON 的宽度为 100px 时,只需在CSS中设置设ICONwidth1.33rem。 计算过程如下:

image.png

此时,你将得到一个响应式的图片大小,无论在任何手机设备上,ICON的大小都相对屏幕宽度呈现固定比例。设计师走查时露出欣慰的笑容😊

到这里,你应该发现此种方案解决了设计稿还原的问题,虽然设计师开心了,但是前端苦逼了,每次都用上面的公式进行换算,非常的麻烦。作为工程师,咱们怎么能受得了这种苦。所以有请px2rem-loader

二、优雅的使用

px2rem-loaderwebpack-loader,支持将用户写入的px单位转化为rem,配合flexilbe 可以做到css1px即锚定设计稿中的1px。大概配置如下

    const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
    remUnit: 37.5 // 设计稿宽度/10
   }

但显而易见,这种方式剥夺了我们书写绝对长度单位px的能力,因为所有的px都被转化为了相对长度单位rem

四、布局理念

我们为什么还需要原来的绝对长度单位 px?

flexible+px2rem 方案中,文本内容在不同宽度的屏幕上显示的字数是相同的。

但用户购买大屏手机,是为了看到更多的内容,而不是更大的内容。

作者认为:文本内容使用 px 单位书写,布局采用 flex/grid 并配合相对单位 rem 才是解决移动端响应式的最优解。

基于以上两种原因加上想要书写真实px的能力,本文的方案随之而来。它解决了响应式布局的两个核心问题,并且新增了两项优点

  1. 还原设计稿:将--designWidth设置为设计稿宽度;
  2. 优雅的使用:1px(设计稿像素) = 1rem,设计稿为1px,CSS中写1rem即可;
  3. 而且它还保留了书写px的能力,改为剥夺了rem(对不起~);
  4. 并且最重要的一点,它真的只需要一行css样式即可,显著的降低了前端配置工程量。

五、兼容性

使用到了CSS的计算函数calc(),以及长度单位vw image.png

image.png 支持 >= Android 4.4,>= IOS 6.1

所以放心的用吧!