Zack Peterson
Zack Peterson

Reputation: 57333

Why is my DIV smaller than its contents?

I'm trying to modify the Simple jQuery Slideshow published by Jonathan Raasch.

It cycles through all images fading from each to the next.

350px square image in a 350px height DIV container http://img154.imageshack.us/img154/904/fixed.jpg

His example works with fixed-size images. I want it to instead work with images sized to a percentage width of the browser window.

This works with fixed-size images...

#slideshow {
    ...
    height:350px;
}

#slideshow img {
    ...
}

This is how I changed it...

#slideshow {
    ...
}

#slideshow img {
    ...
    width: 50%;
}

Becasue I'm no longer explicitly setting the height of the DIV "slideshow", it collapses to 0. And the image then covers up my text. Compare...

50% wide image in a zero height DIV container (overlaps text) http://img253.imageshack.us/img253/6016/variable.jpg

This is my whole HTML file including CSS and JavaScript...

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en">
    <head>
        <title></title>
        <style type="text/css">

            #slideshow {
                position:relative;
                height:350px;
            }

            #slideshow img {
                position:absolute;
                top:0;
                left:0;
                z-index:8;
            }

            #slideshow img.active {
                z-index:10;
            }

            #slideshow img.last-active {
                z-index:9;
            }

        </style>
        <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
        <script type="text/javascript">

            function slideSwitch() {
                var $active = $('#slideshow img.active');
                if ( $active.length == 0 ) $active = $('#slideshow img:last');
                var $next =  $active.next().length ? $active.next()
                    : $('#slideshow img:first');
                $active.addClass('last-active');
                $next.css({opacity: 0.0})
                    .addClass('active')
                    .animate({opacity: 1.0}, 1000, function() {
                        $active.removeClass('active last-active');
                    });
            }

            $(function() {
                setInterval( "slideSwitch()", 5000 );
            });

        </script>
    </head>
    <body>

        <div id="slideshow">
            <img src="img/img1.jpg" alt="" class="active" />
            <img src="img/img2.jpg" alt="" />
            <img src="img/img3.jpg" alt="" />
        </div>

        <p>Lorem ipsum ...</p>

    </body>
</html>

Why is my DIV smaller than its contents? How can I make my DIV height match the height of its contents?

Upvotes: 3

Views: 8236

Answers (2)

David Kolar
David Kolar

Reputation: 3485

The absolute positioning is the reason the images are over the text (since nothing is giving the #slideshow <div> any height), but your system needs the images to be absolutely positioned in order to stack them on top of each other for the slideshow effect. Since you are using jQuery anyway, you can programmatically expand the container <div> to the height of the largest image.

var maxHeight = 0;
$("#slideshow img").each(function(){
    if (maxHeight < $(this).height()) {maxHeight = $(this).height()}
});
$("#slideshow").height(maxHeight);

I'm sure someone can point out a more elegant way to write the maxHeight part of the script!

Upvotes: 1

BonkaBonka
BonkaBonka

Reputation: 351

By setting the position of the image to absolute, you remove it from the flow of the document (where the rest of the text is) and lay it on top.

Edited:

I adjusted the CSS to:

        #slideshow {
            position:relative;
            height:1000px;
        }

        #slideshow img {
            position:absolute;
            width: 50%;
            top:0;
            left:0;
            z-index:8;
            display: none;
        }

        #slideshow img.active {
            z-index:10;
            display: inline;
        }

        #slideshow img.last-active {
            z-index:9;
            display: inline;
        }

Perhaps that's more like what you want. You'll need to come up with a sane height that matches the bulk of your content, but that seemed to fade pictures in and out with a minimum of "popping" when they got to the end of their cycle.

Upvotes: 9

Related Questions