我们在做移动端开发的时候经常遇到这样的需求:界面背景要刚刚好在整个屏幕中,不能超出屏幕,而且肯定还有一些元素要固定在界面中某个位置。
比如这样的设计图( 720 x 1280
的尺寸),我们不仅仅要这个背景不超出屏幕,而且城堡里的图标要不偏不倚地在城堡中的那个位置。
这样分析一下我们就知道了我们要解决的问题:
1.背景图片不能变形
2.元素位置要固定
现在一般的做法:整张图片当做背景, background-size
为 100% 100%
,页面元素百分比绝对定位。
狠狠戳 demo
从demo可以看出元素定位的问题用 absolute
+ 百分比
解决了 ,但是背景变形了(把 .wrap
的 background-size
值改成 contain
试试)。为了不让这种变形更加夸张,给 .wrap
添加了 min-width
和 max-width
。
这个方法还可以优化一下:
1.背景图,因为现在背景图都 188kb
了。可以把背景图切成几分铺在底层, demo
2.logo等绝对不能变形的图片就要单独用 img
引入,然后 absolute
定位
如果允许背景图片一点点地变形以及限定尺寸范围,那么使用上面的方法简单、迅速,很多情况下也都是这么做的。
今天介绍的是一种新方法,背景不会变形且定位准确。
最近在做一个新页面的时候,我不满足于上面的方法,就想看看有没有别的解决办法。要图片在容器中不变形的最好办法就是 background-size:contain
了。看看我们现在的 进展 ,这个页面完美适应窗口,且不会变形。那怎么让元素定位在不确定 contain
以后宽高未知的背景图上呢?
谁说宽高未知的?看下图:
背景 contain
以后不就是这两种情况么?这在我之前的博客 CSS Contain&Cover的数学公式 里介绍过,之前一直以为没什么用的结论可以在这里用上。
参考上面的文章,我们有了这样的思路: viewport
在这里就是 window
, image
在这里是 .container
。然后加上这个结论( contain
部分)我们不难得算出背景图在 contain 以后的宽、高。
在之前的 基础 上,添加计算背景图宽、高的逻辑:
var $appContainer = $('.app-list'), $window = $(window), winWidth = $window.width(), winHeight = $window.height(); var rWindow = winWidth / winHeight, rContainer = 720 / 1280, scale = 1; if(rWindow<=rContainer){ var height = winWidth / rContainer; $appContainer .width(winWidth) .height(height) }else{ var width = winHeight * rContainer; $appContainer .height(winHeight) .width(width) }
还要在样式上保证 .app-list
是居中的:
.app-list{ position: absolute; left:50%; top:0; -webkit-transform:translate(-50%,0); transform:translate(-50%,0); }
这样就可以看到,无论窗口怎么变化 .app-list
始终和 .container
的背景图贴合在一起:
狠狠戳 demo
还剩一个定位问题了,很简单,这里就只做了两个 icon
的定位。查看 完整demo
至此,你可以随意改变窗口的大小,而页面一直都会保持在整屏中,而且不会变形,其中的元素也可以定位准确,基本上满足了整屏页面的所有问题。