这篇文章是99翻译Nicolas Gallagher 的CSS background image hacks 一文。大家都知道,目前有很多浏览器无法实现背景裁切、背景透明度、背景变换和复杂背景定位等效果。那么这篇文章将详细介绍了这几种背景图片的处理方法。
正如前面所说,仅仅依靠CSS现有的属性,我们无法实现背景裁切、背景透明度、背景变换和复杂背景定位等效果.为了实现这些效果,我们需要借助CSS的其他方法来实现,比如说CSS伪元素,他可以帮助我们模拟出这些CSS无法实现的效果,在开始了解怎么实现这些效果之前,我们一起来看一些DEMO效果,让我们最初一个概念。
伪元素技巧不需要添加额外的HTML标签就可以填补浏览器对一些CSS特性支持的真空,甚至可以模拟一些还未进入w3c草案的CSS特性,比如今天要说的背景变换、背景透明等等。
今天这篇文章中利用到的伪元素的大部分技巧均在早前的文章Multiple Backgrounds and Borders with CSS 2.1 (如果你看英文有点烦的话,你可以看看由志哥翻译的文章使用css2.1实现多重背景、多重边框效果)有做过详细介绍,在这篇文章中已经详细讲解了怎样利用伪元素模拟CSS的多背景特性和CSS多边框的特效,文章的Multiple Backgrounds with CSS 2.1 和Multiple Borders with CSS 2.1 页也展现了一些利用伪元素来实现其他特性的基本原理。
模拟背景剪裁这种方法制作的背景剪裁,目前知道的就支持:Firefox 3.5+, Opera 10+, Safari 4+, Chrome 4+, IE 8+
利用css2.1即可模拟背景裁切效果。原理是把背景图片作为伪元素的背景,而不是作为原本容器的背景。下面第一个例子的效果是裁剪一部分背景,第二个效果可以裁剪css sprite,利用这个特性来制作文字旁边的小图片:
某种程度上,相比其他可用的方法使用伪元素是有优势的,伪元素结合了一些方法的优点,而某种程度上又可以规避他们的缺点
Google、facebook、 twitter 均使用空白dom元素来裁切他们复杂sprites,用来实现界面上链接旁的图标效果。
伪元素也可以用类似空白dom元素应用的方式来使用。同时,使用伪元素不需要依赖额外的html标签,而且不会过分依靠sprites。此方法的缺点是ie6,7浏览器不支持。利用此种方式,可以实现渐进增强,加强支持此特性浏览器页面的表现效果,而低版本浏览器仍采用空白元素的办法,同样可以完美的得到我们想要的效果。
这个例子展示了如何从一张排列紧密的雪碧图中裁切出你需要的图标。裁切尺寸为16*16。只需要创建一个ul列表,在需要生效的部分指定一个class即可
应用样式可以以各种方式展示这个列表,在此基础上我们利用伪元素,这里你完全可以把伪元素当作空白标签来使用 比如span标签。
:Before伪元素的尺寸正好可以匹配sprites的一个网格(即16*16)。同样你可以根据所裁切的部分,随意设置伪元素的尺寸
.actions a:before {
content:"";
float:left;
width:16px;
height:16px;
margin:0 5px 0 0;
background:url(sprite.png);
}
.save a:before {background-position:0 -16px;}
.delete a:before {background-position:0 -32px;}
.share a:before {background-position:0 -48px;}
.comment a:before {background-position:0 -64px;}
有的时候你可能不只在一种状态下设置背景图片,比如说悬浮状态下需要改变背景图片的等。其实,增加hover, focus, active, 与 “.saved”的情况是为了让列表在这些情况下也能正确渲染背景位置。
.save a:hover:before,
.save a:focus:before,
.save a:active:before {background-position:-16px -16px;}
.saved a:before {background-position:-32px -16px;}
将来的替代方案
将来可以用另一种方式来实现。火狐浏览器的私有属性 -moz-image-rect可以裁切背景。但这个属性不被其他浏览器支持,而且可能会被属于css3背景属性草案中的一个标识所取代。据我所知就位图图像而言,现代浏览器对于这个属性没有任何稳定的支持。
模拟背景变换伪元素结合css3 transform的rotate,scale,skew属性,可以模拟背景变换。目前没有提案要求支持背景变换属性,所以伪元素技巧是唯一可以模拟此效果的方法。
旋转背景图片
刚刚讲解的背景图片裁切技术可以减少精灵图中的图片个数。我们也可以用css来实现图片的变形,而不需要使用图形软件处理。
实现上图的效果,其实很简单,其代码如下所示:
.accordion a:before {
content:"";
float:left;
width:16px;
height:16px;
margin:0 5px 0 0;
background:url(sprite.png) no-repeat 0 0;
}
.accordion.open a:before {
-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-ms-transform:rotate(90deg);
-o-transform:rotate(90deg);
transform:rotate(90deg);
}
若想对背景图片应用变换,而不会影响到其他元素,需要使用定位来调整背景图片的位置,详细的可以参考:Multiple Backgrounds and Borders with CSS 2.1 (如果你看英文有点烦的话,你可以看看由志哥翻译的文章使用css2.1实现多重背景、多重边框效果)一文。
这里我们利用了伪元素,给伪元素使用图片,之后利用绝对定位跟z-index属性定位伪元素到内容层的下面即可。
背景图片倒影效果
有时候会对背景图有这样的需求,方法类似,不过这次使用的是transform:scale属性
通过伪元素 利用transform:scaleX(-1), transform:scaleY(-1),
transform:scale(-1,-1) 这三个属性你可以沿着x轴,y轴或者沿着中心轴做镜像对称。
下面的例子展示了伪元素模拟的背景变换是怎样应用在一个翻页链接上的。伪类显示了一张单独的图片,或者一张精灵图的一部分,之后进行变换。
注意rotation不能得到我们想要的效果,需要使用scale操作
.prev a:before,
.next a:before {
content:"";
float:left;
width:16px;
height:16px;
margin:0 5px 0 0;
background:url(sprite.png) no-repeat 0 0;
}
.next a:before {
float:right;
margin:0 0 0 5px;
-webkit-transform:scaleX(-1);
-moz-transform:scaleX(-1);
-ms-transform:scaleX(-1);
-o-transform:scaleX(-1);
transform:scaleX(-1);
}
注:这个属性ie8以下不支持,即使你用ie的变换滤镜,伪元素上也不会生效
未来的解决方案
貌似css草案中没有相关的方案,你不需要依靠额外的标签,只需要伪元素就可以实现背景变换跟背景透视的效果。
模拟背景位置Css2.1的background-position属性计算图片偏移只能从元素左侧跟上侧开始计算。这里可以给伪元素设置背景图片,之后把伪元素作为附加的背景层,即可实现从右侧跟下侧来计算背景偏移了
这个技巧可以很容易的结合其他技巧使用。更多利用伪元素实现background-position的细节可以参考:Multiple Backgrounds and Borders with CSS 2.1 (如果你看英文有点烦的话,你可以看看由志哥翻译的文章使用css2.1实现多重背景、多重边框效果)一文。
在这个例子里伪元素放置到内容层的下面。给伪元素设置的背景图片的大小是500px × 300px,因此我们也要设置伪元素的宽高。
利用绝对定位,我们也可以调整伪元素的位置。
#content {
position:relative;
z-index:1;
}
#content:before {
content:"";
position:absolute;
z-index:-1;
bottom:10px;
right:10px;
width:500px;
height:300px;
background:url(image.jpg);
}
未来解决方案
这里的css草案CSS Backgrounds and Borders module 增强了background-position的效果,使其可以从盒子模型的任何一侧开始计算。到现在为止opera11是唯一可以稳定支持这个属性的浏览器。
模拟背景透明度改变伪元素的透明度跟直接操纵元素的透明度一样容易。
注:Ie8及以下利用滤镜对伪元素设置透明度是无效的
我们可以利用定位把伪元素定位在内容层下面,这样就不会影响内容了。之后利用坐标或者宽高调整伪元素的大小,使其适配内容。之后给伪元素设置背景图片,改变伪元素的透明度就可以了。
#content {
position:relative;
z-index:1;
}
#content:before {
content:"";
position:absolute;
z-index:-1;
top:0;
bottom:0;
left:0;
right:0;
background:url(image.jpg);
opacity:0.7;
}
这几种方法可以说将伪元素运用的是炉火纯青,当然他还是有一些限制的,比如说低版本浏览器的不兼容,就算是在现代浏览器中,伪元素有些效果也不被支持,比如说CSS3的animation属性在Webkit内核下就会有问题,但话又说回来,他的用处还是很多的,使用伪元素来制作阴影效果,如23 Box-shadow Effects ,使用伪来制作对话气泡效果,如Pure CSS speech bubbles 。当然还有很多其他的效果。这里就不一一说了。
最后希望这篇译文对大家有所帮助,特别是帮助大有增长思维。