8

I've created a responsive image slider using jQuery cycle.

The following setup I have used works fine, apart from the containing .cycle div is not cleared correctly, making any content after it sit underneath it.

This is due to the fact the div is relative and its children are absolute.

     $('.cycle').cycle({
        slideResize: true,
        containerResize: false,
        fit: 1,
        width: "fit"
     });

My question is , how can I clear the responsive .cycle div without having a fixed height or using some event heavy JavaScript?

Here is my code on jsfiddle: http://jsfiddle.net/blowsie/HuNfz/19/


Update:

I wrote some code to fix the height of the cycle, which works as expected (although it can bug out sometimes), but its event heavy and not very slick.

Id love to see can be done in pure CSS or a change in the cycle setup.

http://jsfiddle.net/blowsie/HuNfz/22/

braX
  • 11,506
  • 5
  • 20
  • 33
Blowsie
  • 40,239
  • 15
  • 88
  • 108
  • I changed the containerResize property to true and then it worked, but then it's not responsive anymore..maybe it helps.. – Boyye Sep 20 '12 at 09:47
  • nope, it needs to be responsive! Thanks tho – Blowsie Sep 20 '12 at 09:58
  • 1
    Not sure if you're open to another piece of tech, but I love and use [Wilto's Dynamic Carousel](https://github.com/Wilto/Dynamic-Carousel). – Jeffrey Lo Sep 21 '12 at 21:08
  • @JeffreyLo Thanks but this doesn't quite cut it, I need the fade effect and other options that it doesn't have. – Blowsie Sep 26 '12 at 13:45

4 Answers4

9

Cycle is not very responsive friendly. But Cycle2 definitely is. Check it out here: http://jquery.malsup.com/cycle2/

malsup
  • 156
  • 1
  • For those curious as to the configuration to achieve this see here. http://jsfiddle.net/blowsie/HuNfz/49/ – Blowsie Sep 26 '12 at 14:05
0

Possibly adding a resize windows:

$(window).resize(function () {
    $('.cycle').height($('img:visible').height());
});
setTimeout(300, $(window).resize());

http://jsfiddle.net/HuNfz/60/

Raul Valverde
  • 587
  • 4
  • 11
  • constant polling is a really bad idea other than that the approach is similar to my mock up in the question. – Blowsie Oct 10 '12 at 06:35
0

Old post, I know.

We have it working in production with cycle. Cycle2 was not and is still not an option for us. Unfortunately, it involves modifying cycle's internal data. Luckily, the fix is straightforward.

When the cycle plugin initializes, it adds two propeties cycleW and cycleH to each of your slides' DOM object with respectively the initial width and height of each slide. Cycle uses these properties to animate each slide regardless of the dimension of the window.

When the window is resized, you need to clear cycleW and cycleH manually or set them to a pre determined value.

Example (assuming your slideshow container is .slideshow):

$(".slideshow").children("div").each(function(){
    this.cycleW = $(this).width();
    this.cycleH = $(this).height();
});

We have it working very well in production.

html looks like this:

<div class="slideshow">
    <div class="slide"><img src=".." width="100%" height="auto"/></div>
    <div class="slide"><p>Copy copy copy no photo on slide </p></div>
    <div class="slide"><img src=".." width="100%" height="auto"/></div>
    <div class="slide"><p>Copy copy copy no photo on slide </p></div>
    ...
</div>

Now the window resize function. This is our version. You might need to customize this to fit your needs. Basically, we store the initial ratio for the cases we have fixed images in the slideshow. There are times we have variable height slideshows. This code addresses both situations. Then, it resets the internal cycleW and cycleH values of each slide DOM element to fit their parent container

$(window).resize(function(){
    // first time around, save original width & height for ratios and complicated preloading
    $(".slideshow").each(function(i,elt){
        var originalWidth = $(elt).data("originalWidth"); // check existence of our ratio cache
        if (typeof originalWidth == "undefined") {
            var containerWidth = $(elt).parent().first().width(); // auto scale to container width.
            var containerHeight = $(elt).parent().first().height();
            $(elt).data("originalWidth",containerWidth);
            $(elt).data("originalHeight",containerHeight);
        }
    });

    // fix slideshows to their container width
    $(".slideshow").each(function(i,elt){
        var containerWidth = $(elt).parent().first().width();
        var originalWidth = $(elt).data("originalWidth")*1;
        var originalHeight = $(elt).data("originalHeight")*1;
        var height = Math.floor(originalHeight*containerWidth/originalWidth);   // maintain original ratio
        $(elt).css("width", containerWidth+"px").css("height",height+"px"); // container actual dimensions. height might get reset again below
        $(elt).children("div").css("width", containerWidth+"px"); // reset each slide width 
                                                                 // (fails once slide moves out, because the cycle plugin will use a cached value)
        $(elt).children("div").children().css("width", containerWidth+"px"); // fix direct children (images or divs - images should have height auto).

        // recompute max height based on inside slide, not just photos.
        // some slideshows have variable height slides.
        var maxHeight = 0;
        var panelArray = $(elt).children("div");
        for (var i = 0; i < panelArray.length; i++) {
            var height = $(panelArray[i]).height();
            if (height > maxHeight) maxHeight = height;
        }
        if (maxHeight > 0) {
            $(elt).height(maxHeight);
        }

        // fix internal cycle dimension cache (cycleW and cycleH on each slide)
        $(elt).children("div").each(function(){
            this.cycleW = containerWidth;
            this.cycleH = maxHeight;
        });
    });
});
Max
  • 1,049
  • 7
  • 9
  • Just some pointers, this code of yours is very expensive and will run too frequently. You should definitely store some of your variables higher up and debounce your function. – Blowsie Jan 27 '15 at 11:40
  • Yep, we debounce it in production :) This is a simplified example we modified for this demo, could definitely be optimized.. But the question was about clearing a cycle plugin for responsiveness, which this post explains. That being said, since you spoke of it, debouncing is not the answer to smooth UI responsiveness. It can create horrendous transitions, and tightening up the interval can defeat the purpose. Cheers and thanks for the comment :) – Max May 19 '15 at 05:27
-1

By default the plugin assigns position:relative to your and also to s within that it assigns position: absolute and z-index values. Which makes the slideshow be a floater/unstuck in a stack. I found 2 solutions to the issue:

  1. Add clearfix class to your and add css styles for clearfix into your stylesheet.

    .clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }

    .clearfix { display: inline-block; }

    html[xmlns] .clearfix { display: block; }

    • html .clearfix { height: 1%; }
  2. (Not very elegant) add border to your cycle class

    .cycle { border: 1px solid #f00; }

Hope one of these helps.

makbeta
  • 339
  • 3
  • 5
  • Thanks for your answer but... Neither solution works for me - Solution 1 =http://jsfiddle.net/blowsie/HuNfz/47/ , Solution 2 = http://jsfiddle.net/blowsie/HuNfz/46/ – Blowsie Sep 26 '12 at 13:37