总结了一下最近做的一个插件,及其背后引发的一些问题。
插件:CSS3背景图片切换动画
预览效果 源码下载
注:文中插件在Github上,例子在JSBin
思路:
-
样式不难,但因为有切换效果,所以就变得复杂了:
-
本来背景图片要用1个div,但这样就无法实现5种不同的切换效果,因此改用5个div;
-
用5个div而不是5个img是因为这样避免图片被拉伸;
-
因为是点击时切换,本来想用jquery,但感觉很麻烦,还要让元素动画后恢复原位置等,于是想用CSS3;
-
用CSS3的话,因为不是hover时修改属性,感觉无法用transition,最后用了target伪类、animation和keyframe来做。
-
-
选中(活动)时,出现相应的动画,
rotate
和scale
一起时,中间用空格
.rotate:target{
z-index: 10;
animation:rotate 1s 1;
-webkit-animation:rotate 1s 1;
}
@-webkit-keyframes rotate{
0%{transform: rotate(-360deg) scale(0.1);}
100%{transform: rotate(0) scale(1);}
}
-
因为设置的是背景全屏,
height:100%
时,需要给html和body也设置height:100%
才会有效。给body设置了最小宽度,确保ul不会换行。 -
用了
nth-child
属性
问题1:
.bg
的position不用fixed,用absolute(Line23);.body加overflow:hidden(Line17)时;图2的变换效果时会出错(好像没有脱离文档流一样);浏览器窗口<920px(body的min-width)时不能保证所有ul都显示,为什么?是否关系到position:absolute
和position:fixed
的区别?预览问题效果
- 高度100%。如果
.bg
不设置绝对定位且没有定位的父元素,则2个.bg
的高度会分别=视图的高度=html高度,且出现滚动条。问题:为什么此时HTML的高度不等于文档的高度?HTML不是代表整个文档吗?猜想:应该是类似于在固定宽高的容器内放入了比容器大的内容,容器的大小是不变的,但内容会溢出来。- 例子1预览效果
HTML代码:
- 例子1预览效果
<div class="bg bg1"></div>
<div class="bg bg2"></div>
CSS代码如下:
html,body{width: 100%;height: 100%;margin: 0;padding: 0;}
.bg{width: 100%;height: 100%;}
.bg1{background: url(http://p1.bpimg.com/576696/cdbcb7e403358881.jpg) left no-repeat;background-size: cover;}
.bg2{background: url(http://p1.bpimg.com/576696/2e26477499566853.jpg) left no-repeat;background-size: cover;}
- 绝对定位与脱离文档流。先不思考第1点,继续研究我们上面提出的问题1,猜想:因为绝对定位虽然脱离了文档流,但是并没有脱离整个文档,也是会影响文档的大小的。
- 例子2预览
HTML结构:
- 例子2预览
<div class="bg bg1"></div>
<div class="bg bg2"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ea quae quam suscipit eum iste deserunt repellendus ducimus accusantium vero nemo, vitae rerum quisquam dolor facilis quis neque, est esse, autem.</p>
CSS代码如下:
html,body{width: 100%;height: 100%;margin: 0;padding: 0;}
.bg{position: absolute;top: 0;left:0;}
.bg1{
width: 100%;
height: 100%;
background: url(http://p1.bpimg.com/576696/cdbcb7e403358881.jpg) left no-repeat;
background-size: cover;
}
.bg2{
left: 50px;
width: 100%;
height: 1200px;/* 设置得比窗口高度大 */
background: url(http://p1.bpimg.com/576696/2e26477499566853.jpg) left no-repeat;
background-size: cover;
}
以上例子2说明:2个.bg
虽然脱离了文档流,将p
覆盖住了,但.bg2
将整个文档的高宽都撑开,出现了滚动条。说明,即使绝对定位,也是影响文档大小的。
- 例子3预览
HTML结构:
<div class="wrap">
![](https://img.haomeiwen.com/i4047954/629e2191a77f91b5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
</div>
CSS代码如下:
html,body{margin: 0;padding: 0;}
.wrap{position: absolute;left: 50%;}
.wrap img{position: relative;left: -50%;}
以上例子3不定宽块状元素水平居中时,出现了水平滚动条,再次说明了绝对定位是会影响文档大小。如果把.wrap
改为position:fixed
则不会出现滚动条,但前提是.wrap
没有外嵌套父容器,否则只能用overflow:hidden
了。
总结:
- 图2的变换效果时会出错,是因为
position:absolute
虽然脱离文档流,但依然会影响文档的大小; - 浏览器窗口<920px(body的min-width)时不能保证所有ul都显示,是因为前面为了不让图2变换时出现滚动条而给
body
设置了overflow:hidden
问题2:
为什么选中任意圆形图标切换背景时,.bg:not(:target)
(Line165)只选中当前最顶的背景,而不会选中其他当前没有活动的.bg呢?预览问题效果,点击审查元素,当切换任意动画的时候,查看几个.bg
的z-index值。
网页一打开的时候,所有的.bg
的z-index
都是5,说明动画是对所有非活动的.bg
有效的。但当前有活动.bg
时,:not(:target)
只对当前已target的.bg
有效了。猜想:需满足2个条件:切换和动画。
- 例子4预览效果
HTML结构:
<a href="#img1">图1</a>
<a href="#img2">图2</a>
<a href="#img3">图3</a>
<a href="#img4">图4</a>
<a href="#img5">图5</a>
![](https://img.haomeiwen.com/i4047954/9859a63e6349192d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i4047954/5fde9acd2a5b7017.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i4047954/8ab42330b0316d15.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i4047954/a9d3014b1f061d86.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i4047954/dbebb4640692a48a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
CSS代码如下:
img{display: block;width: 500px;}
img:target{border: 2px solid red;}
img:not(:target){border: 2px solid yellow;}
img:not(:target){
animation:notTarget 5s 1;
-webkit-animation:notTarget 5s 1;
}
@-webkit-keyframes notTarget{
0%{width: 800px;}
100%{width: 400px;}
}
@keyframes notTarget{
0%{width: 800px;}
100%{width: 400px;}
}
@-moz-keyframes notTarget{
0%{width: 800px;}
100%{width: 400px;}
}
通过以上例子的预览效果,说明问题2的猜想是正确的,当:not(:target)
选中元素有动画属性时,动画效果只对被切换的元素有效,而不会对所有非活动元素有效。
网友评论