我在网上看过不少相关的资料,都在说淘宝适配方案和网易适配方案。说了dpr,meta等好多概念,说实话我感受写的都好复杂,跟我本身想的有出入。新学东西我总想找到这个东西设计的出发点,但我没在这些文章中找出来。在看了些如今主流网站的代码后,以为本身有了一点心得,因此献丑拿来分享下,但愿对你有点帮助javascript
既然是适配咱们开始确定要有一个参考屏幕,这里咱们先提早肯定下面全部的例子都是以iphone6的屏幕(宽度为375px
)为参照。一般设计稿是2倍的设计稿,因此咱们拿到的设计稿设计稿最终宽度为750px
。css
屏幕适配最终的目标或者说本质就是实现 等比缩放。html
如今各大网站虽然方案有差别,但步骤和目的实际上是同样的,主要分为如下几步:前端
为何要有个基准?由于咱们不但愿每种屏幕写一种布局样式,因此咱们须要有一个基准来随屏幕宽度变化,咱们只要根据基准来肯定咱们的css值,就能够适配全部的屏幕了。java
这就是适配的所有了,下面咱们来看看这几步能够用什么方案来解决。git
基准是什么?为了简单基准咱们当作单位,因此咱们须要找一个能变化的单位,思考下,css中哪些单位能够变化?rem
是以根字体的大小来肯定本身的值的,符合条件。因此咱们可让根字体随屏幕变化而变化,咱们直接用rem
进行布局能够了。github
下一步就是肯定基准值,咱们这里就是肯定根字体的值。为了方便咱们计算咱们能够设置一个很容易计算的值,好比咱们可让设计稿中1rem=100px
,那么写起来就是sass
// 屏幕宽度 / 7.5 = 1rem
// 或
// 100vw / 7.5 = 1rem
复制代码
这两种在这个例子中是同样的,而后咱们写样式的时候用rem
作为单位就能够了,好比设计稿上有一个宽度为80px
的div
元素,咱们只须要这样写:bash
div {
width: .8rem;
}
复制代码
若是你仍是嫌每次手动计算麻烦,能够用如今样式预处理器(如less、sass)中的mixin的来帮你或者使用js来动态计算。app
到这里咱们的适配就说完了。你可能会问dpr、meta头设置视图宽度那些东西怎么没看到,我明明在不少文章看到这些概念。别急,其实这些都是为了解决一个问题,下面咱们就来讲说这个问题
hairline
是啥?hairline其实就是很细的线,不少设计师特别喜欢用这种线,让咱们前端头大🙄。这种线直接用0.5px
行吗?这在之前一些旧的屏幕上是不行的,会被自动修正为1px
,咱们都知道。
可是现代不少手机都是高倍屏,即一个css像素会有多个物理像素,这样显示的图像更细腻而且更清晰,有的已经支持css使用小数,这种状况下咱们能够直接使用像0.5px
来写出这种宽度的线了。这里有个概念,物理像素数和css像素被称为设备像素比
,也就是咱们常常说的dpr了
物理像素数 / css像素数 = dpr
复制代码
dpr
的值能够经过window.devicePixelRadio
来获取。
问题好像已经解决了。可是咱们前端还有很重要的一部分的工做是兼容,若是遇到不支持这种小数css写法的怎么办?咱们想个很通用的解决方案,那就是缩放,好比咱们把1px
宽度的线缩小一半就能获得0.5px
宽度的线了。
为了让咱们全部1px
宽度缩为一个物理像素宽,咱们就须要让页面宽度为屏幕css宽度 * dpr
。而后咱们在这个宽度下写1px
宽度的线,最后再缩小dpr
倍咱们就能够得获得1物理像素宽度了。
为了实现让页面变为屏幕css宽度 * dpr
的宽的目的,咱们须要按比例改变咱们上面的适配方案。
假如如今dpr=3
,咱们就须要让页面宽度为 375 * 3 = 1125,而咱们的设计稿是750。咱们就须要让咱们的基准值成比例变化
// 屏幕宽度 / 7.5 => 屏幕宽度 / 7.5 / 2 * 3
复制代码
如今咱们获得尺寸为屏幕css宽度 * dpr
的页面了,为了让页面彻底显示在屏幕中咱们须要在html中设置meta头(不了解这些的本身查下,有不少资料)
<meta name="viewport" content="width=屏幕css宽度 * dpr">
复制代码
而后缩小dpr倍变成
<meta name="viewport" content="width=屏幕css宽度 * dpr,initial-scale=1/dpr,minimum-scale=1/dpr,maximum-scale=1/dpr,user-scalable=no">
复制代码
到这里,咱们全部东西都讲完了,但愿你已经理解了为何会有那么多写法不一样的适配方案了,他们都是异曲同工。
最后附上如今淘宝和网易的部分代码,你能够本身直接去他们网站找到这些代码。你应该能根据这些代码分析他们的方案了,这些留给你本身思考和分析了
手机淘宝网部分适配代码
! function (e, t) {
var n = t.documentElement,
d = e.devicePixelRatio || 1;
function i() {
var e = n.clientWidth / 3.75;
n.style.fontSize = e + "px"
}
if (function e() {
t.body ? t.body.style.fontSize = "16px" : t.addEventListener("DOMContentLoaded", e)
}(), i(), e.addEventListener("resize", i), e.addEventListener("pageshow", function (e) {
e.persisted && i()
}), 2 <= d) {
var o = t.createElement("body"),
a = t.createElement("div");
a.style.border = ".5px solid transparent", o.appendChild(a), n.appendChild(o), 1 === a.offsetHeight && n.classList.add("hairlines"), n.removeChild(o)
}
}(window, document)
复制代码
手机网易新闻网部分适配代码
html {
font-size: 13.33333vw
}
@media screen and (max-width: 320px) {
html {
font-size:42.667px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 321px) and (max-width:360px) {
html {
font-size:48px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 361px) and (max-width:375px) {
html {
font-size:50px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 376px) and (max-width:393px) {
html {
font-size:52.4px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 394px) and (max-width:412px) {
html {
font-size:54.93px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 413px) and (max-width:414px) {
html {
font-size:55.2px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 415px) and (max-width:480px) {
html {
font-size:64px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 481px) and (max-width:540px) {
html {
font-size:72px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 541px) and (max-width:640px) {
html {
font-size:85.33px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 641px) and (max-width:720px) {
html {
font-size:96px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 721px) and (max-width:768px) {
html {
font-size:102.4px;
font-size: 13.33333vw
}
}
@media screen and (min-width: 769px) {
html {
font-size:102.4px;
font-size: 13.33333vw
}
}
复制代码
本文原文更新在个人github上,这里是原文连接。若是文章有任何错误或不许确之处,欢迎指出,很是感谢!