17

In my JS image slider (Owl-Carousel), images have different dimensions:

http://goo.gl/KmpX2P

enter image description here

You can see that the image height varies within the carousel. How to make it constant while keeping carousel responsive? I need images to fill the slider space at all times, therefore some will have to be cropped through CSS somehow. The desired result looks like this:

enter image description here

drake035
  • 3,955
  • 41
  • 119
  • 229
  • So all images have to be the same height and take up all the width side by side? Correct? And you can cut the images. – Thierry Blais Feb 07 '14 at 16:15
  • 1
    The second image (white tables with red things on it) is quite vertical, so I guess some images like this one must be cropped by CSS. But I can't crop the actual images using Photoshop for example, it has to be done by JS or CSS. – drake035 Feb 07 '14 at 16:19
  • @drake you can do the cropping in css by setting the `background:url(...)` to a given image, then setting the `background-size` and the `background-position`, the same functionality is used in working with sprites for video games. – Arthur Weborg Feb 07 '14 at 16:28
  • @drake035 So what would you like to achive: All images have the same height, but width may vary, or all images have exactly the same size (width + height is equal)? And should images which intrinsic height is larger be scaled down while keeping their aspect ratio or should just the height be adjusted? – Netsurfer Feb 07 '14 at 16:30
  • I'm pretty sure the images need to be the same height as the shorter one and change size maintaining that ratio as the screen resizes, correct? – Thierry Blais Feb 07 '14 at 16:31
  • @Netsurfer: for a given slider total width, all images must have exact same dimensions. As slider width increases (responsive slider), image dimensions should increase too, at least images' width. The requirements are: same image dimensions, and image must fill the entire slider space. Likwid_T: yes, the shorter one's height should be the one of all images, sounds correct. ArtyMcFly: I think Owl Carousel must be populated with actual images, not div with a background image. – drake035 Feb 07 '14 at 16:37
  • Sorry I realize Owl Carousel DOES support other than img elements so ArtyMcFly's idea might work. – drake035 Feb 07 '14 at 16:44
  • @drake035 So especially if the site is a responsive site, size matters! I would recommend the use of a graphic program to make your images all the same height. By doing so larger images are also reduced in file size! – Netsurfer Feb 07 '14 at 16:52

6 Answers6

29

It can be specified in css.

Example,

http://jsfiddle.net/AwBLL/2/

.owl-carousel .owl-item{
    height:285px;
    width:100%;
}

EDIT The following solution uses the plugin's callback events to modify the viewport's/wrapper's height according to the smallest image height.

http://jsfiddle.net/DNMpF/1/

js

$(document).ready(function () {

    $("#owl-example").owlCarousel({
        afterUpdate: function () {
            updateSize();
        },
        afterInit:function(){
            updateSize();
        }
    });
    function updateSize(){
        var minHeight=parseInt($('.owl-item').eq(0).css('height'));
        $('.owl-item').each(function () {
            var thisHeight = parseInt($(this).css('height'));
            minHeight=(minHeight<=thisHeight?minHeight:thisHeight);
        });
        $('.owl-wrapper-outer').css('height',minHeight+'px');
    }
});

css

.owl-carousel .owl-item img {
    height:auto;
    width:100%;
    display: block;
}

.owl-carousel .item {
    margin:0px;
}

EDIT2

Regarding the latest comment, to show the bottom part of the large images one approach could be to iterate the images and add a negative top margin equal to the part of these images hidden.

function updateSize(){
        var minHeight=parseInt($('.owl-item').eq(0).css('height'));
        $('.owl-item').each(function () {
            var thisHeight = parseInt($(this).css('height'));
            minHeight=(minHeight<=thisHeight?minHeight:thisHeight);
        });
        $('.owl-wrapper-outer').css('height',minHeight+'px');

        /*show the bottom part of the cropped images*/
        $('.owl-carousel .owl-item img').each(function(){
            var thisHeight = parseInt($(this).css('height'));
            if(thisHeight>minHeight){
                $(this).css('margin-top',-1*(thisHeight-minHeight)+'px');
            }
        });

    }
