views:

61

answers:

1

Hey Stack Overflow community!

Our Group is trying to create a slide-out option panel for products to be sold on our site.

For some reason, CSS is acting up on us and it's a pain to get our images to layer properly. In the past, z-index did the trick, but now we have to test random stylings and workarounds just to get remotely what we're looking for.

At the moment, we have a relative div with absolute content, which should already be raising a red flag for you layout designers.

Everything functions as it should, but why isn't this working right? I would provide an example from our ftp, but for some reason my internet is acting up and I can't get the content uploaded.

For now, here's our source:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
    <html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
    <link type="text/css" href="css/ui-lightness/jquery-ui-1.8.5.custom.css" rel="Stylesheet" />        
    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.8.5.custom.min.js"></script>
    <script type="text/javascript">

    function move(name){

           if (name.style.left == "500px")
           {
               $(name).animate({left: 0}, 300);
           }
           else if(name.style.left == "0px")
           {
               $(name).animate({left: 500}, 300);
           }
    }

    </script>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>JQuery Test</title>
    </head>

    <body>
    <div class="item">
           <div id="top" style="z-index:1; position: absolute; top:0px; left:0px; width:500px; height:375px;">
                   <img src="images/car1.jpg" />
           </div>
           <div id="bottom" style="z-index:-1; position:absolute; top: 0px; left:0px; width:550px; height:375px;">
                   <img src="images/car2.jpg" />
               <div class="optionsExpandButton" style=" position:absolute; left: 500px; width:50px; height:375px; background-color: #000; z-index:inherit; float:left" onclick="move(bottom);"></div>
           </div>
    </div>
    </body>

    </html>

Many thanks in advance!

Justian

EDIT:

Forgot to mention the main issue.

Typically when we create our z-indexes, the images will end up below each other instead of beneath each other.

Ex:

-------------------------
|       z-index: 1      | <- img 1
-------------------------
|       z-index: -1     | <- img 2
-------------------------
+1  A: 

Edit:

After discussion I realized you wanted a slide right / left solution. Here is that solution, followed by some more general advice.

First the HTML:

<div class="item">
    <div id="top">
        <img src="http://img814.imageshack.us/img814/8089/car1j.jpg" alt="..." />
    </div>
    <div id="bottom">
        <img src="http://img178.imageshack.us/img178/3779/car2dy.jpg" alt=".." />
    </div>
    <div class="optionsExpandButton"></div>    
</div>

I had some positioning and clicking issues with .optionsExpandButton inside #bottom, so I put it outside. I'm sure you could actually do it either way.

Anyway, notice the complete lack on inline CSS or JS. Dont' forget to add your alt tags for accessibility!

Now let's set the positioning up so we can slide left to right correctly.

We'll position .item absolutely and the 3 divs inside relatively.

This means that #top is at left:0, top:0. Now #bottom would be below that at left:0, top:375, but we want it right on #top so #bottom will get left:0, top:-375. The expand div would be at left:0, top:750, but we want it at the height of #top and to the right of it, since #top is 500 wide that make the expand button at left:500, top:-750:

The CSS

img, div { border:0; padding:0; margin:0; }
div.item {
    position: absolute; /* This could also be relative */ }
#top {
    z-index:1;
    position: relative; 
    top:0px; left:0px; 
    width:500px; height:375px; }
#bottom {
    z-index:-1; 
    position:relative; 
    top: -375px; left:0px; 
    width:550px; height:375px; }
div.optionsExpandButton {  
    position:relative;
    width:50px; height:375px; 
    top: -750px; left: 500px;
    background-color: #000; 
    z-index:999; }

Now, let's make use of .toggle() for sliding right than left instead of an awkward if statement:

The JS:

$(function() {
    $(".optionsExpandButton").toggle(function() {
        $(this).animate({left: '+=425' });
        $("#bottom").animate({left: '+=425' });
    }, function() {
        $(this).animate({left: '-=425' });        
        $("#bottom").animate({left: '-=425' });    
    });
});
​

Try it out at this jsFiddle

(on its own page)

Below is the old answer:


I would advise against inline JS and inline CSS. Keep the content separate from the functionality and styling.

You might find it much easier to just list all your divs without positioning, and then position everything with jQuery. This also applies to your z-index.

It looks like you want to show one image, and on click slide down another image.

I'll show you a way to do this quite simply without worrying about CSS. The method degrades nicely if a user has JS disabled in that both images will be visible without JS, which is not true if you rely on setting CSS z indices and position one image above the other.

First I'll show you how to do one slider with IDs, similar to how you have. Then I'll show you how to put as many different image sliders as you want on one page using classes.


One slider with IDs:

So, first, I would set up the HTML in a way that makes sense without JS. Just one image after the other. I would make no JS or CSS inline. Don't forget about your alt tags for accessibility.

