简述·场景

“最”常见webpack移动前端开发流程:

天马行空的UE给到PSD -> 不分角色(UE or FE)地标注&切图 -> 按标注适应最佳分辨率(320?)布局

然后,好不容易适配好了以320为最佳css分辨率的机子,PM拿着I疯6    Plus兴匆匆跑过来问你:“这个界面的字体和图片好像和我当时所想的策略不太一样哦?!”

然后,你内心一万个草泥马在奔腾......

解决方案

  • 使用rem
  • 使用em
  • px + @media query,
使用rem

暂时认同,网上说这是一个很好的方案(只要你不考虑兼容一些很奇葩的浏览器,比如我们团队t5内核的浏览器产品);

使用em

简单说一下,em比rem弱了不少,但是兼容性要好;

使用px

这里,我们首先回到一个css最初的问题,px支持小数吗?当然支持,不过兼容性有问题,有的浏览器会直接取整数,有的浏览器则四舍五入,看SF就好......,其实,说白了浏览器并不是傻傻地给你支持小数,而是当你有小数输入的时候,大部分给你转化成了整数,于是,我们还不如直接写成整数,像这样

.container {
    width: 320px;
    border: 1px solid #eee;
}

考虑到多分辨率最佳视角

.container {
    width: 320px;
    border: 1px solid #eee;
}
@media screen and min-width(360px) {
    .container {
        width: 360px;
    }
}
@media screen and min-width(414px) {
    .container {
        width: 414px;
    }
}

于是,TM问题就来了,我们每次写一个.container,就要添加两个规则到@media块里面,你不累?我宁愿用rem.......,要么用一些预编译语言去for循环也行啊(貌似less、sass还有stylus,写一写也要一堆代码哦,后面会提到),怎么搞?

实际工作中,我发现了两个问题:

  • UE给我的标注肯定不是320,他们觉得320做设计太小了,他们会以客户端主流分辨率为标准,以720为宽的PSD给我标注(没办法,前端后妈生的);
  • @media的声明实在是repeat self,为了多分辨率适应,必须得“写上”,当然,这个“写上”肯定不是人去写;

于是我们可不可以利用动态语言去mixin或者function搞?可惜,用stylus折腾了半天,并没有发现很好的做法,虽然这些流程化的css扩展语言提供了一系列语法或者语法糖,但是我在“研究”的过程中发现,我需要的并不是语法上的扩展,而是一种自定义的语法糖,具体来说,我需要一个自定义的单位,然后我能通过这个单位找到所有对应的css selector,以及其对应的规则,通过收集到所有这样符合条件的规则以及selectors,重新生成对应的media块!

可以参考如下:

/* 输入src/test.css */
/* 自定义单位: mpt */
/* UE标准最佳分辨率宽度720 */
/* 前端基本最佳分辨率宽度320 */
/* 前端需要支持的其他最佳分辨率宽度列表:360, 414 */
/* 单位换算公式: 实际像素 = (输入规则值mpt / 720) * 最佳分辨率宽度 */

.container {
	width: 720mpt;
    border: 1px solid #eee;
}
.navigator {
	width: 720mpt;
	height: 120mpt;
}

/* 输出dist/test.css */
/* 生成单位: px */
.container {
	width: 320px; /* (720 / 720) * 320 */
    border: 1px solid #eee;
}
.navigator {
	width: 320px; /* (720 / 720) * 320 */
	height: 53px; /* (120 / 720) * 320 */
}
@media screen and min-width(360px) {
    .container {
        width: 360px; /* (720 / 720) * 360 */
    }
    .navigator {
        width: 360px; /* (720 / 720) * 360 */
        height: 60px; /* (120 / 720) * 360 */
    }
}
@media screen and min-width(414px) {
    .container {
        width: 414px; /* (720 / 720) * 414 */
    }
    .navigator {
        width: 414px; /* (720 / 720) * 414 */
        height: 69px; /* (120 / 720) * 414 */
    }
}

这里并不是造轮子,而且现有的css动态语言并不支持如此高的语义化单位语法糖(或许已经支持,只是俺太笨:<),现在针对现有的经验,基于css AST(抽象语法树),封装一个webpack的loader是相对低成本的,这里是github传送门