具有任意数量图片的纯CSS交叉淡入淡出画廊

时间:2015-03-31 09:24:56

标签: css css3

我有一个幻灯片,其中图片在循环中自动交叉淡入淡出。设置为3张图片滚动。

Codepen中的演示(http://codepen.io/lopis/pen/VYRoKE

<section class="crossfade">
  <article class="slide">
    <img src="http://lorempixel.com/400/200/people" alt="" />
  </article>
  <article class="slide">
    <img src="http://lorempixel.com/400/200/cats" alt="" />
  </article>
  <article class="slide">
    <img src="http://lorempixel.com/400/200/sports" alt="" />
  </article>
</section>

CSS:

$slideDuration: 4; // seconds
$slideNum: 3;

@mixin loop($name, $duration, $delay) {
  -webkit-animation: $name #{$duration}s #{$delay}s infinite;
  -moz-animation: $name #{$duration}s #{$delay}s infinite;
  animation: $name #{$duration}s #{$delay}s infinite;
}

@mixin slide() {
  @for $i from 1 through $slideNum {
    .slide:nth-child( #{$i} ) {
      @include loop( crossfade, ($slideNum * $slideDuration), (($i - 1) * $slideDuration) );
    }
  }
}

@mixin keyframes() {

  @-webkit-keyframes crossfade {
    0% {
      opacity:1;
    }
    25% {
      opacity:1;
    }
    33% {
      opacity:0;
    }
    86% {
      opacity:0;
    }
    100% {
      opacity:1;
    }
  }

  @keyframes crossfade {
    0% {
      opacity:1;
    }
    25% {
      opacity:1;
    }
    33% {
      opacity:0;
    }
    86% {
      opacity:0;
    }
    100% {
      opacity:1;
    }
  }
}


.crossfade {
  position: relative;
}
.slide {
  position: absolute;
  top: 0;
}
.slide:first-child {
  position: static;
}

@include slide();

@include keyframes();

有没有办法像这样制作一个只使用CSS的任意数量幻灯片的动画?

编辑:我理解这种动态不适用于CSS,但您可以使用某些动态内容,例如使用calc()等。

一些库,如评论中建议的那样,允许使用mixins来完成此任务。这不是我正在寻找的,因为它需要重建源。

1 个答案:

答案 0 :(得分:7)

您可以使用内容响应技术

仅使用CSS

让我们为每张幻灯片设置一个2秒的时间。

我们需要为每2秒钟的孩子设置一个交错的延迟。这很容易被n-child接受。

现在,我们需要根据元素的数量增加转换的持续时间。使用此technique,我们可以轻松实现这一目标。

第三个问题是管理淡出。在标准方法中,这将涉及改变关键帧的变化点,这将是麻烦的。使用更少的代码来处理这个问题的技巧是在动画本身中进行z-index运动。元素向后移动,然后我们不再关心它们的不透明度了

仅为3个可能数量的元素设置示例:

.container {
  width: 100px;
  height: 50px;
  position: relative;
  margin: 10px;
  display: inline-block;
}

.element {
  position: absolute;
  width: 100%;
  height: 100%;
  opacity: 0;
  animation: anim 6s infinite;
}


.element:nth-child(1) {
  background-color: lightyellow;
  animation-delay: 0s;
}

.element:nth-child(2) {
  background-color: lightgreen;
  animation-delay: 2s;
}
.element:nth-child(3) {
  background-color: pink;
  animation-delay: 4s;
}
.element:nth-child(4) {
  background-color: lightblue;
  animation-delay: 6s;
}
.element:nth-child(5) {
  background-color: coral;
  animation-delay: 8s;
}
.element:nth-child(6) {
  background-color: aliceblue;
  animation-delay: 10s;
}
.element:nth-child(7) {
  background-color: burlywood;
  animation-delay: 12s;
}
.element:nth-child(8) {
  background-color: bisque;
  animation-delay: 14s;
}
.element:nth-child(9) {
  background-color: beige;
  animation-delay: 16s;
}

.element:nth-last-child(3):first-child, 
.element:nth-last-child(3):first-child ~ .element {
  animation-duration: 6s;
}

.element:nth-last-child(6):first-child, 
.element:nth-last-child(6):first-child ~ .element {
  animation-duration: 12s;
}

.element:nth-last-child(9):first-child, 
.element:nth-last-child(9):first-child ~ .element {
  animation-duration: 18s;
}

@keyframes anim {
  0% { opacity: 0; z-index: 100;}
  15% { opacity: 1;}
  50% { opacity: 1;}
  100% { opacity: 0; z-index: 1;}
}
<div class="container">
    <div class="element">ONE</div>
    <div class="element">TWO</div>
    <div class="element">THREE</div>
</div>
<div class="container">
    <div class="element">ONE</div>
    <div class="element">TWO</div>
    <div class="element">THREE</div>
    <div class="element">FOUR</div>
    <div class="element">FIVE</div>
    <div class="element">SIX</div>
</div>
<div class="container">
    <div class="element">ONE</div>
    <div class="element">TWO</div>
    <div class="element">THREE</div>
    <div class="element">FOUR</div>
    <div class="element">FIVE</div>
    <div class="element">SIX</div>
    <div class="element">SEVEN</div>
    <div class="element">EIGHT</div>
    <div class="element">NINE</div>
</div>