68

I have a very basic implementation of the Twitter Bootstrap Carousel plugin on a site that I am working on (http://furnitureroadshow.com/). I was just wondering if anyone had extended the Carousel plugin so that it fades in and fades out on slide transition?

I found this issue #2050 on github.com (https://github.com/twitter/bootstrap/issues/2050) that seems to suggest that at this point, it isn't possible. Just wanted to see if it could be or has been done.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
generalopinion
  • 1,437
  • 2
  • 13
  • 21

6 Answers6

128

Yes. Bootstrap uses CSS transitions so it can be done easily without any Javascript.

The CSS:

.carousel .item {-webkit-transition: opacity 3s; -moz-transition: opacity 3s; -ms-transition: opacity 3s; -o-transition: opacity 3s; transition: opacity 3s;}
.carousel .active.left {left:0;opacity:0;z-index:2;}
.carousel .next {left:0;opacity:1;z-index:1;}

I noticed however that the transition end event was firing prematurely with the default interval of 5s and a fade transition of 3s. Bumping the carousel interval to 8s provides a nice effect.

Very smooth.

StrangeElement
  • 2,282
  • 2
  • 16
  • 20
  • 4
    note that using the css transition requires CSS3 which only the modern browsers support – xorinzor May 15 '12 at 20:08
  • 4
    Pretty nice innovation, it helps promoting CSS3 and "encourages" users with crappy browsers to update. :-) – Daan Jun 18 '12 at 11:31
  • 9
    You need to add `.carousel .active.right` to account for moving the other way through the gallery, thanks though for the right direction. – Duncanmoo Oct 23 '12 at 13:21
  • It works but only when going to the next item... returning back to previous item, doesn't have any cross-fade transition. – Primoz Rome Feb 04 '13 at 17:04
  • If your carousel isn't entirely an image (ie, it contains text with no image background) give the `.item` a background color, or the dissolve isn't quite smooth. – Phil Gyford Feb 12 '14 at 12:08
75

Yes. Although I use the following code.

.carousel.fade
{
    opacity: 1;

    .item
    {
        -moz-transition: opacity ease-in-out .7s;
        -o-transition: opacity ease-in-out .7s;
        -webkit-transition: opacity ease-in-out .7s;
        transition: opacity ease-in-out .7s;
        left: 0 !important;
        opacity: 0;
        top:0;
        position:absolute;
        width: 100%;
        display:block !important;
        z-index:1;
        &:first-child{
            top:auto;
            position:relative;
        }

        &.active
        {
            opacity: 1;
            -moz-transition: opacity ease-in-out .7s;
            -o-transition: opacity ease-in-out .7s;
            -webkit-transition: opacity ease-in-out .7s;
            transition: opacity ease-in-out .7s;
            z-index:2;
        }
    }
}

Then change the class on the carousel from "carousel slide" to "carousel fade". This works in safari, chrome, firefox, and IE 10. It will correctly downgrade in IE 9, however, the nice face effect doesn't happen.

Edit: Since this answer has gotten so popular I've added the following which rewritten as pure CSS instead of the above which was LESS:

.carousel.fade {
  opacity: 1;
}
.carousel.fade .item {
  -moz-transition: opacity ease-in-out .7s;
  -o-transition: opacity ease-in-out .7s;
  -webkit-transition: opacity ease-in-out .7s;
  transition: opacity ease-in-out .7s;
  left: 0 !important;
  opacity: 0;
  top:0;
  position:absolute;
  width: 100%;
  display:block !important;
  z-index:1;
}
.carousel.fade .item:first-child {
  top:auto;
  position:relative;
}
.carousel.fade .item.active {
  opacity: 1;
  -moz-transition: opacity ease-in-out .7s;
  -o-transition: opacity ease-in-out .7s;
  -webkit-transition: opacity ease-in-out .7s;
  transition: opacity ease-in-out .7s;
  z-index:2;
}
Robert McKee
  • 21,305
  • 1
  • 43
  • 57
  • 2
    I tried a bunch of other answers that worked for a lot of people, but for some reason, this is the only one that worked for me. When I have a moment, I will have to investigate... – Dan Ross Mar 09 '13 at 00:08
  • But, this messes up the image titles on the slides; all of the images are not `display: none`, so the mouse always hovers over the last `.item`, no matter which `.item` is currently shown. CSS (>_<) – Dan Ross Mar 09 '13 at 00:16
  • 1
    Of course, I can replicate the functionality of the `title` attribute manually, which I just did. I tried setting `.item` to `display: none` and `.item.active` to `display: block`, but that prevented all but the first slide from ever displaying. – Dan Ross Mar 09 '13 at 00:54
  • 3
    I've editted the above to add z-indexing which should solve your title issue. I've noticed that the bootstrap code specifically looks for the slide class when trying to determine which slide is currently showing (The navigation dots). It still works, but the timing is a bit different for fade than slide. It changes the nav dot to the incoming one instantly instead of waiting for the transition effect to finish, which I prefer anyhow. Just thought I would point out the oddity in case it bugs you. – Robert McKee Mar 09 '13 at 02:57
  • 2
    Note: this doesn't look like CSS - it's probably LESS so needs compiling. – Simon East Jul 06 '13 at 01:04
  • LESS because Bootstrap is perfect, this works like a charm. Had to add z-index = 2 to &.right, &.left to make my navigation arrows show (carousel-control). Definitely the correct answer. – qwertzman Nov 25 '13 at 01:53
  • if using bootstrap mixin files you can also use `.transition(.7s ease-in-out opacity);` – Stephen Mar 02 '14 at 12:54
  • It seem to work fine, but it fades instaltly. I tryed to change the timing, but it seems nothing happends. The fade time is almost instant..and i need something smoother. Can you help me please? – Crisan Raluca Teodora Apr 08 '14 at 14:30
  • Are you testing in IE 9? – Robert McKee Apr 14 '14 at 01:00
  • There's no fade in Chrome - http://pivoture.com/best-practices/data-and-the-user-experience-part-1/ (scroll down and see right sidebar 'What we do' item with paginated nav. – Lawrence Black Aug 03 '14 at 23:10
  • I changed it to .0s; to remove for now - before it was becoming invisible during the transition. – Lawrence Black Aug 03 '14 at 23:15
  • Not sure what you are seeing. I changed the styles back to having a 0.7s transition on your site, and it cross fades in Chrome just fine. Looks the same in Firefox. Tested in Chrome 36, and Firefox 31. – Robert McKee Aug 04 '14 at 20:05
  • This works absolutely fine with Bootstrap version 3.3.4 carousel. I just copied and pasted into my existing HTML template and it works like a charm. Thank a lot @RobertMcKee. You have no idea how helpful you were. – ChickenWing24 May 14 '15 at 06:59
  • @ChickenWing24 That's good to know that it still works. I wrote it for the Bootstrap 2.x line. – Robert McKee May 20 '15 at 15:19
19

Yes. Bootstrap uses CSS transitions so it can be done easily without any Javascript. Just use CSS3. Please take a look at

carousel.carousel-fade

in the CSS of the following examples:

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
  • Don't forget to add "transform: none !important;" to .item class: .item { opacity: 0; transition-property: opacity; transform: none !important; } – goksel Jun 01 '15 at 22:58
4

Came across this issue when using Bootstrap 3. My solution was to add the carousel-fade class to the carousel main DIV and slot the following CSS in, somewhere after the Bootstrap CSS is included:

.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;
}

The style transitions that Bootstrap applies mean that you have to have the mid-stride transitions (active left, next left) quickly, otherwise the item just ends up disappearing (hence the 1/2 second transition time).

I haven't experimented with adjusting the .item and .left transition times, but they will probably need adjusting proportionally to keep the effect looking nice.

Raad
  • 4,540
  • 2
  • 24
  • 41
2

If you are using Bootstrap 3.3.x then use this code (you need to add class name carousel-fade to your carousel).

.carousel-fade .carousel-inner .item {
  -webkit-transition-property: opacity;
          transition-property: opacity;
}
.carousel-fade .carousel-inner .item,
.carousel-fade .carousel-inner .active.left,
.carousel-fade .carousel-inner .active.right {
  opacity: 0;
}
.carousel-fade .carousel-inner .active,
.carousel-fade .carousel-inner .next.left,
.carousel-fade .carousel-inner .prev.right {
  opacity: 1;
}
.carousel-fade .carousel-inner .next,
.carousel-fade .carousel-inner .prev,
.carousel-fade .carousel-inner .active.left,
.carousel-fade .carousel-inner .active.right {
  left: 0;
  -webkit-transform: translate3d(0, 0, 0);
          transform: translate3d(0, 0, 0);
}
.carousel-fade .carousel-control {
  z-index: 2;
}
Maverick
  • 961
  • 9
  • 13
  • Great! This really fades in and out images instead of removing the inactive one and only sliding in the active image. Thumbs up! – Youp Bernoulli May 30 '16 at 08:04
0

Note: If you are using Bootstrap + AngularJS + UI Bootstrap, .left .right and .next classes are never added. Using the example at the following link and the CSS from Robert McKee answer works. I wanted to comment because it took 3 days to find a full solution. Hope this helps others!

https://angular-ui.github.io/bootstrap/#/carousel

Code snip from UI Bootstrap Demo at the above link.

angular.module('ui.bootstrap.demo').controller('CarouselDemoCtrl', function ($scope) {
  $scope.myInterval = 5000;
  var slides = $scope.slides = [];
  $scope.addSlide = function() {
    var newWidth = 600 + slides.length + 1;
    slides.push({
      image: 'http://placekitten.com/' + newWidth + '/300',
      text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' ' +
        ['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
    });
  };
  for (var i=0; i<4; i++) {
    $scope.addSlide();
  }
});

Html From UI Bootstrap, Notice I added the .fade class to the example.

<div ng-controller="CarouselDemoCtrl">
    <div style="height: 305px">
        <carousel class="fade" interval="myInterval">
          <slide ng-repeat="slide in slides" active="slide.active">
            <img ng-src="{{slide.image}}" style="margin:auto;">
            <div class="carousel-caption">
              <h4>Slide {{$index}}</h4>
              <p>{{slide.text}}</p>
            </div>
          </slide>
        </carousel>
    </div>
</div>

CSS from Robert McKee's answer above

.carousel.fade {
opacity: 1;
}
.carousel.fade .item {
-moz-transition: opacity ease-in-out .7s;
-o-transition: opacity ease-in-out .7s;
-webkit-transition: opacity ease-in-out .7s;
transition: opacity ease-in-out .7s;
left: 0 !important;
opacity: 0;
top:0;
position:absolute;
width: 100%;
display:block !important;
z-index:1;
}
.carousel.fade .item:first-child {
top:auto;
position:relative;
}
.carousel.fade .item.active {
opacity: 1;
-moz-transition: opacity ease-in-out .7s;
-o-transition: opacity ease-in-out .7s;
-webkit-transition: opacity ease-in-out .7s;
transition: opacity ease-in-out .7s;
z-index:2;
}
/*
Added z-index to raise the left right controls to the top
*/
.carousel-control {
z-index:3;
}
phanf
  • 661
  • 1
  • 11
  • 16