You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
玉凤:树,设计稿发给你啦,差那么点像素,就叼死你┏(  ̄へ ̄)=☞
阿树:(>_<)没问题啦~
阿树:哇靠,为啥你给的设计稿是750px宽 ,iPhone 6不是375px宽吗???
玉凤:A pixel is not a pixel is not a pixel, you know ?
阿树:(#‵′),I know Google。。。
最近一直在看一些手淘移动端适配rem之类的技术方案,在研究这些技术方案之前,首先需要掌握一些基本的单位概念,所以在网上也搜了一些资料。虽然全部看下来还是存在一些疑惑的地方,在此做一下记录。
有趣的问题
人物:前端实习生「阿树」与 切图工程师「玉凤」
事件:设计师出设计稿,前端实现页面
玉凤:树,设计稿发给你啦,差那么点像素,就叼死你┏(  ̄へ ̄)=☞
阿树:(>_<)没问题啦~
阿树:哇靠,为啥你给的设计稿是750px宽 ,iPhone 6不是375px宽吗???
玉凤:A pixel is not a pixel is not a pixel, you know ?
阿树:(#‵′),I know Google。。。
为什么会出现以上的情况,难道他们当中一位出错了,摆了这样的乌龙?
事实上,他们都是对的,只是谈的不是同一个「像素」。
1. dp (设备像素)
1.1 概念
1.2 相关说明
设备像素其实就是一个固定的尺寸,1pt = 1/72(inch),inch及英寸,而1英寸等于2.54厘米。
不同的设备,其图像基本单位是不同的,比如显示器的点距,可以认为是显示器的物理像素。现在的液晶显示器的点距一般在0.25mm到0.29mm之间。而打印机的墨点,也可以认为是打印机的物理像素,300DPI就是0.085mm,600DPI就是0.042mm。
2. px (CSS pixels)
比如iPhone 6使用的是Retina视网膜屏幕,使用2px x 2px的 device pixel 代表 1px x 1px 的 css pixel,所以设备像素数为750 x 1334px,而CSS逻辑像素数为375 x 667px。
3. dpr(Device Pixel Ratio) 设备像素比
设备像素比表示1个CSS像素(宽度)等于几个物理像素(宽度):
比如dpr=2时,1个CSS像素宽度等于2个物理像素宽度。1css像素由2 * 2个物理像素点组成,见上面对CSS像素的解释。DPR不是单位,而是一个属性名,比如在浏览器中通过
window.devicePixelRatio
获取屏幕的DPR。4. ppi (pixel per inch)每英寸的像素数,像素密度。
5. viewport 视窗
在桌面浏览器中,viewport就是浏览器窗口的宽度高度。
但移动设备的屏幕比桌面屏幕要小得多,为了要让网页在小尺寸的屏幕上显示正确,就需要对viewport做些处理。需要把viewport分成两部分:
visual viewport
和layout viewport
。George Cummins在Stack Overflow上对这两个概念做了分析。大致意思如下:5.1 visual viewport
visual viewport是页面当前显示在屏幕上的部分。用户可以通过滚动来改变他所看到的页面的部分,或者通过缩放来改变visual viewport的大小。
5.2 layout viewport
layout viewport就是页面原来的大小。
但是我们用在手机用浏览器打开PC的网页的时候,会看到网页被浏览器自动缩小了,变的太小会导致无法浏览内容。
5.3 idea viewport
布局视口的默认宽度并不是一个理想的宽度,大家从上面的图就可以看出来了,所以苹果公司就引进了理想窗口这个概念:
注意:
而且会随着设备转向改变
width=device-width
或者initial-scale=1.0
),就没问题了。5.4 viewport meta标签
为了不让浏览器自动缩小,引入了viewport元标签。通过这个元标签控制layout viewport的宽度。
上面这行代码就是告诉浏览器,布局视口的宽度应该与理想视口的宽度一致。
注意下图片中的红色框,第二张图片内容超了出来,应该是给文字设置了宽度,并且这个宽度大于layout viewport导致了出来。但其实在Android和IOS中会有不一样的表现。在文章《A tale of two viewports》中指出:
移动端 1px 像素问题
一直以来我们实现边框的方法都是设置
border: 1px solid #ccc
,但是在 retina 屏上因为设备像素比(dpr)的不同,边框在移动设备上的表现也不相同: 1px 可能会被渲染成 2px, 3px....也就是说逻辑像素1px会被用不同大小的物理像素来表示。(这里只介绍几种常用的方式,更多可以自行Google)rem + viewport
按照上面这种表述,首先想到的最快解决这种问题的肯定是根据dpr不同来进行缩放就好了,这种方式也就是常说的
rem + viewpor
。关于rem的介绍可以参考这里。核心的实现如下:大概意思就是设置网页根字体 font-size 为
37.5 * dpr
,这样根据 rem 产出的网页就会被放大 dpr 倍,此时css里面写的还是1px
,然后再通过initial-scale= 1 / dpr
来对网页进行缩小dpr倍。这样 1px 就会显示成1 / dpr
px。border-image 实现
这篇文章是腾讯github上的解决方案border-image来实现的。缺点是,你需要制作图片,圆角的时候会出现模糊。
border.png
也可以用 base64 图片替代。background-image 渐变实现
除啦用图片,难道纯粹的css就不能实现吗?我的确不想使用图片,感觉制作起来很麻烦,其实百度糯米团首页就是这么做的但是这种方法有个缺点,就是不能实现圆角
box-shadow 实现
利用阴影我们也可以实现,那么我们来看看阴影,优点是圆角不是问题,缺点是颜色不好控制。
伪类 + transform 实现
原理是把原先元素的
border
去掉,然后利用:before
或者:after
重做border
,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。单条border样式设置(其他的类似):
优点可以实现圆角,京东就是这么实现的。缺点是按钮添加active比较麻烦,对于已经使用伪类的元素(例如clearfix),可能需要多层嵌套。
The text was updated successfully, but these errors were encountered: