图片 19

图片方面的自适应处理——Flexible Images

Posted by

CSS Contain 和 Cover 的数学公式

2015/11/01 · CSS ·
Contain,
Cover

本文作者: 伯乐在线 –
risker
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

background-sizecontain
cover是怎么用的,大家应该都明白。但是里面也有一些有趣的数学关系。

<h2>模板</h2>

基本概念

图片 1

上面就是我们对于 rimage (图片宽高比)、rviewport
(容器宽高比) 的定义。

假设我们有一个两栏自适应的布局,在主内容中应用了一个图片,其结构如下:
<div class="figure"> <div class="inner"> ![](http://upload-images.jianshu.io/upload_images/2244949-f80854741861cd7f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <p class="figcaption">Lo, the robot walks</p> </div> </div>

将图片放进容器

这是一个很常见的结构,其效果就是一张图片,图片下面有一个简单的文本描述。在整个效果中,针对figure
内元素写了一点样式
//SCSS .figure { float: right; margin: 0.5em 0; margin-left: 1.9672131%; //12px/610px width: 45.9016393%; // 280px/610px .inner { border: 10px solid hsla(333,50%,60%,.8); border-radius: 10px; } img { vertical-align: top; } p { background-color: hsla(333,50%,60%,.8); padding: 10px 10px 0; color: #fff; } }

三种方法

  • stretch : 把图片的宽高强行设置为容器的宽高

图片 2

注:
h’image、w’image、r’image分别为图片改变后的高、宽、宽高比。之后文章这些名词也是这个意思,不再解释。

stretch的方式可想而知后果:

图片 3

那么保持怎样的数学关系才能保证图片放进容器之后不会变形呢?
答案也是明显的:

r’image = rimage

接下来介绍的两种方法就是不会变形的,也就是说能够上面的公式对于它们来说是已知条件。

  • contain :
    让图片适应容器,我们把它“装”进容器,同时也会留下空白。就像我们看电影时的”黑边”。

对于contain方法来说,也只有图片放进容器后的高度( h’image
)是未知的,我们来算一下:

图片 4

如果不知道contain为什么是这样的建议先看看background-size

  • cover : 也可以让图片“遮”住容器。

contain对应,cover方法要来算一下 w’image

图片 5

从上面的代码中我们可以想像出我们要的效果,figure占整个容器.content宽度的”45.9016393%”
也就是”280px/610px”。虽然整个布局是自适应布局,但图片依旧撑破容器:

宽高比的影响

不知道大家注意到没有,刚才我们推导contain的 h’image
cover的 w’image
时使用的图片的宽高比总是大于容器的宽高比。

这导致了什么?导致了我们推导时使用的 条件3 是不一定正确的。
额,这么说我也有点晕,看图:

图片 6

可以看到,我们只考虑了 rimage >
rviewport的情况。

图片 7

结论

我们考虑rimage <
rviewport后加完整了,图片放进容器之后的宽、高如下:

图片 8

这样我们就求到了图片在应用background-size属性之后在容器中实际的宽、高。

比例 hidden

现在讨论图片放进容器后的图片与容器的比例关系hidden,这样我们就可以以此关系让图片随着容器的变化而变化。
注意,hidden是一个小于1的比例,至于为什么要这样设定后面有解释。

contain布局为例,rimage > rviewport :

图片 9

而以cover布局为例,rimage > rviewport :

图片 10

以此类推,得到所有情况的 hidden

图片 11

这样可以看到四种可能性,但是别忘了我们在上面可是推导过
w’image 、h’image

所以hidden最终的结果是:

图片 12

可以看出来,hidden就只有两种结果,rimage /
rviewport
r viewport /
rimage
,而且这个数是小于1的(这是上面就确定的)。

所以,hidden的计算可以简化为:

图片 13

Flexible Images

后记

你可能想,搞了半天,这到底能干吗?直接用background-size不就好了,为什么还要得到具体的宽、高,得到了伸缩比又能怎么样。
我也想了想,如果只是图片,似乎上面都是废话。但如果是DOM呢?这是不是就是一种布局方式?

我也不知道,知识有时候就是这样。当你需要用到的时候,你才觉得有用。

这并不是我们想要我效果,我们真正想要达到的效果应该是这样的,换句话说理想中要的将是下图的效果:

参考文章

CSS – Contain &
Cover

我的博客,欢迎订阅

微博粉丝太少,求粉

1 赞 收藏
评论

图片 14

关于作者:risker

图片 15

2014年大学毕业,现在在北京某互联网公司从事前端开发的工作,近半年主要做移动web开发。微博粉丝太少,求粉。

个人主页 ·
我的文章 ·
7 ·
  

图片 16

Flexible Images

那接下来,我们观注的就是,如何让我们的效果达到上图所示的效果。

方案一:max-width
在介绍响应式设计的文章中,为了解决图片的自适应问题,都会提到使用max-width
。Richard
Rutter设计首先提出使用max-width的方案:
img { max-width: 100%; }
在上面的示例基础上,我们为img添加max-width值为“100%”:

图片 17

Flexible Images

更重要的是,在现代浏览器中发展到可以自动调整图像的比例,可以根据容器的大小缩放或者放大图像,并且图像的宽高比保持不变。
max-width:100%除了可以应用于自适应元素容器上之外也可以应用于固定元素容器上。而且可以应用于视频和其他富媒体上也具有同等的效果。
img, embed, object, video { max-width: 100%; }
不幸的是,max-width属性在IE7以及其以下版本并无法支持。

另外一点,在一些浏览器中仅指定图片的宽度,可能会导致浏览器重新处理布局,调整页面的时间周期会增加两到三倍,虽然周期不到一毫秒,但是累积起来,尤其是页面上有很多个这样的元素的时候,还是或多或少会影响页面的性能。为了解决这个问题,可以显式的指定图片的height值为auto
img { max-width: 100%; height: auto; }
方案二:background-image
在响应式设计中实现图片自适应另一种方案可以采用background-image。因为在CSS3有一个background-size
属性可以让我们的背景图片适应容器大小。
先简单的来模拟一个效果,基于上例的基础上,我们将模板结构做一下调整:
<div class="figure"> <div class="inner"> <div class="image-wrapper"></div> <p class="figcaption">Lo, the robot walks</p> </div> </div>
将图片变成背景图片应用于image-wrapper容器之上。
//SCSS .figure { float: right; margin: 0.5em 0; margin-left: 1.9672131%; //12px/610px width: 45.9016393%; // 280px/610 .inner { border: 10px solid hsla(333,50%,60%,.8); border-radius: 10px; } .image-wrapper { width: 100%; background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center; min-height: 100px; background-size: cover; } p { background-color: hsla(333,50%,60%,.8); padding: 10px 10px 0; color: #fff; } }
可以清楚的看到,在<code>.image-wrapper</code>应用了背景图片,并且配合了<code>background-size:cover</code>一起使用:
<code>.image-wrapper {
width: 100%;
background:
url(“http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg”)
no-repeat center;
min-height: 100px;
background-size: cover;
}
</code>
不过这里让你为难的是,在<code>.image-wrapper</code>容器中没有任何内容,以至于无法撑开容器的高度,因此想正常的显示出图片,那必须给容器指一个准确的高度或一个最小高度,言外之意,我们宽度可以自适应,但比例不会根据图片的宽高比例来定,另外图片会进行截取,如示例所示:

图片 18

Flexible Images

<p>很显然,这样的效果不理想,不是我们所需要的效果。那有什么方法可以让背景图片根据自身的比例来自适应呢?</p>

<p>在响应式设计中,布局可以根据设备调整宽度。就算是用百分比调整宽度,也会自动按比例调整元素的高度。换句话说,其宽度比例保持不变来调整大小。如果我们要使背景图片达到同等的效果,我们就必须得知道如何保持任何HTML元素的纵横比例。</p>

<p>针对这个问题,Rolf Timmermans 写了一篇文章<a
href=”
background images with fixed or fluid aspect
ratios</a>,文章中介绍了如何解决背景图像的固定和流体的纵横比例。接下来我们一起来看看Rolf Timmermans是如何实现的。</p>
<h3>

固定纵横比例</h3>

<p>在保持背景图片的纵横比例,关键之处是是让背景图片垂直居中。而其中主要是基于宽度的百分比来设置内距<code>padding</code>的百分比值。这种技术早前在<a
href=”;

图片 19

Flexible Images

<p>假设我们有一张700像素宽和467像素高的图像。当宽度改变时,我们需要维护其纵横向比例是“16:9”。下面有一个示例,我们使用像素为单位,当然也可以使用<code>em</code>为单位,但我们的结构和前面示例一样:</p>

<pre>
<code><div class=”figure”>
<div class=”inner”>
<div class=”image-wrapper”></div>
<p class=”figcaption”>Lo, the robot walks</p>
</div>
</div>
</code></pre>

<p>一般情况之下,我们知道图片的尺寸大小,根据纵横比例,我们可以通过下面的公式计算出内距<code>padding-top</code>或<code>padding-bottom</code>的百分比值:</p>

<pre>

<code>padding-top或padding-bottom = (背景图片高度 / 背景图片宽度)
* 100%

</code></pre>

<p>根据这个公式,可以轻松计算出:</p>

<pre>

<code>padding-top(或padding-bottom) = 467 / 700 = 0.667142857 =
66.7142857%

</code></pre>

<p>如此一来,我们可以将前面的示例调整为:</p>
<code>//SCSS
.figure {
margin: .5em;
//背景图像宽度必须宽度为700px
max-width: 700px; //图片的宽度
.inner {

border: 10px solid hsla(333,50%,60%,.8);

border-radius: 10px;

}

.image-wrapper {

background:
url(“http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg”)
no-repeat center;

background-size: cover;

padding-top:66.7142857%; // 467px / 700px = 0.667142857

}

p {

background-color: hsla(333,50%,60%,.8);

padding: 10px 10px 0;

color: #fff;

相关文章

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注