melc
  • 11,523
  • 3
  • 36
  • 41
  • melc: nice but width cannot be specified in pixels as the slider must be responsive.. – drake035 Feb 07 '14 at 16:41
  • @drake035 setting it to `width:100%` would it be ok? e.g. http://jsfiddle.net/AwBLL/1/ – melc Feb 07 '14 at 16:44
  • @drake035 updated the answer, i think class `.owl-item` is more accurate. – melc Feb 07 '14 at 16:49
  • Images must fill the slider space, no gaps. Images must not be distorted either. – drake035 Feb 07 '14 at 16:53
  • @drake035 regarding distortion in this example http://jsfiddle.net/AwBLL/3/ i think the images are simply cropped, not distorted. – melc Feb 07 '14 at 16:55
  • @drake035 regarding spaces you need to wrap the images inside a div and set `margin:0px` as shown here, http://owlgraphic.com/owlcarousel/demos/images.html . – melc Feb 07 '14 at 16:58
  • @drake035 tried to simulate the example in the url above, using this example is more or less something like this http://jsfiddle.net/AwBLL/4/ , you may come up with some better modifications. – melc Feb 07 '14 at 17:02
  • @drake035 i think the last edit of the answer is a bit closer to what you're looking for, hope it helps. – melc Feb 07 '14 at 18:04
  • Thank you so much melc, it works perfectly! Do you think it's possible to show the vertical middle of cropped image instead of the top? So in my example instead of seeing the clouds we would see the tables? – drake035 Feb 07 '14 at 19:44
  • 1
    @drake035 your are welcome, i'm glad it helped you please also check the latest update related to your last comment. – melc Feb 08 '14 at 18:08
5

Slides with random height at http://jsfiddle.net/AwBLL/108/

HTML:

<h2>Vertical align</h2>
<div class="owl-carousel bg-contain">
  <img src="http://lorempixel.com/234/100/technics/1/"  />
  <img src="http://lorempixel.com/234/400/technics/2/"  />
  <img src="http://lorempixel.com/234/200/technics/9/"  />
  <img src="http://lorempixel.com/234/150/technics/10/" />
</div>

<h2>Full Zoom small images</h2>
<div class="owl-carousel bg-cover">
  <img src="http://lorempixel.com/234/100/technics/1/"  />
  <img src="http://lorempixel.com/234/400/technics/2/"  />
  <img src="http://lorempixel.com/234/200/technics/9/"  />
  <img src="http://lorempixel.com/234/150/technics/10/" />
</div>

CSS:

.owl-wrapper-outer {
  border: 1px solid red;
  font: 0/0 a;
  line-height: 0;
}

.owl-carousel .owl-item {
  background-position: 50% 50%;
  background-repeat: no-repeat;
}
.bg-contain .owl-item { background-size: contain }
.bg-cover .owl-item { background-size: cover }

.owl-carousel .owl-item img {
  height: auto;
  width: 100%;
  visibility: hidden;
}

JS:

$(".owl-carousel").each(function () {
  var $this = $(this);

  $this.owlCarousel({
    afterUpdate: function () {
      updateSize($this);
    },
    afterInit: function () {
      updateSize($this);
    }
  });
});

function updateSize($carousel) {
  var maxHeight = 0;

  $('.owl-item', $carousel).each(function () {
    var $this = $(this);
    var $image = $this.find('img');

    //Max height
    var prevHeight = $this.height();
    var thisHeight = $this.height('auto').height();
    $this.height(prevHeight);
    maxHeight = (maxHeight > thisHeight ? maxHeight : thisHeight);

    //Set image as background
    var imageSource = $image.attr('src');
    $this.css('backgroundImage', 'url(' + imageSource + ')');
  });

  //Set equal height
  $('.owl-item', $carousel).height(maxHeight);
}
shilovk
  • 11,718
  • 17
  • 75
  • 74
bekliev
  • 2,331
  • 2
  • 12
  • 11
1

My images are loaded dynamically, which mean image name could changes from time to time, how could keep as a background image and pass the proper image name into css file?

Allen
  • 316
  • 3
  • 7
0

if you are using div with background image in your carsoual You can try controlling the size of the background by using the background-size property.

#header {
 -webkit-background-size:100%;
 -moz-background-size:100%;
  background-size:100%;
  background-position: 0% 0%;
  background: url(http://i47.tinypic.com/2090r3c.jpg) no-repeat;
}

Or else if you use then you can useauto resize according to container width

img {
 height: inherit; 
 max-height: 100%;

}

0

Wish you'd put up a fiddle, but off the top of my Notepad++ you could try putting this at the bottom of your page and see if that works out for you.

<script>
$(document).on('resize', function(e){
    var OIs = $('.owl-item')
        minHeight = 0;
//reset overflow
OIs.css('overflow', 'visible');

    //cycle through items and add height to array
    for (i==0;i<OIs.length;i++){
        var thisHeight = OIs[i].innerHeight;
        if (thisHeight != undefined && thisHeight != null && thisHeight > 0){
            if (minHeight == 0 ){
                minHeight = thisHeight;
            } else if (thisHeight < minHeight){
                minHeight = thisHeight;
            }               
        }
    }
    //resize containers to smallest height
    OIs.css({'overflow':'hidden', 'height': minHeight + 'px'}       
});
</script>

if it works there are better ways to write this but it'll give you the start of a solution

Thierry Blais
  • 2,848
  • 22
  • 41
0

You can achieve equal height using flexbox. Try this:

.owl-stage
   display flex
.owl-item
   flex 0 0 auto
Crashh
  • 9
  • 4