使用下一个和上一个按钮实现仅 CSS 幻灯片/轮播?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21647389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implement a CSS-only slideshow / carousel with next and previous buttons?
提问by Pebbl
For some time now, off and on, I've been trying to implement a CSS-only slideshow, one that would:
一段时间以来,断断续续地,我一直在尝试实现一个仅使用 CSS 的幻灯片,它可以:
- Offer forward and backward navigation.
- Not modify navigation history.
- Instil a distinct direction to the movement of the content.
- Work across as many browsers as possible.
- 提供向前和向后导航。
- 不修改导航历史。
- 为内容的移动注入一个明确的方向。
- 在尽可能多的浏览器上工作。
Most other CSS Slideshows I've come across didn't tick all those the boxes.
我遇到的大多数其他 CSS 幻灯片并没有勾选所有这些框。
Thankfully it's taken me so long that the browsers themselves have improved no-end, to the point where it is now actually quite widely possible, albeit with a few "modern" CSS-isms. Just in case it is useful to anyone else out there I thought I'd post it here.
值得庆幸的是,我花了很长时间浏览器本身已经得到了无止境的改进,现在实际上已经很可能实现了,尽管有一些“现代”CSS-isms。以防万一它对其他人有用,我想我会在这里发布。
So how can you create a navigable slideshow, using only CSS and the following markup?
那么如何仅使用 CSS 和以下标记来创建可导航的幻灯片呢?
<ul class="css-slider">
<li class="slide"><img src="photos/a.jpg" /></li>
<li class="slide"><img src="photos/b.jpg" /></li>
<li class="slide"><img src="photos/c.jpg" /></li>
<li class="slide"><img src="photos/d.jpg" /></li>
<li class="slide"><img src="photos/e.jpg" /></li>
</ul>
回答by Pebbl
a working example
一个工作示例
UPDATE:There seems to be a bug with Firefox 32 (Mac)that means ellipses will not render in SVG masks, this leads to the reflection failing... and don't get me started on what Chrome 37.0.2062.120 (Mac) is doing if you hover off any of the images in the implemented example at the foot of this answer.
— 18 Sept 2014.
更新:Firefox 32 (Mac) 似乎存在一个错误,这意味着省略号不会在 SVG 蒙版中呈现,这会导致反射失败......并且不要让我开始使用 Chrome 37.0.2062.120 (Mac) 是什么如果您将鼠标悬停在此答案底部的已实现示例中的任何图像上,则执行此操作。
— 2014 年 9 月 18 日。
explaining the basic principal
解释基本原理
The slides are built up out of two main parts, a visual part and an interactive part. The interactive part pretty much stays static, and the visual part is animated. After much playing around I extended the initial HTML structure (see above) to incorporate a few extra wrappers around the slide's content. This allows for the separate interactive and visual parts, and also extra flexibility for other useful abilities i.e. like vertical centering and reflections.
幻灯片由两个主要部分组成,视觉部分和交互部分。交互部分几乎保持静态,而视觉部分是动画的。经过多次尝试后,我扩展了初始 HTML 结构(见上文)以在幻灯片内容周围加入一些额外的包装器。这允许单独的交互和视觉部分,以及其他有用功能的额外灵活性,例如垂直居中和反射。
<ul class="css-slider">
<li class="slide" tabindex="1" id="l1">
<span class="slide-outer">
<span class="slide-inner">
<span class="slide-gfx" id="s1">
<img src="photos/a.jpg" />
</span>
</span>
</span>
</li>
<li class="slide" tabindex="1" id="l2">
<span class="slide-outer">
<span class="slide-inner">
<span class="slide-gfx" id="s2">
<img src="photos/b.jpg" />
</span>
</span>
</span>
</li>
...
</ul>
Now in order to actually have any system behave as a slideshow, you need to have some way to identify the current or focused slide. In this case i'm relying on :focus
to handle this distinction. You might have noticed the addition of tabindex=“1”
above, this is so that the pseudo-class :focus
is applied to unexpected elements like <li>
— this was required mainly for webkit-based browsers, but may help out other agents too.
现在,为了真正让任何系统表现得像幻灯片一样,您需要有某种方法来识别当前或聚焦的幻灯片。在这种情况下,我依靠:focus
处理这种区别。您可能已经注意到tabindex=“1”
上面的添加,这是为了将伪类:focus
应用于意外元素,例如<li>
- 这主要是基于 webkit 的浏览器所必需的,但也可能有助于其他代理。
So put simply, all the slides are stacked one on top of the other, the current focused slide is centred to the viewport and given the highest z-index
, the slide before the focused slide is translated off screen to the left, and the slide after the focused slide is translated off screen to the right. It should be noted that the xy translations only effect the visual content of the slides, the interactive parts are still layered atop one another filling the entire viewport area, well almost...
简而言之,所有幻灯片都堆叠在另一个顶部,当前聚焦的幻灯片以视口为中心并给出最高z-index
,聚焦幻灯片之前的幻灯片向左移出屏幕,聚焦之后的幻灯片幻灯片被翻译到屏幕右侧。应该注意的是,xy 平移只影响幻灯片的视觉内容,交互部分仍然一层一层地填充整个视口区域,几乎......
I say almost because in order for the focus to be triggered on the next and previous slides — via mouse or touch — part of their interactive layers must be accessible and clickable by the user. Using a mixture of left
, right
and padding
the correct areas can be revealed without displacing the visual elements.
我这么说几乎是因为为了在下一张和上一张幻灯片上触发焦点——通过鼠标或触摸——他们的交互层的一部分必须可供用户访问和点击。使用left
,right
和padding
正确区域的混合可以在不替换视觉元素的情况下显示出来。
So, as the current focused slide changes, so do the areas of the interactive layers that are accessible. Each time a user clicks the next or previous arrows, they are actually focusing on the adjacent <li>
element, rather than clicking a link that performs any kind of action.
因此,随着当前聚焦的幻灯片发生变化,可访问的交互式图层区域也会发生变化。每次用户单击下一个或上一个箭头时,他们实际上都在关注相邻<li>
元素,而不是单击执行任何类型操作的链接。
useful to know
知道有用
In order to get this to work on Webkit browsers the
tabindex
attribute needs to be used so that the:focus
Pseudo-class will function on the whatever base element you use to represent a slide.Because of the tricks employed, the slides will play in a reversed-dom-order.
You can navigate the slideshow using tab, however, it will navigate backwards, due to point 2. If you have a Mac, you may need to tweak your os settingsbefore tab will function.
Due to the
left
,right
trick to expose the navigation arrows, there is a slight visual glitch when navigating forwards — in that you can see the subsequent previous arrow quickly animate into place.Because this system works based on
:focus
whenever focus is lost the slideshow reverts back to the initial slide, for this reason, sub links will not work within your slides — unless you enhance interactions with JavaScript.My demo makes use of SVG background images, these are obviously optional and do not work on older browsers.
为了让它在 Webkit 浏览器上工作,
tabindex
需要使用该属性,以便:focus
Pseudo-class 将在您用来表示幻灯片的任何基本元素上运行。由于使用了技巧,幻灯片将以相反的 dom 顺序播放。
您可以使用选项卡导航幻灯片,但是,由于第 2 点,它会向后导航。如果您有 Mac,您可能需要在选项卡起作用之前调整您的操作系统设置。
由于
left
,right
暴露导航箭头的技巧,向前导航时会出现轻微的视觉故障 - 因为您可以看到随后的前一个箭头快速动画到位。因为这个系统的工作原理是
:focus
每当失去焦点时,幻灯片就会恢复到初始幻灯片,因此,子链接在幻灯片中不起作用——除非你增强与 JavaScript 的交互。我的演示使用了 SVG 背景图像,这些显然是可选的,并且不适用于旧浏览器。
supported by
支持
- Firefox v26.0 (Mac/PC ~ most likely much earlier versions)
- Chrome v32 (Mac/PC ~ most likely much earlier versions)
- Safari v7 (Mac/PC ~ most likely much earlier versions)
- Opera v18 (Mac/PC ~ most likely much earlier versions)
- Internet Explorer 9+ (PC)
- Firefox v26.0(Mac/PC ~很可能是更早的版本)
- Chrome v32(Mac/PC ~很可能是更早的版本)
- Safari v7(Mac/PC ~很可能是更早的版本)
- Opera v18(Mac/PC ~很可能是更早的版本)
- Internet Explorer 9+ (PC)
IE7 & IE8 can't even understand
:last-child
or:nth-child
so no, it does notwork for them.
IE7和IE8甚至无法理解
:last-child
或者:nth-child
所以没有,但它不为他们工作。
added extras
附加功能
In the demo below you will see that there are a few JavaScript flourishes, these either help show off what the construct can do, or they progressively enhance. The checkboxes, which are only there for the demo, should allow you to enable or disable certain features. These features are applied by simple classes:
在下面的演示中,您将看到一些 JavaScript 的蓬勃发展,这些要么有助于展示该构造的功能,要么逐渐增强。仅用于演示的复选框应允许您启用或禁用某些功能。这些功能由简单的类应用:
- .with-responsive-images~ little hack to force images to autosize.
- .with-selection-disabled~ prevents user dragging and highlighting.
- .width-fade-in~ fades the slideshow in, initially.
- .with-reflection~ enables a reflection for firefox and webkit.
- .with-slide-zoom~ on hover the slides will zoom to a max-width.
- .with-slide-float~ on focus the slides will levitate.
- .with-slide-float-hover~ on hover the slides will levitate.
- .with-shadow~ a poorman's reflection.
- .with-responsive-images~ 强制图像自动调整大小的小技巧。
- .with-selection-disabled~ 防止用户拖动和突出显示。
- .width-fade-in~ 最初淡入幻灯片。
- .with-reflection~ 为 firefox 和 webkit 启用反射。
- .with-slide-zoom~ 在悬停时幻灯片将缩放到最大宽度。
- .with-slide-float~ 在焦点上幻灯片会悬浮。
- .with-slide-float-hover~ 悬停时幻灯片会悬浮。
- .with-shadow~ 穷人的倒影。
please note:the reflection add-on relies on arbitrary markup attributes. You will have to add unique ids to each .slide, and then extend the CSS to take them into account.
请注意:反射附加组件依赖于任意标记属性。您必须为每个 .slide 添加唯一的 id,然后扩展 CSS 以将它们考虑在内。
CSS breakdown
CSS 分解
set-up
设置
Ok, so to start with here is the basic set-up. First off, because my slideshow is with images I've set some basic image styling, this is all optional.
好的,从这里开始是基本设置。首先,因为我的幻灯片放映的图像我已经设置了一些基本的图像样式,所以这都是可选的。
.slide-gfx img {
max-width: 600px;
max-height: auto;
border-radius: 20px;
box-shadow: 0 0 80px rgba(255,255,255,1);
}
The slider mask was added as a wrapper to the entire slideshow, to prevent the window scrollbars from displaying when operating the slideshow at full screen size. This again is optional.
滑块蒙版作为包装添加到整个幻灯片,以防止在全屏操作幻灯片时显示窗口滚动条。这也是可选的。
.css-slider-mask {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
}
Now we get the actual set-up that is required for the slider. This first part is quite straight-forward, save for the display: none;
part. This initially hides the slideshow from everyone, but is then later overridden for browsers that support :nth-child
. It is most likely that your <body>
element will be the 2nd child, but you should check before using this.
现在我们得到了滑块所需的实际设置。第一部分非常简单,除了display: none;
部分。这最初对所有人隐藏幻灯片,但随后被支持:nth-child
. 您的<body>
元素很可能是第二个子元素,但您应该在使用它之前进行检查。
.css-slider {
list-style: none;
margin: 0;
padding: 0;
width: 96%;
height: 100%;
margin-left: 2%;
z-index: 1;
}
.css-slider {
position: relative;
display: none;
}
body:nth-child(2) .css-slider {
display: block;
}
slides
幻灯片
Next we get down to slide specifics. Because of the non-existence of a reversed General Sibling Selector(~
), all default styles for slides represent the future (or next) state. This is because there isn't an actual way to select the future slides.
接下来我们开始介绍幻灯片的细节。由于不存在反向通用兄弟选择器( ~
),幻灯片的所有默认样式都代表未来(或下一个)状态。这是因为没有选择未来幻灯片的实际方法。
.css-slider .slide {
display: block;
position: absolute;
left: 40px;
top: 0;
right: 0;
bottom: 0;
padding-left: 0;
padding-right: 40px;
z-index: 100;
outline: 0; /* kill the focus rect! */
}
Again, by default we style the forward arrow, and then override later for the current and past slides.
同样,默认情况下我们设置向前箭头的样式,然后稍后覆盖当前和过去的幻灯片。
.css-slider .slide {
background: url('arrow-right.svg') no-repeat right center;
background-size: 25px auto;
}
.css-slider .slide:hover {
background-image: url('arrow-right-hover.svg');
cursor: pointer;
}
Now the focused slide, the key items here are :focus
(as I've already explained) and :last-child
which I haven't. Last Child is used rather than First Child because, again, we have to work backwards (all due to the lack of a reverse General Sibling Selector~
). Why either child is needed at all is so that we can "focus" an initial slide when there is no current focus i.e. on page load.
现在是重点幻灯片,这里的关键项目是:focus
(正如我已经解释过的)和:last-child
我没有的。使用 Last Child 而不是 First Child 因为,同样,我们必须向后工作(所有这些都是由于缺少反向General Sibling Selector~
)。为什么需要任何一个孩子是为了当没有当前焦点时,即页面加载时,我们可以“聚焦”初始幻灯片。
.css-slider .slide:target,
.css-slider .slide:target:hover,
.css-slider .slide:focus,
.css-slider .slide:focus:hover,
.css-slider .slide:last-child,
.css-slider .slide:last-child:hover {
left: 40px;
right: 40px;
padding-left: 0;
padding-right: 0;
background: transparent;
z-index: 101;
cursor: default;
}
Now we need to affect all the slides that slip into the past. I have a avoided mentioning the :target
pseudo-class prior to now, basically this has been implemented to support the "jump nav". There are two reasons why I wont sing the praises of the the "jump nav":
现在我们需要影响所有滑入过去的幻灯片。之前我一直避免提及:target
伪类,基本上这是为了支持“跳转导航”而实现的。我不会歌颂“跳跃导航”的原因有两个:
- It is partially powered by JavaScript.
- It relies on #hash or #fragment values, which, due to creation of history states can mess around with your site's usability.
- 它部分由 JavaScript 提供支持。
- 它依赖于 #hash 或 #fragment 值,由于历史状态的创建,这些值可能会影响您网站的可用性。
Anyway, the trick to selecting slides that are in the past, hinges on the General Sibling Selector. The following construct basically means select .slide(s) that you find after the .slide that has :focus.
无论如何,选择过去的幻灯片的技巧取决于General Sibling Selector。以下构造基本上意味着select .slide(s) 在 .slide 之后找到 :focus。
.css-slider .slide:target ~ .slide,
.css-slider .slide:focus ~ .slide {
padding-left: 40px;
padding-right: 0;
left: 0;
right: 40px;
}
.css-slider .slide:target ~ .slide,
.css-slider .slide:focus ~ .slide {
background: url('arrow-left.svg') no-repeat left center;
background-size: 25px auto;
}
.css-slider .slide:target ~ .slide:hover,
.css-slider .slide:focus ~ .slide:hover {
background-image: url('arrow-left-hover.svg');
}
slide contents
幻灯片内容
Next up we need to control what exactly happens with our slide contents. I have designed this system so that if you want to, you can leave out the animation section. This will mean that the slides will switch instantaneously. This next part takes care of that.
接下来,我们需要控制幻灯片内容究竟发生了什么。我设计了这个系统,如果你愿意,你可以省略动画部分。这意味着幻灯片将立即切换。下一部分会处理这个问题。
.css-slider .slide .slide-outer {
display: none;
width: 100%;
height: 100%;
}
Slide-inner is purely used to handle the centering of the slide contents. It relies on display table
and display table-cell
.
Slide-inner 纯粹用于处理幻灯片内容的居中。它依赖于显示table
和显示table-cell
。
.css-slider .slide .slide-outer .slide-inner {
display: table-cell;
vertical-align: middle;
text-align: center;
width: 100%;
height: 100%;
}
Slide-gfx is literally just a containing wrapper for whatever you decide to put in your slideshow. The reflection is generated from this container, and a few other visual extras are attached to it also.
Slide-gfx 实际上只是您决定放入幻灯片的任何内容的包含包装器。反射是从这个容器生成的,并且还附加了一些其他视觉效果。
.css-slider .slide .slide-outer .slide-inner .slide-gfx {
position: relative;
display: inline-block;
z-index: 102;
text-align: left; /* override the centering back to defaults */
}
This part is responsible for the instant switch when no animation is included.
这部分负责不包含动画时的即时切换。
.css-slider .slide:target .slide-outer,
.css-slider .slide:focus .slide-outer,
.css-slider .slide:last-child .slide-outer {
display: block; /* if they don't support display table */
display: table;
}
last-child overrides
最后一个孩子覆盖
Due to the :last-child
declarations that step in when nothing is focused, if you were to make no further changes, you would find certain things break. This is because :last-child
always applies, unlike :focus
. To rectify this we need to negate the :last-child
changes, but only when something has been focused. That's what the following CSS does.
由于:last-child
在没有关注任何内容时介入的声明,如果您不进行进一步的更改,您会发现某些事情会中断。这是因为:last-child
始终适用,与:focus
. 为了纠正这个问题,我们需要否定这些:last-child
变化,但只有在关注某些事情的情况下。这就是下面的 CSS 所做的。
.css-slider .slide:target ~ .slide:last-child,
.css-slider .slide:focus ~ .slide:last-child {
cursor: pointer;
}
.css-slider .slide:target ~ .slide:last-child .slide-outer,
.css-slider .slide:focus ~ .slide:last-child .slide-outer {
display: none;
}
final annoying z-index hack
最后一个烦人的 z-index hack
So far the CSS has been quite generalised, but there is always something...
到目前为止,CSS 已经相当普遍,但总有一些东西......
This part is only required to fix the click-ability of the 'previous slide' arrow, so that the most recent previous frame floats above anything else. If you don't care about a previous slide action then you could do away with this step, as long as you hide the previous arrow. It's rather annoying because this whole arbitrary section could be done away with if CSS supported an inverted version of the General Sibling Selector.
这部分只需要修复“上一张幻灯片”箭头的点击能力,以便最近的前一帧浮动在其他任何内容之上。如果您不关心上一个幻灯片操作,那么您可以取消此步骤,只要您隐藏上一个箭头即可。这很烦人,因为如果 CSS 支持General Sibling Selector的倒置版本,则可以取消整个任意部分。
Basically the following will support up to 5 frames, if you need more, add more. The good news at least is you can add far more frames than you need without any real adverse effects. Obviously if you go above 100 frames you'll have to adjust other z-indexes in the rest of the CSS.
基本上下面最多支持5帧,如果你需要更多,添加更多。好消息至少是您可以添加比您需要的更多的帧,而不会产生任何真正的不利影响。显然,如果超过 100 帧,则必须调整其余 CSS 中的其他 z-index。
.css-slider .slide:target ~ .slide:nth-child(1),
.css-slider .slide:focus ~ .slide:nth-child(1) { z-index:99; }
.css-slider .slide:target ~ .slide:nth-child(2),
.css-slider .slide:focus ~ .slide:nth-child(2) { z-index:98; }
.css-slider .slide:target ~ .slide:nth-child(3),
.css-slider .slide:focus ~ .slide:nth-child(3) { z-index:97; }
.css-slider .slide:target ~ .slide:nth-child(4),
.css-slider .slide:focus ~ .slide:nth-child(4) { z-index:96; }
.css-slider .slide:target ~ .slide:nth-child(5),
.css-slider .slide:focus ~ .slide:nth-child(5) { z-index:95; }
Animation and Add-ons
动画和附加组件
As I have stated, the animation is optional, along with all the rest of the CSS i.e. visual add-ons. I'll include the rest here with less detail. Most of it is quite straight-forward once you know the tricks above and CSS transitions or animations. The main reason for it's bulk, is, as usual, vendor-prefixes; which I've removed for brevity. To source the full CSS you can obviously do so from the demo below.
正如我所说,动画是可选的,以及所有其余的 CSS,即视觉附加组件。我将在此处包含其余部分,但不那么详细。一旦您了解了上述技巧和 CSS 过渡或动画,其中大部分内容就变得非常简单。其庞大的主要原因是,像往常一样,供应商前缀;为简洁起见,我已将其删除。要获取完整的 CSS,您显然可以从下面的演示中这样做。
please note:Most of these add-ons rely on quite modern CSS i.e. animations or SVGs
请注意:这些附加组件中的大多数依赖于相当现代的 CSS,即动画或 SVG
/** --------------------------------------------------------------------------
* HANDLE THE SLIDE ANIMATION (optional)
* ------------------------------------------------------------------------ */
/* Override the default instant slide behaviour */
.css-slider .slide .slide-outer {
display: block !important;
display: table !important;
}
/* set up the transitions */
.css-slider .slide .slide-outer {
transition-property: opacity, transform;
transition-duration: 2s;
transition-timing-function: ease;
}
/* After state */
.css-slider .slide:target ~ .slide .slide-outer,
.css-slider .slide:target ~ .slide:last-child .slide-outer,
.css-slider .slide:focus ~ .slide .slide-outer,
.css-slider .slide:focus ~ .slide:last-child .slide-outer {
transform: translate(-150%,0);
transform: translate3D(-150%,0,0);
}
/* Before state */
.css-slider .slide .slide-outer {
transform: translate(200%,0);
transform: translate3D(200%,0,0);
}
/* Focused state*/
.css-slider .slide:target .slide-outer,
.css-slider .slide:focus .slide-outer,
.css-slider .slide:last-child .slide-outer {
transform: translate(0,0);
transform: translate3D(0,0,0);
}
/** --------------------------------------------------------------------------
* SMALL SCREEN FIX / SLIDE JERK (optional)
* ---------------------------------------------------------------------------
* When we shift 'left' and 'right' values -- in order to allow access to a future
* or past arrow -- this can cause a jump in the responsive scaling of the slide.
* if we transition the left value quickly, it can make this appear less jarring.
*/
.css-slider .slide {
transition-property: left, padding-left;
transition-duration: 1s;
transition-timing-function: ease;
}
/** --------------------------------------------------------------------------
* Add-on module : responsive images
* ------------------------------------------------------------------------ */
.with-responsive-images .slide-gfx img {
width: 100%;
height: auto;
}
/** --------------------------------------------------------------------------
* Add-on module : stop user selection
* ------------------------------------------------------------------------ */
/* if your slides don't need to be selectable, I recommend using this */
.with-selection-disabled {
user-select: none;
}
/** --------------------------------------------------------------------------
* Add-on module : initial fade in
* ------------------------------------------------------------------------ */
.with-fade-in .slide-gfx {
opacity: 0;
}
/* animate into visibility */
.with-fade-in .slide-gfx {
animation: css-slideshow-fade-in 2s;
animation-delay: 1s;
animation-fill-mode: forwards;
}
/* Vebdor animations */
@keyframes css-slideshow-fade-in { from { opacity: 0; } to { opacity: 1; } }
/** --------------------------------------------------------------------------
* Add-on module : slide reflection
* ------------------------------------------------------------------------ */
/* force our slide-gfx to be inline-block and relative positioned */
.with-reflection .slide-gfx {
display: inline-block !important;
}
/* reflection for webkit agents */
.with-reflection .slide-gfx > *:first-child {
-webkit-box-reflect: below 2px
-webkit-gradient(linear, left top, left bottom,
from(transparent), color-stop(0.9, transparent), to(white));
}
/* make sure internal images don't keep inline spacing/margin */
.with-reflection .slide-gfx img {
display: block;
}
/* generate the reflection */
.with-reflection .slide-gfx:after {
content: '';
position: absolute;
display: block;
mask: url("reflection-mask.svg#mask"); /* gradient fade the reflection */
transform: scaleY(-1); /* flip clone to appear as reflection */
opacity: 0.5; /* fade out reflection */
top: 100%;
width: 100%;
height: 60px;
z-index: 200;
margin-top: 2px;
}
/* again, due to element() requiring IDs we need arbitrary code
per each slide and each slide-gfx needs an id */
.with-reflection #s1:after { background: -moz-element(#s1) no-repeat left bottom; }
.with-reflection #s2:after { background: -moz-element(#s2) no-repeat left bottom; }
.with-reflection #s3:after { background: -moz-element(#s3) no-repeat left bottom; }
.with-reflection #s4:after { background: -moz-element(#s4) no-repeat left bottom; }
.with-reflection #s5:after { background: -moz-element(#s5) no-repeat left bottom; }
.with-reflection #s6:after { background: -moz-element(#s6) no-repeat left bottom; }
.with-reflection #s7:after { background: -moz-element(#s7) no-repeat left bottom; }
.with-reflection #s8:after { background: -moz-element(#s8) no-repeat left bottom; }
.with-reflection #s9:after { background: -moz-element(#s9) no-repeat left bottom; }
.with-reflection #s10:after { background: -moz-element(#s10) no-repeat left bottom; }
.with-reflection #s11:after { background: -moz-element(#s11) no-repeat left bottom; }
.with-reflection #s12:after { background: -moz-element(#s12) no-repeat left bottom; }
.with-reflection #s13:after { background: -moz-element(#s13) no-repeat left bottom; }
.with-reflection #s14:after { background: -moz-element(#s14) no-repeat left bottom; }
.with-reflection #s15:after { background: -moz-element(#s15) no-repeat left bottom; }
.with-reflection #s16:after { background: -moz-element(#s16) no-repeat left bottom; }
.with-reflection #s17:after { background: -moz-element(#s17) no-repeat left bottom; }
.with-reflection #s18:after { background: -moz-element(#s18) no-repeat left bottom; }
.with-reflection #s19:after { background: -moz-element(#s19) no-repeat left bottom; }
.with-reflection #s20:after { background: -moz-element(#s20) no-repeat left bottom; }
/** --------------------------------------------------------------------------
* Add-on module : slide zoom (optional, not compatible with slide float)
* ------------------------------------------------------------------------ */
.with-slide-zoom .slide .slide-gfx > *:first-child {
transition-property: max-width;
transition-duration: 2s;
transition-timing-function: ease-in-out;
transition-delay: 0.25s;
}
.with-slide-zoom .slide .slide-gfx > *:first-child:hover {
max-width: 1000px;
}
/** --------------------------------------------------------------------------
* Add-on module : slide float (optional, not compatible with slide zoom)
* ------------------------------------------------------------------------ */
/* inital transition set-up */
.with-slide-float:not(.with-slide-zoom) .slide .slide-gfx > *:first-child,
.with-slide-float-hover:not(.with-slide-zoom) .slide .slide-gfx > *:first-child {
transition-property: transform;
transition-duration: 2s;
transition-timing-function: ease-in-out;
}
/* we need a delay for the non-hover version */
.with-slide-float:not(.with-slide-zoom) .slide .slide-gfx > *:first-child {
transition-delay: 2s;
}
/* initial levitation on focus */
.with-slide-float:not(.with-slide-zoom) .slide:target .slide-gfx > *:first-child,
.with-slide-float:not(.with-slide-zoom) .slide:focus .slide-gfx > *:first-child,
.with-slide-float-hover:not(.with-slide-zoom) .slide .slide-gfx > *:first-child:hover {
transform: translate(0,-40px);
transform: translate3D(0,-40px,0);
}
/* trigger the float animation after 4s */
.with-slide-float:not(.with-slide-zoom) .slide:target .slide-gfx > *:first-child,
.with-slide-float:not(.with-slide-zoom) .slide:focus .slide-gfx > *:first-child,
.with-slide-float-hover:not(.with-slide-zoom) .slide .slide-gfx > *:first-child:hover {
animation: css-slideshow-levitate 4s;
animation-direction: alternate;
animation-fill-iteration-count: infinite;
animation-timing-function: ease-in-out;
animation-delay: 2s;
}
/* longer delay for automatic version i.e. non-hover */
.with-slide-float:not(.with-slide-zoom) .slide:target .slide-gfx > *:first-child,
.with-slide-float:not(.with-slide-zoom) .slide:focus .slide-gfx > *:first-child {
animation-delay: 4s;
}
/* Vebdor animations for the float */
@keyframes css-slideshow-levitate {
from { transform: translate(0,-40px); transform: translate3D(0,-40px,0); }
to { transform: translate(0,-20px); transform: translate3D(0,-20px,0); }
}
/** --------------------------------------------------------------------------
* Add-on module : ground shadow (optional)
* ------------------------------------------------------------------------ */
.with-shadow .slide .slide-gfx:before {
content: '';
background: url('slide-shadow.svg') no-repeat center center;
position: absolute;
bottom: -10px;
left: -20px;
right: -20px;
height: 20px;
z-index: -1;
opacity: 0.7;
}
.with-shadow.with-slide-float .slide .slide-gfx:before,
.with-shadow.with-slide-float-hover .slide .slide-gfx:before {
transition-property: opacity;
transition-duration: 2s;
transition-timing-function: ease-in-out;
}
.with-shadow.with-slide-float .slide .slide-gfx:before {
transition-delay: 2s;
}
.with-shadow.with-slide-float .slide:target .slide-gfx:before,
.with-shadow.with-slide-float .slide:focus .slide-gfx:before,
.with-shadow.with-slide-float .slide:last-child .slide-gfx:before,
.with-shadow.with-slide-float-hover .slide .slide-gfx:hover:before {
opacity: 0.1;
animation: css-slideshow-shadow 4s;
animation-delay: 4s;
animation-direction: alternate;
animation-fill-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
.with-shadow.with-slide-float-hover .slide .slide-gfx:hover:before {
animation-delay: 2s;
}
/* Vebdor animations for the float */
@keyframes css-slideshow-shadow { from { opacity: 0.1; } to { opacity: 0.7; } }
implemented example (v0.2)
实现示例(v0.2)
http://codelamp.co.uk/css-slideshow/v0.2/
http://codelamp.co.uk/css-slideshow/v0.2/
please note:the jump nav i.e. circular dots do rely on a small bit of JavaScript. The rest is pure CSS.
请注意:跳转导航即圆点确实依赖于一点点 JavaScript。其余的是纯 CSS。
previous version
以前的版本
As I said, it has taken quite a bit of time to refine this system. For those that might be interested, here is my (last) version 0.1 — there have been many before ;) This took a slightly different approach and involved both visual and interactive moving parts. In the end I scrapped it because it involved more browser processing and so was much more clunky; something that this solid color demo doesn't reveal.
正如我所说,完善这个系统花了相当多的时间。对于那些可能感兴趣的人,这是我的(最后一个)版本 0.1 — 以前有很多版本 ;) 这采用了稍微不同的方法,并涉及视觉和交互式移动部件。最后我放弃了它,因为它涉及更多的浏览器处理,所以更笨重;这个纯色演示没有透露的东西。