1个CSS3插件引发的问题和思考

2016-12-16  本文已影响0人  妙言Lisa

总结了一下最近做的一个插件,及其背后引发的一些问题。

插件:CSS3背景图片切换动画

预览效果 源码下载
注:文中插件在Github上,例子在JSBin

思路:

  1. 样式不难,但因为有切换效果,所以就变得复杂了:

    1. 本来背景图片要用1个div,但这样就无法实现5种不同的切换效果,因此改用5个div;

    2. 用5个div而不是5个img是因为这样避免图片被拉伸;

    3. 因为是点击时切换,本来想用jquery,但感觉很麻烦,还要让元素动画后恢复原位置等,于是想用CSS3;

    4. 用CSS3的话,因为不是hover时修改属性,感觉无法用transition,最后用了target伪类、animation和keyframe来做。

  2. 选中(活动)时,出现相应的动画,rotatescale一起时,中间用空格

.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);}
        }
  1. 因为设置的是背景全屏,height:100%时,需要给html和body也设置height:100%才会有效。给body设置了最小宽度,确保ul不会换行。

  2. 用了nth-child属性

问题1:

.bg的position不用fixed,用absolute(Line23);.body加overflow:hidden(Line17)时;图2的变换效果时会出错(好像没有脱离文档流一样);浏览器窗口<920px(body的min-width)时不能保证所有ul都显示,为什么?是否关系到position:absoluteposition:fixed的区别?预览问题效果

  1. 高度100%。如果.bg不设置绝对定位且没有定位的父元素,则2个.bg的高度会分别=视图的高度=html高度,且出现滚动条。问题:为什么此时HTML的高度不等于文档的高度?HTML不是代表整个文档吗?猜想:应该是类似于在固定宽高的容器内放入了比容器大的内容,容器的大小是不变的,但内容会溢出来。
<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点,继续研究我们上面提出的问题1,猜想:因为绝对定位虽然脱离了文档流,但是并没有脱离整个文档,也是会影响文档的大小的。
<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将整个文档的高宽都撑开,出现了滚动条。说明,即使绝对定位,也是影响文档大小的。

<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:

为什么选中任意圆形图标切换背景时,.bg:not(:target)(Line165)只选中当前最顶的背景,而不会选中其他当前没有活动的.bg呢?预览问题效果,点击审查元素,当切换任意动画的时候,查看几个.bg的z-index值。

网页一打开的时候,所有的.bgz-index都是5,说明动画是对所有非活动的.bg有效的。但当前有活动.bg时,:not(:target)只对当前已target的.bg有效了。猜想:需满足2个条件:切换和动画。

   <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)选中元素有动画属性时,动画效果只对被切换的元素有效,而不会对所有非活动元素有效。

上一篇下一篇

猜你喜欢

热点阅读