像图片一样布局
来源:互联网 发布:tbq淘宝权微博 编辑:程序博客网 时间:2024/05/02 02:30
移动端经常会有这样的展示页面,页面中有一些独立的元素,并且伴随各种交互效果、转场动画。
针对页面布局的话,大概有这样的需求:
- 不滚动页面,所有元素均在一屏之类展示
- 像图片那样缩放元素---宽度改变时高度按比例变化
- 背景图需要把浏览器窗口撑满
- 往往项目是独立的,需要快速上线,开发周期短
这种形式页面在正常的文档流中布局显然不太合适,比较传统的做法是这样:
- 布局以绝对定位为主
- 用百分比配合px控制宽高、位置
- 背景图用background-size:cover撑满
- 用css媒体查询来适应多种屏幕
- css搞不定的请js帮忙
布局一个单屏展示页
比如这样一个640*960的设计稿,分背景和按钮两层,要求背景全屏(可以不显示全)按钮定位在精确的位置上。
传统做法
一般会把背景图用background-size:cover显示在一个宽高撑满屏幕的容器上以适应各种屏幕, 这个按钮怎么定位呢,一般是会这样做吧position:absolute;bottom:18%;
模拟一下iPhone5微信中的显示
iPhone4微信中的显示
可以看到iPhone4中按钮错位,原因是当屏幕尺寸改变时,背景图与按钮的尺寸与位置会遵循不同的规则变化。这个例子中的效果貌似还能接受,可有些场景对定位的要求可能比这更高。
解决这个问题一般会用媒体查询针对屏幕做适配吧
@media screen and (max-height: 500px) { .btn{ bottom:12%; }}
Demo 在这里 http://jsbin.com/zugape/edit
如果页面中元素多、定位要求精确,这种做法是比较暴力的。下面是支付宝十年晒单页面中针对不同尺寸屏幕做的适配
/* <=640 */@media screen and (min-width: 319px) and (max-width: 321px) { ...}/* 720 */@media screen and (min-width: 359px) and (max-width: 361px) { ...}/* 1024*768, 2056*1536 */@media screen and (min-width: 383px) and (max-width: 385px) { ...}/* 800 */@media screen and (min-width: 399px) and (max-width: 401px) { ...}/* 1080 */@media screen and (min-width: 539px) and (max-width: 541px) { ...}/* 1200 */@media screen and (min-width: 599px) and (max-width: 601px) { ...}/* 1440 */@media screen and (min-width: 719px) and (max-width: 721px) { ...}/* 1600 */@media screen and (min-width: 799px) and (max-width: 801px) { ...}/* for small screen */@media screen and (max-height: 500px) { ...}/* for iPhone6 Plus */@media only screen and (device-width: 414px) and (-webkit-min-device-pixel-ratio: 3),only screen and (device-width: 375px) and (-webkit-min-device-pixel-ratio: 3){ ...}
总结下这种方式的缺点:
- 要把设计稿中的PX在大脑中换算成%
- 百分比控制宽高是相对于父元素,计算繁琐
- 用媒体查询针对各种尺寸的屏幕做兼容工作繁琐
图片的自适应规则
一张图片如果给他设置<img src="pic" style="max-width: 100%;max-height:100%” />
的话,无论视口大小,他都会显示在视口里面,如图
类似的还有图片作为背景显示时的background-size属性。
background-size: contain:缩放图像的最大值,其宽度和高度都能放入内容区域
background-size: cover:缩放图像的最小值,其宽度和高度都能放入内容区域
当你改变图片的宽度或高度时,图片的另一边会自动按比例缩放,如果div有这种能力多好啊!
vw、vh--为移动而生
vw、vh是CSS3中出现的新的长度单位,vw 相对于视窗的宽度,视窗宽度是100vw;vh 相对于视窗的高度,视窗高度是100vh。
其中视窗指的是浏览器实际显示区域,即window.innerWidth/window.innerHeight的大小。
如 想一个元素的宽是视口宽的一半,只需设置width:50vw
与百分比的异同
乍一看好像和百分比类似,并没发现多少优势,在进行一些尝试之后我总结了一下他们的异同
Tips:其实margin-top/bottom以百分比为单位时他的参照对象并不是父元素的height而是width。详情阅读 doyoe margin系列文章
这些特性可以实现一些之前用CSS难以解决的问题。
相对视口100%高度
由于百分比高度是相对父级的,之前如果想让文档流中的某容器相对视口高度100%,只用css的话得从html>body>element一层层下来都设置height:100%
,而现在只需给元素设置height:100vh
。
height 100% Demo http://jsbin.com/risegu/edit
响应式文字 && 像图片一样布局
先上Demo
百分比方式 http://jsbin.com/vemudo/edit
vw方式 http://jsbin.com/huwido/edit
这两个Demo建议把浏览器模拟成移动设备的样子,拉伸浏览器窗口宽度观察效果。
可以看到当浏览器宽度改变时,百分比Demo中只有元素的宽度发生了变化,而统一使用vw做单位的Demo中文字的大小、元素的高度与宽度均按缩放比例发生了变化,这正是我们想要的“像图片一样布局”的效果。
vmin 与 vmax
还有vw、vh延生出来的单位vmin、vmax。
vmin:关于视口高度和宽度两者的最小值
vmax:关于视口高度和宽度两者的最大值
我觉得这是一组神奇的单位,但是暂时对这个使用场景的理解有限,能想到的场景是一个正方形,height:100vmin;width:100vmin
时,得到的是这个视口中能显示满的一个最大正方形(http://jsbin.com/baheko);height:100vmax;width:100vmax
时得到的是能把这个视口全部显示满的最小正方形(http://jsbin.com/tamasi)。
然后在codepen上找到这样一个demo,他让16:9的视频窗口在视口中自适应http://codepen.io/CreativeJuiz/pen/KzkgL
其他适用场景有待发掘
vw、vh的问题
vw vh 在桌面端浏览器兼容性已经是比较好了,不过在移动端貌似还需要等待,国产安卓浏览器的话UC到现在都不支持真不让人省心。
另外对张鑫旭的视区相关单位vw, vh..简介以及可实际应用场景 中他的结论:vw vh只适用于非定位元素;vh高度值的内部元素不支持百分比%高度 有些疑问,我在测试中并未发现这样的情况,这篇文章写于2012年,不知道是不是这样的情况只发生在当时的浏览器。Demo http://jsbin.com/dineka/edit
rem方案
回头来看我们的布局,vw vh的方案因为兼容性问题只能放弃,重新分析下我们的需求:
其实我们需要那么一个全局的相对单位...
我们可以通过修改这个单位来控制整个布局...
我们可以通过判断屏幕的比例来缩放整个页面以展示全部内容...
然后想到类似手机淘宝的动态rem的方案:所有布局元素单位使用rem,由于rem是相对于根元素的,所以不同屏幕按一定规则控制的font-size 即可兼容各屏幕。
var root = document.getElementsByTagName('html')[0], NATIVE_W = 640;function updateSize() { var w = window.innerWidth; var cw = w / (NATIVE_W / 100); root.style.fontSize = cw + 'px';}window.onload = updateSize;window.onresize = updateSize;
这样的页面一般会有设计稿的,我们需要设置rem和设计稿中px的转换比例。
1rem = 1px 这样固然方便,但是有些浏览器有最小字体的限制。
所以我想让 1rem = 100px。
我们的设计稿一般为640 x 960,这个尺寸是针对iPhone4,设备像素比是2,那么我们实际需要html的font-size为50px。
这样的话假如设计稿中一个元素尺寸为240px x 200px,
那么这个元素需要在屏宽为320px的设备上显示的尺寸是120px x 100px,而我们需要他在布局时设置的宽高是2.4rem x 2rem。
设计稿宽640px 也就是整个页面应为 6.4rem。 所以对应不同宽度的设备时用window.innerWidth(视口宽) / 6.4 得到的就是对应此设备的font-size。
布局时,把设计稿上的尺寸除以100然后把px单位换成rem。
怎么解决比较短的屏幕显示不完全的情况呢,可以先判断一下视口的比例,当视口高宽比低于设计稿宽高比时,缩小html节点的font-size这样就能把内容显示全了
var root = document.getElementsByTagName('html')[0], NATIVE_W = 640, NATIVE_H = 960;function htmlSize() { var cw = 50, w = window.innerWidth, h = window.innerHeight; if ((w / h) > (NATIVE_W / NATIVE_H)) { cw = h / (NATIVE_H / 100); } else { cw = w / (NATIVE_W / 100); } root.style.fontSize = cw + 'px';}window.onload = htmlSize;window.onresize = htmlSize;
Demo http://jsbin.com/rupole/edit
可以试下缩小、拉大窗口布局也会像图片那样相应变化,并且无论窗口是什么样的尺寸,元素都会出现在比较合理的位置,当然,一些特殊情况仍然要用媒体查询来适配。
然后在布局时,其实只要把这段js放在页面中,就rem当成px来用就行了,不需要多考虑啥,这个方案的优点就是构建页面成本低,跨屏显示效果也能满意。
calc
另外有些元素我们想他垂直方向上针对中心定位而不是顶部或底部,比如想让一个小球居中之前大概是这样:
#cir{ width:200px; height:200px; border-radius:100px; background:#888; position:absolute; left:50%; top:50%; margin-left:-100px; margin-top:-100px;}
其实CSS3中有这样一个表达式:calc()(CSS里居然有这玩意,我第一次看到时怀疑是不是SASS或LESS里的),他可以给元素的border、margin、pading、font-size和width等属性动态计算值,例如:top:calc(50% - 1rem)
,这在这种展示页面的布局中是相当有用的,上面的css可以改写成:
#cir{ width:200px; height:200px; border-radius:100px; background:#888; position:absolute; left:calc(50% - 100px); top:calc(50% - 100px);}
Demo http://jsbin.com/gasato/edit
关于更多calc的介绍建议阅读大漠的这篇博文 http://www.w3cplus.com/css3/how-to-use-css3-calc-function.html
遗憾的是这玩意在桌面端浏览器中支持的已经比较好了,不过在移动端的表现令人堪忧,安卓原生浏览器从4.4开始支持,而最新版的安卓UC仍然不支持。
原文地址:https://github.com/xiangpaopao/blog/issues/9
- 像图片一样布局
- 像图片一样布局
- 像table一样布局div
- 图片像幻灯片一样切换
- CSS技巧,像table一样布局div
- CSS技巧,像table一样布局div
- CSS技巧!像table一样布局div
- 像写代码一样写布局
- JTree像QQ一样显示图片
- CSS技巧学习:像table一样布局div
- 像表格table一样对层div进行轻松布局
- 像表格table一样轻松布局div层
- 像table一样布局div的CSS属性详解
- 用div实现像table一样的布局方法
- 用Javascript编写的像Flash一样的图片轮换
- 像flickr一样多选图片一次上传
- 如何写一个像UIImagePicker一样的自定义图片选择器
- 像Booch一样思考
- 分数拆分
- LightOJ-1031 博弈 区间DP
- 【Struts】--Struts1工作原理
- C++反汇编代码分析--函数调用
- 深入理解Java虚拟机 - 读书笔记
- 像图片一样布局
- 各类工程师入门进阶的路线图
- win7-64bit安装office2010出错:需要在计算机上安装MSXML6.10.1129.0
- HDU 5102 The K-th Distance(队列模拟,数组模拟邻接表)
- 实验七:OSPF实验
- JAVA中的static
- HTML属性选择器
- Android 源码系列之<十二>从源码的角度深入理解LeakCanary的内存泄露检测机制(上)
- 欢迎使用CSDN-markdown编辑器