一,响应式网页设计
响应式网页设计( RWD,Responsive Web Design) 这个术语,由伊桑・马科特( Ethan Marcotte )提出。他在AList Apart发表了一篇开创性的文章,将三种已有的开发技巧(弹性网格布局、弹性图片、媒体和媒体查询)整合起来,并命名为响应式网页设计。这个术语还有一堆表示相同意思的其他叫法,如流式设计、弹性布局、塑料布局、流体设计、自适应布局、跨设备设计以及弹性设计。
上面仅列举了其中一部分!不过,正如马科特等人所说,真正的响应式设计方法不仅仅只是根据视口大小改变网页布局。相反,它是要从整体上颠覆我们当前设计网页的方法。以往我们先是针对桌面电脑进行固定宽度设计,然后将其缩小并针对小屏幕进行内容重排;现在我们应该首先针对小屏幕进行设计,然后逐步增强针对大屏幕的设计和内容。
如果要用一句话概括响应式网页设计,我觉得它是针对任意设备对网页内容进行完美布局的一种显示机制。相反,如果需要根据不同设备提供特定的内容和功能,那就需要一个真正的“手机版”网站。这种情况下,手机版网站会提供与桌面版网站完全不同的用户体验。
响应式布局有两个缺点:
首先,原本设计师就给了一个尺寸的设计稿,其他的尺寸的实现效果本质上是工程师和浏览器的自由发挥,设计师无法再对工程师实现页面的还原度做100%的把控,这对很多设计师来说是不可接受的事。
其次,理论上来说工程师基于一个设计稿实现的页面在其他设备也能合理展示,但毕竟有很多不可控的因素在,保不准在428的屏幕上看起来OK,但在320的屏幕上某个按钮被挤了下去。开发工程师和测试工程师需要在尽可能多的真实设备上确认效果,对展示有问题的地方用媒体查询做微调。但这样这样间接增加了工作量。
二,页面等比缩放
所谓的页面等比缩放,就是设计师基于一个尺寸做一套设计图,开发工程师会基于设计图100%还原页面。在不同屏幕上的视觉呈现比例完全一致。以下图为例,屏幕尺寸虽有差异,但同一页面视觉效果完全一样,页面内容等比缩放。
这种方式最大的优点是简单、可控。设计师能对不同屏幕尺寸手机的展现效果做绝对的把控,测试工程师也不用担心漏测了某款机型出现样式错乱自己没有发现,开发工程师也可以一套代码满足任何场景。你好我好大家好。
当然,这种“偷懒”的适配思路也不见得完美。手机屏幕之所以越来越大,本意是想展示更多的内容,而不是让文字图片越变越大。反过来看,如果文字图片在IPhone12 Max Pro上看起来展示合理,在IPhone 6s上会小的像蚂蚁。
等比缩放适配的具体方案:
方案一,动态rem方案(常用方案)
在使用单位控制页面元素大小时,可以使用固定单位px,也可以使用相对单位rem。
举个实际的例子。设计师交付的设计稿宽度是750px,设计稿上一个div的标注尺寸是375px(宽度是设计稿宽度的一半)。
(function () { function changeRootFont() { var designWidth = 750, rem2px = 100; document.documentElement.style.fontsize = ((window.innerWidth / designWidth) * rem2px) + 'px'; //iphone6: (375 / 750) * 100 + 'px'; } changeRootFont(); window.addEventListener('resize', changeRootFont,false); })();
这段代码不难懂吧,可以看到,我们通过动态的获取设备独立像素,然后除以设计稿的宽度,然后赋给根字体的fontsize,以致来动态改变跟字体大小,做到自适应。但至于为什么要乘100,首先375 / 750是0.5,浏览器默认最小字体为12px,所以我们需要放大一些,而100又很好算,我们只需要将设计稿量出来的长度(px),小数点向左移2位,单位变成rem就好了。
更详细的代码参考:https://javascript.net.cn/article?id=641
方案二,viewport缩放方案
页面开发好后,在HTML的head标签里加入 <meta name="viewport" content="width={设计稿宽度}, initial-scale={屏幕逻辑像素宽度/设计稿宽度}" > 。
举个例子。假设设计师交付的设计稿宽度是750px,设计稿上一个标题字号标注的是32px 、margin是20px。我们以标注的大小来写CSS。之后需要通过JavaScript计算获取屏幕的宽度(假设需要适配逻辑像素宽度是428px的屏幕),在HTML的head里添加<meta name="viewport" content="width=750px, initial-scale=0.57" > 即可(428/759 = 0.57)。
这段代码的意思是:设置布局视口(layout viewport)的宽度为750px(此时页面一般会超出屏幕),再缩放页面(initial-scale)使其恰好撑满屏幕。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> const WIDTH = 750 const mobileAdapter = () => { let scale = screen.width/WIDTH let content = `width=${WIDTH}, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}` let meta = document.querySelector('meta[name=viewport]') if(!meta) { meta = document.createElement('meta') meta.setAttribute('name', 'viewport') document.head.appendChild(meta) } meta.setAttribute('content', content) } mobileAdapter() window.onorientationchange = mobileAdapter </script> </head> <body> ... </body> </html>
缺点:
该方案有个问题,1px的边框在大屏手机被放大后显得很粗,在小屏手机上被缩小后又显得太细。
方案三,vw适配方案
vw是相对单位,1vw表示屏幕宽度的1%。基于此,我们可以把所有需要适配屏幕大小等比缩放的元素都使用vw做为单位。不需要缩放的元素使用px做单位。
举个例子。设计师交付的设计稿宽度是750px,设计稿上一个标题的fontSize标注尺寸是32px。(32/750)*100% = 4.27% ,换句话说这个标题的字号占屏幕宽度的占比是4.27%,尺寸 = 100vw*设计稿标注大小/设计稿宽度。
假设设计稿尺寸是750px,页面有一个按钮,按钮文字标注大小28px,按钮高度标注为48px,宽度为120px,边框为1px不缩放。
<meta name="viewport" content="width=device-width, initial-scale=1"> <style> .button { width: 16vw; /* 100vw*120/750 */ font-size: 3.73vw; /* 100vw*28/750 */ line-height: 6.4vw; /* 100vw*48/750 */ border: 1px solid #000; /*不需要缩放的部分用px*/ text-align: center; } </style> <div class="button">按钮</div>
缺点:
这个方案计算起来确实太麻烦
三,方案一的补充
方案一的最佳时间是,设计师按750px屏宽出图,程序员把单位全部按rem写代码即可。各种移动设备的屏幕宽度差异不是很大,但是,在PC屏幕或者pad横屏状态下,因为屏幕宽度远大于750了。此时rem根据屏幕宽度变化的结果就严重脱离了预期,大的惨不忍睹。所以可以设置一个“基准屏宽”,超过这个值就不在放大。基准屏宽有人推荐为960px。
参考:
《响应式Web设计 HTML5和CSS3实战》
https://javascript.net.cn/article?id=641
https://blog.csdn.net/weixin_36029647/article/details/112722248
https://uniapp.dcloud.io/adapt
修改时间 2021-11-23