For the last 3 hours I've been trying to make a simple adjustment to Bootstrap 3's carousel transitions. I've tried changing the slide speed where this is the only thing that seems to have any effect:
.carousel-inner .item {
-webkit-transition-duration: 2s;
-moz-transition-duration: 2s;
-o-transition-duration: 2s;
transition-duration: 2s;
}
but it hides the 'leaving' content too soon, and I have no clue what property to modify to fix that.
I've also tried changing it to a fade transition with
.carousel-fade .item {
opacity: 0;
-webkit-transition: opacity 2s ease-in-out;
-moz-transition: opacity 2s ease-in-out;
-ms-transition: opacity 2s ease-in-out;
-o-transition: opacity 2s ease-in-out;
transition: opacity 2s ease-in-out;
left: 0 !important;
}
.carousel-fade .active {
opacity: 1 !important;
}
.carousel-fade .left {
opacity: 0 !important;
-webkit-transition: opacity 0.5s ease-in-out !important;
-moz-transition: opacity 0.5s ease-in-out !important;
-ms-transition: opacity 0.5s ease-in-out !important;
-o-transition: opacity 0.5s ease-in-out !important;
transition: opacity 0.5s ease-in-out !important;
}
.carousel-fade .carousel-control {
opacity: 1 !important;
}
And just about every other snippet to do so that I've come across, but every single one always first removed the leaving content, showing a featureless background, before fading in the next. What am I missing? All I need is some plain CSS to override the existing transition details, but I don't know where to look any more.
I think different aspects of bootstrap's carousel plugin give the effects you mention.
Active items have display: block
while not active items have display: none
This can be solved by giving all items display: block
and then setting the position
to absolute
with top: 0
and left: 0
, resulting in the items overlapping. Setting opacity: 0;
makes them invisible by default.
Less:
.carousel-inner > .item {
opacity: 0;
top: 0;
left: 0;
width: 100%;
display: block;
position: absolute;
}
One problem of the position: absolute
is that the container does not get a height
. The preceding can be solved by setting the position
of the first item to relative
(it is add the right position already). In Less code, it is as follows:
.carousel-inner > .item {
:first-of-type {
position:relative;
}
}
Bootstrap uses translate3d
s to change the position of the item in the space. You won't need these transformations, so reset them. Leveraging Less, code shown below:
.carousel-inner > .item {
transform: translate3d(0,0,0) !important;
}
The CSS transitions are triggered by adding and removing CSS classes with jQuery. The time between these class changes has been hardcoded in the carousel plugin code (Carousel.TRANSITION_DURATION = 600
). So, after 600 ms, one item becomes active (having the .active class). That is the reason for the unexpected behavior if your css transition-duration
is greater than 0.6 seconds.
The CSS class changes are as follows:
The active item has class .active
-> .active.left
-> none
The next item has no class -> .next.left
-> .active
So the .active.left
and .next.left
are important (or .prev.right
and .active.right
when you slide backwards).
Because all images are already stacked, you can use the z-index
property to make an image in the stack visible, because we can change the opacity
at the same time. You can use the following Less code to fade in the next slide:
.carousel-inner {
> .next.left {
transition: opacity 0.6s ease-in-out;
opacity: 1;
z-index:2;
}
> .active.left {
z-index:1;
}
}
To make sure that the controls are visible as well, use:
.carousel-control {
z-index:4;
}
Putting all together, see the results in this demo, which uses the following Less code:
.carousel-inner {
> .item {
opacity: 0;
top: 0;
left: 0;
width: 100%;
display: block;
position: absolute;
z-index:0;
transition: none;
transform: translate3d(0,0,0) !important;
&:first-of-type {
position:relative;
}
}
> .active {
opacity: 1;
z-index:3;
}
> .next.left,
> .prev.right {
transition: opacity 0.6s ease-in-out;
opacity: 1;
left: 0;
z-index:2;
}
> .active.left,
> .active.right {
z-index:1;
}
}
.carousel-control {
z-index:4;
}
The above code can be compiled with the Less autoprefixer plugin plugin into CSS with the following command:
lessc --autoprefix="Android 2.3,Android >= 4,Chrome >= 20,Firefox >= 24,Explorer >= 8,iOS >= 6,Opera >= 12,Safari >= 6' code.less
which outputs:
.carousel-inner > .item {
opacity: 0;
top: 0;
left: 0;
width: 100%;
display: block;
position: absolute;
z-index: 0;
-webkit-transition: none;
-o-transition: none;
transition: none;
-webkit-transform: translate3d(0, 0, 0) !important;
transform: translate3d(0, 0, 0) !important;
}
.carousel-inner > .item:first-of-type {
position: relative;
}
.carousel-inner > .active {
opacity: 1;
z-index: 3;
}
.carousel-inner > .next.left,
.carousel-inner > .prev.right {
-webkit-transition: opacity 0.6s ease-in-out;
-o-transition: opacity 0.6s ease-in-out;
transition: opacity 0.6s ease-in-out;
opacity: 1;
left: 0;
z-index: 2;
}
.carousel-inner > .active.left,
.carousel-inner > .active.right {
z-index: 1;
}
.carousel-control {
z-index: 4;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With