【适配】521- 移动端开发各种兼容适配问题(屏幕、图像、字体与布局等)
什么是响应式设计
为什么要设计响应式界面
即便是PC或Mac用户,有查显示只有一半的人会将浏览器全屏显示,而剩下的一般人使用多大的浏览器,很难预知;
台式机、投影、电视、笔记本、手机、平板、手表、VR……智能设备正在不断增加,“主流设备”的概念正在消失;
屏幕分辨率正飞速发展,同一张图片在不同设备上看起来,大小可能天差地别;
鼠标、触屏、笔、摄像头手势……不可预期的操控方式正在不断出现。
响应式界面的四个层次
同一页面在不同大小和比例上看起来都应该是舒适的;
同一页面在不同分辨率上看起来都应该是合理;
同一页面在不同操作方式(如鼠标和触屏)下,体验应该是统一的;
同一页面在不同类型的设备(手机、平板、电脑)上,交互方式应该是符合习惯的。
响应式界面的基本规则
可伸缩的内容区块:内容区块的在一定程度上能够自动调整,以确保填满整个页
可自由排布的内容区块:当页面尺寸变动较大时,能够减少/增加排布的列
适应页面尺寸的边距:到页面尺寸发生更大变化时,区块的边距也应该变化
能够适应比例变化的图片:对于常见的宽度调整,图片在隐去两侧部分时,依旧保持美观可用
能够自动隐藏/部分显示的内容:如在电脑上显示的的大段描述文本,在手机上就只能少量显示或全部隐藏
能自动折叠的导航和菜单:展开还是收起,应该根据页面尺寸来判断
放弃使用像素作为尺寸单位:用dp(对于前端来说,这里可能是rem)尺寸等方法来确保页面在分辨率相差很大的设备上,看起来也能保持一致。同时也要求提供的图片应该比预想的更大,才能适应高分辨率的屏幕。
媒体查询,边界断点的规则设定(Media queries && break point)
内容的可伸缩性效果(Flexibel visuals)
流式网格布局(Fluid grids)
主要内容呈现及图片的高质量(Main content and high quality)
响应式 vs. 自适应
渐进增强 vs. 优雅降级
渐进增强(progressive enhancement):针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级(graceful degradation):一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
移动端屏幕适配方案
提示:一些概念性的东西,大部分人很难一次性记住,或者记了又忘,我觉得记忆这个东西比较看技巧,比如关联法,想象法,把这些生硬的概念与一些符合我们常识的知识关联在一起记忆,往往能够事半功倍。
设备独立像素
375 * 667
表示的是什么呢,表示的是设备独立像素(DIP),也可以理解为 CSS 像素,也称为逻辑像素:
物理像素
1334 x 750
,这里描述的就是屏幕实际的物理像素。
1334 x 750
表示手机分别在垂直和水平上所具有的像素点数。通过控制每个像素点的颜色,就可以使屏幕显示出不同的图像,屏幕从工厂出来那天起,它上面的物理像素点就固定不变了,单位为pt。
DPR(Device Pixel Ratio) 设备像素比
或者是 1334 / 667 = 2
dpr > 1
的屏幕称为视网膜屏幕。
2688 x 1242
,
896 x 414
,很容易得出 iPhone XS Max 的 dpr 为 3。
适配不同屏幕大小,也就是适配不同屏幕下的 CSS 像素
适配不同像素密度,也就是适配不同屏幕下 dpr 不一致导致的一些问题
适配不同屏幕大小
375*667
的大小的设计稿,其中一个元素的标注如下:
元素的宽度为:
209/375 = 55.73%
元素的高度为:
80/375 = 21.33%
元素的上左右边距依次计算...
宽度(width)、间距(maring/padding)支持百分比值,但默认的相对参考值是包含块的宽度;
高度(height)百分比的大小是相对其父级元素高的大小;
边框(border)不支持百分值;
边框圆角半径(border-radius)支持百分比值,但水平方向相对参考值是盒子的宽度,垂直方向相对参考值是盒子的高度;
文本大小(font-size)支持百分比值,但相对参考值是父元素的font-size的值;
盒阴影(box-shadow)和文本阴影(text-shadow)不支持百分比值;
rem 适配方案
flexible
根据设备的 dpr 动态改写
<meta>
标签,设置 viewport 的缩放给
<html>
元素添加 data-dpr 属性,并且动态改写 data-dpr 的值根据
document.documentElement.clientWidth
动态修改<html>
的 font-size ,页面其他元素使用 rem 作为长度单位进行布局,从而实现页面的等比缩放
hotcss
对于 rem 方案的一些总结
动态修改 Viewport 存在一定的风险的,譬如通过 Viewport 改变了页面的缩放之后,获取到的
innerWidth/innerHeight
也会随之发生变化,如果业务逻辑有获取此类高宽进行其他计算的,可能会导致意想不到的错误;
flexible/hotcss 都并非纯 CSS 方案,需要引入一定的 Javascript 代码
rem 的设计初衷并非是用于解决此类问题,用 rem 进行页面的宽度适配多少有一种 hack 的感觉
存在一定的兼容性问题,对于安卓 4.4 以下版本系统不支持 viewport 缩放(当然,flexible 处理 Android 系列时,始终认为其 dpr 为 1,没有进行 viewport 缩放)
vw 适配方案
font-size
,而 vw/vh(vmax/vmin) 的出现则很好弥补 rem 需要 JS 辅助的缺点。
vw
等于初始包含块(html元素)宽度的1%,也就是
1vw
等于window.innerWidth
的数值的 1%1vh
等于window.innerHeight
的数值的 1%
元素的宽度为:
209/375 = 55.73% = 55.73vw
元素的高度为:
80/375 = 21.33% = 21.33vw
元素的上左右边距依次计算...
容器大小适配,可以使用 vw
文本大小的适配,可以使用 vw
大于 1px 的边框、圆角、阴影都可以使用 vw
内距和外距,可以使用 vw
自动转换插件
// 假设设计稿的宽度是 375px,假设取设计稿宽度下 1rem = 100px$baseFontSize: 100;@function px2rem($px) { @return $px / $baseFontSize * 1rem;}
// 假设设计稿的宽度是 375px
@function px2rem($px) {
@return $px / 375 * 100vw;
}
vw polyfill
CSS Houdini:通过CSS Houdini针对vw做处理,调用CSS Typed OM Level1 提供的 CSSUnitValue API。
CSS Polyfill:通过相应的Polyfill做相应的处理,目前针对于 vw 单位的 Polyfill 主要有:vminpoly、Viewport Units Buggyfill、vunits.js和 Modernizr
对于 vw 方案的一些总结
也没能很好的解决 1px 边框在高清屏下的显示问题,需要自行处理
由于 vw 方案是完全的等比缩放,在完全等比还原设计稿的同时带来的一个问题是无法很好的限定一个最大最小宽度值,由于 rem 方案是借助 Javascript 的,所以这一点 rem 比 vw 会更加的灵活
再聊移动端页面的适配
Responsive And Fluid Typography With vh And vw Units
使用VH和VW实现真正的流体排版
1px线
在 dpr = 1 时,此时 1 物理像素等于 1 CSS 像素宽度;
在 dpr = 2 时,此时 1 物理像素等于 0.5 CSS 宽度像素,可以认为 border-width: 1px 这里的 1px 其实是 1 CSS像素宽度,等于 2 像素物理宽度,设计师其实想要的是 border-width: 0.5px;
在 dpr = 3 时,此时 1 物理像素等于 0.33 CSS 宽度像素,设计师其实想要的是 border: 0.333px
渐变实现
使用缩放实现
使用图片实现(base64)
使用SVG实现(嵌入 background url)
图片适配及优化
消除多余的图像资源
尽可能利用 CSS3\SVG 矢量图像替代某些光栅图像
谨慎使用字体图标,使用网页字体取代在图像中进行文本编码
选择正确的图片格式
为不同 DPR 屏幕提供最适合的图片尺寸
无脑多倍图
srcset 配合 1x 2x 像素密度描述符
<div class='illustration'>
<img src='illustration-small.png'
srcset='images/illustration-small.png 1x,
images/illustration-big.png 2x'
style='max-width: 500px'/>
</div>
当屏幕的 dpr = 1 时,使用 images/illustration-small.png 这张图
当屏幕的 dpr = 2 时,使用 images/illustration-big.png 这张图
srcset 属性配合 sizes 属性 w 宽度描述符
<img
sizes = “(min-width: 600px) 600px, 300px"
src = "photo.png"
srcset = “[email protected] 300w,
[email protected] 600w,
[email protected] 1200w,
>
sizes = “(min-width: 600px) 600px, 300px"
的意思是,如果屏幕当前的 CSS 像素宽度大于或者等于 600px,则图片的 CSS 宽度为 600px,反之,则图片的 CSS 宽度为 300px。
srcset = “[email protected] 300w, [email protected] 600w, [email protected] 1200w
里面的 300w,600w,900w 叫宽度描述符。怎么确定当前场景会选取哪张图片呢?
1. 当前屏幕 dpr = 2 ,CSS 宽度为 375px。
300 / 300 = 1
600 / 300 = 2
1200 / 300 = 4
2. 当前屏幕 dpr = 3 ,CSS 宽度为 414px。
300 / 300 = 1
600 / 300 = 2
1200 / 300 = 4
3. 当前屏幕 dpr = 1 ,CSS 宽度为 1920px。
300 / 600 = .5
600 / 600 = 1
1200 / 600 = 2
Google Web Fundamentals -- Web Responsive Images
响应式图片srcset全新释义sizes属性w描述符
字体适配方案
字体大小
PC上最小 font-size=12px
手机上最小 font-size=8px
字体的选择展示
兼顾各个操作系统
{
font-family:
system-ui,-apple-system,BlinkMacSystemFont,segoe ui,Roboto,
Helvetica,Arial,
sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol;
}
font-family 关键字
font-family
而言,它有两类取值。
一类是类似这样的具体的字体族名定义:
font-family: Arial
这里定义了一个具体的字体样式,字体族名为Arial
;一类是通用字体族名,它是一种备选机制,用于在指定的字体不可用时给出较好的字体,类似这样:
font-family: sans-serif
。
sans-serif
表无衬线字体族,例如, "Open Sans", "Arial" "微软雅黑" 等等。
serif 衬线字体族
sans-serif 非衬线字体族
monospace 等宽字体,即字体中每个字宽度相同
cursive 草书字体
fantasy 主要是那些具有特殊艺术效果的字体
新增通用字体族关键字
system-ui 系统默认字体
emoji 用于兼容 emoji 表情符号字符
math 适用于数学表达式
fangsong 此字体系列用于中文的(仿宋)字体。
system-ui
。
system-ui
font-family: system-ui
的目的就是在不同的操作系统的 Web 页面下,自动选择本操作系统下的默认系统字体。
font-family: system-ui
字体设置的优势之处在于它与当前操作系统使用的字体相匹配,对于文本内容而言,它可以得到最恰当的展示。
San Francisco Fonts
system-ui
字体族。但是像 -apple-system
、BlinkMacSystemFont
没有在最新的标准里出现。它们又代表什么意思呢?
San Francisco Fonts
。
San Francisco Fonts
又叫旧金山字体,是一款西文字体。随着 iOS 9 更新面世,在 WatchOS 中随 Apple Watch 一起悄然发售,并且还将在 Apple TV 上的新 tvOS 中使用。
San Francisco Fonts
在 iOS 系统上用于替代升级另外一款西文字体 Helvetica Neue
。Apple 做了一些重要的改变,使其成为平台上更好的, 甚至是完美的西文字体。
-apple-system/BlinkMacSystemFont
system-ui
的普及很快。Chrome 和 Safari 都可以在各种平台上完全支持它。只有 Mozilla 和 Windows 相对落后。
system-ui
的兼容性,Can i Use -- system-ui(图片截取日 2019-08-13):
Supported as the -apple-system value (only on macOS and iOS)
Supported as the BlinkMacSystemFont value (only on macOS)
-apple-system
及 BlinkMacSystemFont
来兼容适配 system-ui
标准。
Segoe UI
font-family: Segoe UI
可以在 Windows 平台及 Windows Phone 上选取最佳的西文字体展示。
Roboto
总结一下
{
font-family:
system-ui,-apple-system,BlinkMacSystemFont,segoe ui,Roboto,
Helvetica,Arial,
sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol;
}
system-ui,使用各个支持平台上的默认系统字体
-apple-system, 在一些稍低版本 Mac OS X 和 iOS 上,它针对旧版上的 Neue Helvetica 和 Lucida Grande 字体,升级使用更为合适的 San Francisco Fonts
BlinkMacSystemFont,针对一些 Mac OS X 上的 Chrome 浏览器,使用系统默认字体
segoe ui,在 Windows 及 Windows Phone 上选取系统默认字体
Roboto,面向 Android 和一些新版的的 Chrome OS
Helvetica,Arial,在针对不同操作系统不同平台设定采用默认系统字体后,针对一些低版本浏览器的降级方案
sans-serif,兜底方案,保证字体风格统一,至少也得是无衬线字体
font-family
的定义不一定是最佳的。譬如天猫移动端在 font-family
最前面添加了 "PingFang SC",miui,..
必定也有他们的业务上的考虑。但是一些 fallback 方案向后兼容的思想都是一致的,值得参考学习。
你该知道的字体 -- font-family
Web 字体 font-family 再探秘
Using UI System Fonts In Web Design: A Quick Practical Guide
System Fonts in CSS
Apple’s San Francisco Font
前端布局的兼容适配
布局发展历程
text-align: justufy
可以 hack 实现,等等等等。
.container {
display: flex;
justify-content: space-between;
align-items: center;
}
.container {
display: flex;
}
.item {
margin: auto;
}
CSS Grid Layout
最后
END
回复“加群”与大佬们一起交流学习~