在变化的布局中动态裁剪图像技术

By | 2016年6月22日

在一个布局大小自由变化的页面中,固定宽度的图像会由于布局宽度的变化而出现溢出问题。使用此技术可以通过动态裁剪背景图像和前景图像以适应宽度变化的布局。

由于布局大小改变导致图像占用的区域大小发生变化,此时图像本身也需要做相应调整。当图像的尺寸不大,没有超出布局的边界的时候不会有任何问题。当然还有很多种方法可以动态改变一个图像在屏幕上占用的区域大小,比如给图像指定最小的宽度。

我已经写了很多关于改变图像占用屏幕大小的文章,但是我们现在讨论另一种方式:动态调整图像显示出来的部分。这种方式不改变图像本身的大小,而是改变图像可以在页面上显示出来的部分大小,在允许显示区域之外的那部分图像将会被隐藏。我给这种方式命名为“动态剪切”。

对于前景和背景图像,你都可以实现动态剪切的效果。虽然看上去差不多,但是这两种方式适应于不同的情况。

动态裁剪背景图像

如果图像只是起到装饰作用,那么毫无疑问应该使用背景图像剪切技术。这种技术可以将你要剪切的图像与其他装饰的图像一起放在CSS中,这样的话如果你的网站外观发生的变化,所有装饰的图像都可以通过修改一个CSS文件来实现,而不用在网站的多个页面上分别调整。将装饰性的图像在CSS中定义为背景还有一个好处,就是当用户打印页面的时候,可以禁止打印背景图像(大多数浏览器默认是禁止的),用户可以只专注于保存需要的内容。

如果要使用CSS背景图像,必须先要有一个区域来放置背景。下面的例子使用div元素来实现:

<div id="background"></div>

这是一个空的div元素;不包含任何内容,它的存在只是为了放置一个背景图像,你可以使用一个更符合情景的元素来代替它。比如,你可能想要动态裁剪一个在h3元素上方的图像以适应宽度。你可以给这个h3元素增加一个背景图像,给h3元素设置足够的top padding值,就可以保证文字显示在图像的下方,而不是上方。

接下来,为这个div元素设置一个非平铺的背景图像:

div#background {
  background: url(styx.jpg) no-repeat;
  border: 2px solid #000;
}

我给这个div元素增加了一个border属性以便于清楚的看到它的边界位置。现在,由于div元素中没有包含内容,它的高度缩小为0。需要加入width和height属性“打开”这个div。

div#background {
    width: 50%; 
    height: 330px;
    background: url(styx.jpg) no-repeat;
    border: 2px solid #000;
}

Tip:如果想要使高度也可以动态改变,需要为height使用可变的设置,像width一样(如上面的50%)

将宽度被设置为动态的值,比如使用一个百分比,像我上面做的那样,也可以使用em单位,这样div可以随着width的改变而动态调整图像的显示部分。如果将高度设置为一个固定像素值,图像显示的高度会始终不会变化。

这个div元素的宽度会始终为当前显示视口的50%;它的背景图像尺寸不会发生变化,但是会从右边开始裁剪掉动态大小的一部分。

然而,有时候有些图像从左边开始剪切看上去效果更好,比如一个小猫的头在照片的右边。此时可以通过设置background-position属性,或者它的简写方式来指定图像剪切的方向:

div#background {
    width: 50%;
    height: 330px;
    background: url(styx.jpg) no-repeat right;
    border: 2px solid #000;
}

现在背景图像与div是右侧对齐的,当div的大小改变时会动态从图像的左侧开始剪切。

最终只需要使用上面的CSS定义就可以实现基本的动态剪切技术,但是你可以根据实际需要在CSS中增加其他属性。比如在上面的示例中div的宽度超过图像时,在div中显示空白区域。当然还有其他的方法处理这种情况:
* 给div加一个背景颜色属性来填充空白区域
* 使图像的边缘颜色与div的背景颜色混合,这样看上去效果也不错
* 给div设置一个max-width属性,保证它的宽度不会比图像大
* 在第三个方法的基础上再给div设置min-width,max-height,min-height属性,这样图像就不会被拉伸的显得很诡异

动态裁剪前景图像

如果你想要动态剪切的图像是用来的提供内容的,你应该在(X)HTML中将它作为前景图像放在一个img元素里。当你不确定是否应该将它放在img元素里的时候,你应该首先思考这个图像是一个实际的内容还是只起装饰作用。

这个图像是否传递了一些信息,我需要使用alt属性来指achieve定一个文本吗?
我是否确定打印的时候必须要打印出这个图像,如果缺少这个图像的话打印结果是不正常的或者不完整的?
我是否需要这个图像的链接?

如果上面的问题都是肯定回答,这个图像是一个应该放在img元素里的内容。CSS背景图像实现不了上面的功能-至少在没有做一些hack的情况下实现不了(我保证所有的hack方法都傻的一腿),而一个img元素就可以简单的解决所有问题。

与运用背景图像剪切技术一样,我们需要在(X)HTML中的一个块元素里放置图像。我们也同样使用一个div;不过这次它不会是空的,我们要在里面放一个img元素:

<div id="foreground">
    <img src="styx.jpg" alt="my cat Styx" width="500" height="330">
</div>

注意:img元素的alt属性可以指定一段文本代替图像。背景图像无法实现这个功能

同上个例子一样,这个div元素需要用动态的width和一个px单位的height属性:

div#foreground {
    width: 50%;
    height: 330px;
    border: 2px solid #000;
}

至今,我们只是创建了一个div和一个img,并没有用到动态剪切技术。如果这个图像的大小超出了div,它不会被剪切,而是会溢出。
要实现剪切的效果,加入overflow属性:

div#foreground {
    overflow: hidden; 
    width: 50%;
    height: 330px;
    border: 2px solid #000;
}

现在任何超出div的图像部分都会被隐藏。
现在解决同样的问题,如何使图像剪切的方向变成左边。由于这不是一个背景图像,所以无法使用background-position属性。我们可以使这个图像浮动到另一个方向:

div#foreground img {
    float: right;
}

图像固定在div的右边,所以当div大小改变的时候图像会动态调整左边显示的区域。使用前景图像看上去与使用背景图像效果差不多,但是我们可以给它加上alt属性,也很容易给它加上一个链接。

翻译自http://zomigi.com/blog/hiding-and-revealing-portions-of-images/
个人blog:http://www.qintianxiang.com,转载请注明出处,非常感谢

发表评论

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