<div class="item">
       <div id="top">
               <img src="images/car1.jpg" alt="..." />
       </div>
       <div id="bottom">
               <img src="images/car2.jpg" alt="..." />                   
       </div>

       <!-- Don't nest this button in either top or bottom! -->
       <div id="expand">+ Expand</div>
</div>

Now the jQuery can hide image #2 when the page is ready and slide it up and down when the expane div is pressed. You can use classes for the button, but that's a little more complicate, so first I'll show how to do it with an id:

$(function() {  // <== doc ready

    $("#bottom").hide();          // Hide the second image

      // Define what happen on button click
    $("#expand").click(function() {
        var $this = $(this);   // This is for efficiency

          // Toggle the second image sliding up or down
        $("#bottom").slideToggle();

          // Toggle the writing in the button.
        $this.html() == "+ Expand" ? 
            $this.html("- Contract") :
            $this.html("+ Expand");
    });
});​

Try it out with the jsFiddle example



Many sliders with classes:

Now let's generalize and use just classes with divs set up a certain way.

HTML:

<div class="item">
       <div class="top"><img src="img1a"  alt="..." /></div>
       <div class="bottom"><img src="img2a"  alt="..." /></div>
       <div class="expand">+ Expand</div>
</div>
<div class="item">
       <div class="top"><img src="img1b"  alt="..." /></div>
       <div class="bottom"><img src="img2b"  alt="..." /></div>
       <div class="expand">+ Expand</div>
</div>
...

jQuery

$(function() {
    $("div.item div.bottom").hide();
    $(".expand").click(function() {
        var $this = $(this);
        $this.prev().slideToggle();
        $this.html() == "+ Expand" ? 
            $this.html("- Contract") :
            $this.html("+ Expand");
    });
});​

Try it out with this jsFiddle



References:

Peter Ajtai
@Peter Ajtai: Well, it does bring the optionsExpandButton in-line with the bottom image, but some functionality still needs to be changed. However, the main issue that we're looking for has yet to be fixed. If you're testing this with dummy images on your computer, set the positions to relative to see what I mean.
Justian Meyer
@Justian - jsFiddle is down. I'll make an example when it's up. If you only want one image showing, then hide the other with jQuery not zIndex. Since this is in a JS slider, that's a fine option. Also take a look at the jQuery `.toggle()`, `.slideUp()`, `.slideDown()`, and `slideToggle()`. - gtg gl
Peter Ajtai
@Peter Ajtai: We're all new to jQuery (just started today), so I'll wait for your complete example while messing with the code above in the meantime. Thanks for the help thus far.
Justian Meyer
@Justian - I think I got what you're after. You want the first image to be always visible and the second image to slide down and up when the button is pressed, right?
Peter Ajtai
@Peter Ajtai: Very close to what we're looking for. The only difference is that we plan to have ours slide out to the right, which seems like a different construction in JQuery. It's a little different in a sense that the image doesn't slide out from underneath the image, but it might work. I'll see if I can set up a jsFiddle with what we're looking for (roughly).
Justian Meyer
@Peter Ajtai: Functional version of what I have above. http://jsfiddle.net/7mSTL/1/. Our issue (1) That our clickable bar is below the images (should be flush with right side of bottom image) and (2) that our "relative"/"absolute"s are all over the place. We want the outer div to be "absolute" and every other image/div within it to be "relative", but we get some funky results. Mess around with it and you'll see what I mean.
Justian Meyer
@Justian - Your CSS is off. Relative is positioned relative to where it would be by default. The absolute should be the `.item` ==> http://jsfiddle.net/Ekazp/ -------- Also, if that side dive is inside `#bottom` I have a hard time with the CSS, so I just put it outside.
Peter Ajtai
@Peter Ajtai: Thanks so much! Just changed "425" to "500" and it was perfect! (http://jsfiddle.net/Ekazp/1/) We'll look over this tomorrow to fully understand it. Thanks again!
Justian Meyer
@Justian - Glad to help. I got a little more familiar with `.animate()` by helping you, so that's good. That previous code still has a vestigal `.move()` function, you can just cut that out: http://jsfiddle.net/5T3Lk/
Peter Ajtai
@Peter Ajtai: Yeah, I noticed that. I've looked over this and everything makes sense. Any suggestions for implementing multiple expanders side-by-side?
Justian Meyer
@Justian - That gets tricky. .items positioned relative and floated left inside a parent div of fixed size, and z-index of elements changed strategically. Here's a quick try ==> http://fiddle.jshell.net/TCrvS/show/light/ ---- Note that I don't use z-index -1 since IE didn't like it. -------- You have to pay attention to what `this` is inside each function.
Peter Ajtai
@Peter Ajtai: Luckily, we plan to have only one slider open at a time, so when we click one, the previously open one should return to its original state (it'll clear up some of the overlap issues). I suppose we could also have the function push everything else to the side (or css it up differently). This looks like it's going to be quite the challenge. Ideally, we're looking to have the image to the right halve its size in order to make room for the newly opened tab, then return to normal when it's closed.Urg
Justian Meyer