views:

116

answers:

6

http://clifgriffin.com/blockade2/

Ok, I have an unordered list that serves as a list of menu links. In each li there is a div that is set to absolute positioning, bottom: 0. The idea is you hover over the link in the li and jQuery animates the height to show the hidden menu div.

It's a simple concept, but I am apparently a retard.

The issue I'm having is that the div that contains the slide down menu doesn't take up any dimensions (according to Firefox and Chrome's calculated style information) when I put it in the li. If I put it anywhere else on the page it renders PERFECTLY. You can see what I mean from the link. The gray menu looking thing at the top is how it is supposed to render inside the li but doesn't.

<div class="ram">
    <div class="gray_middle">
            <ul>
                    <li><a href="">Guest Services</a></li> 
                    <li><a href="">Concierge / Local Attractions</a></li>
                    <li><a href="">East Restaurant</a></li>
                    <li><a href="">Aquarium Lounge</a></li>
                    <li><a href="">Health Club</a></li>
                    <li><a href="">Sandcampers Program</a></li>
                    <li><a href="">Treasure Chest Gift Shop</a></li>
            </ul>
    </div>
    <div class="gray_bottom">
            <img src="images/top_menu_slidedown_gray_bottom.png" />
    </div>

There is a bit of javascript going on that is supposed to find the height of the menu div and set the id of the containing li equal to the height so that it can be referenced later. Doesn't matter...the point is, when the div is in the li, its computed height is 0. When it is outside, it's correct.

Any ideas?

This is driving me absolutely batty. I have never had this many issues with something so simple.

Thanks in advance, Clif

P.S. I added some HTML comments to the destination so that you can better see what I mean.

A: 

When you absolutely position an element, it won't expand the size of it's container to the size required to accommodate it.

EXAMPLE

HTML

<div id="outer"><div id="inner">In</div>Out</div>

CSS

#outer {
    background-color: red;
}

#inner {
    width: 100px;
    position: absolute;
    top: 100px;
    background-color: blue;
}

See it live here - http://www.jsfiddle.net/r7MgY/86/

Jamie Wong
Is there any way around this? What is the workaround/standard practice for something like this. I know what I'm trying to do is possible.</frustrated>
clifgriffin
A: 

Hi clifgriffin Had a quick look at you HTML, shame you didn't give us the CSS aswell, but ... there are a few things I'm not sure on - the header says generator WordPress 2.9.2 but the html does look like "familiar" WordPress. If it is WordPress generated then check the wp_list_pages & wp_list_categories tags you are using. Also I serously recommend an upgrade to WP3.0 as it has MUCH more functionality (custome post/page types etc) plus a "built" in menu function.

I think you may be using too much CSS. Most of what you want to acheive can be done with a lot less.

  • Guest Services
  • Concierge / Local Attractions
  • East Restaurant
  • Aquarium Lounge
  • Health Club
  • Sandcampers Program
  • Treasure Chest Gift Shop
  • You can then give the ul an ID (remember ID's need to be unique) this will help with any Java you want to use also add to your ram class with a background image class images/top_menu_slidedown_gray_bottom.png. As you use the ram class again without the image. e.g. <div class="ram backgroundimageclass"> You are then saving a lot of "code" and download times etc.

    If you give the ram class the attribute "position: relative;" you can then give the UL id the attribute "position: absolute;" the li's can be styled such as

    ul#ID li {line-height 30px; etc ...)
    ul#ID li:hover {line-height 30px; etc ...)
    ul#ID li:hover a {line-height 30px; etc ...)
    

    and so on.

    Ohh forgot ... also why not add this code in the head

    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    

    And this just after the tag

        <!-- DO NOT REMOVE  -->
    
    <!-- THIS SECTION SETS THE LAYOUT FOR GOOGLE CHROME FRAME IF YOU NEED FURTHER INFO LOOK HERE http://code.google.com/chrome/chromeframe/ -->
    <!-- Google Chrome Frame is a free plug-in that helps you enjoy modern HTML5 web apps within Internet Explorer. -->
    
    <div id="prompt"><!-- if IE without GCF, prompt goes here --></div>
    
    <script type="text/javascript">
        CFInstall.check({
         mode: "inline", // the default
         node: "prompt"
        });
    </script> 
    <!-- END THE LAYOUT FOR GOOGLE CHROME FRAME -->
    

    This allows "detection" of the browser and gives them the option (if not installed) to use Google Chrome Frame, you can: Start using open web technologies - like the HTML5 canvas tag - right away, even technologies that aren't yet supported in Internet Explorer 6, 7, or 8. Take advantage of JavaScript performance improvements to make your apps faster and more responsive. Enabling Google Chrome Frame is simple. For most web pages, all you have to do is add a single tag to your pages like above and detect whether your users have installed Google Chrome Frame. If Google Chrome Frame is not installed, you can direct your users to an installation page. If Google Chrome Frame is installed, it detects the tag you added and works automatically.

    It will be part of WP in the end. I'm modifying a theme.
    clifgriffin
    Hi again Cliff, OK - dont forget to wp_list_pages/catagores ('title_li=') then cos you will have additional UL's to deal with unless you write the query as a custom wp query
    Oh and again don't forget to wp_enqueue_script your JQuery bits in the "functions file" BUT something I have noticed of late (I do a lot of custom WP stuff) is it seems best to put your wp_enqueue_script scripts inside an if ( !is_admin() ) : statement as there appears to be much more "area for" conflict now
    +1  A: 

    Absolutely positioned elements are "outside" of a container and can't really determine its size.

    Relatively positioned elements impact container size (and content flow) but then they move elsewhere.

    Also, for absolutely and relatively positioned elements, you should always give an explicit X,Y position. This avoids some rendering differences, cross browser.

    Anyway, I made the following CSS changes and that submenu seemed to render OK on FF 3.6.4:

    1. For <li id="49"> add: height: 230px; overflow: hidden; .

    2. For div.subMenu add: top: 17px; and delete: bottom:0; .

    3. For gray_middle add: height:160px; top:0; and delete: padding-top:20px; .

    Brock Adams
    That's the problem though, I need it to expand to fit the content or it is pretty useless.
    clifgriffin
    @clifgriffin, I thought you were using jQuery to set heights anyway? This is just 2 more to set. If the rest of the layout is working and **if** javascript is required for the menu anyway then this might be a small price to pay to not have to revamp the design?
    Brock Adams
    Well, the problem is...jQuery.height() doesn't return the actual height. I have no way of knowing what the height should be in pixels since the content will potentially be dynamic.
    clifgriffin
    You can get the height `gray_middle` needs to be with `$("#49 div.gray_middle ul:first").outerHeight (true) );`.Set that then use a similar technique to find the needed height for `<li id="49">`.
    Brock Adams
    Relatively positioned elements are positioned according to normal flow and then shifted. They have as much impact on the layout of elements around them as statically positioned elements do. It is only absolute and fixed elements that are taken out of normal flow.
    David Dorward
    @David Dorward: I stand corrected.
    Brock Adams
    A: 

    Cliff Just "totally" realised what you are trying to do here - sorry took so long to "twig" OK you can do this with much more ease than you are trying to do at the moment. All it needs is a little JQuery and some basic CSS. No need to positions absolute etc.

    In your CSS use { display: none; } for the class="subMenu" as you know this will "hide" it, I might also be tempted to do the same in your JQuery functions to be "doubly sure". Then in the JQuery create a mouseover effect (mouse over "better" than hover) for the class top_menu_links (I think you could take out the classes "aco" and "white_middle" or at least combine them in the css for the relevant ul) to show the .next('ul); you can slide it etc. Then a mouseout function on the ul. That way the ul stays visable until a mouse out event. I have done this quite successfully on a WP theme to display a "dynamic" list of categories on a mouse over event on a div made to look like a button. Sorry don't have the code to hand but will look later and "pass it over"

    In addition you can set the ul background image as the approp. <img src="images/top_menu_slidedown_white_bottom.png" /> (or grey) just by setting it to background position: bottom repeat: none; and a bottom padding the height of the image. No need for alt tags etc.

    Hi Russ, thanks for your response! I understand what you're suggesting...seems like it would work, except I can see a scenario where someone hovers over the link but then slides their mouse up. In this scenario, the menu would never rehide until they moused over it. They could even trigger another menu...not quite the effect I'm going for.I'm going to take your ideas here though and see if I can come up with something inbetween. Thanks again!
    clifgriffin
    A: 

    Hi Cliff Sorry been "out for a bit" anyhow here is a code I have used to "recreate" your bottom menu. It doesn't do as you suggest it closes after either a mouseout of the "menu item" or the "submenu". To get it to work on the top menu, just change the position from bottom to top:

    $(document).ready(function() {
    $('.indexMenu').mouseover(function(){
    $(this).children().show();
    $(this).children().mouseover(function(){
    $(this).children().show();
    });
    });
    
    $('.indexMenu').mouseout(function(){
    $('.sub_menu').hide();
    });
    });
    

    Here is the "html"

    <div class="indexMenu">
     Menu 1
        <div class="sub_menu">
            Item
            <br />
            Item
            <br />
            Item
        </div>
     </div>
    
      <div class="indexMenu">
      Menu 2
        <div class="sub_menu">
        Item
        <br />
        Item
        <br />
       Item
        <br />
        Item
        </div>
     </div>
    
      <div class="indexMenu">
    
        <div class="sub_menu">
        Menu 3
        <br />
        Item
        <br />
        Item 
        <br />
        Item
        <br />
        Item
        </div>
     </div>
    
      <div class="indexMenu">
      Menu 4
        <div class="sub_menu">
        Item
        </div>
     </div>
    

    Obviously you can "use" any thing in submenu a ul,ol, etc...

    And the "simple CSS

    .indexMenu {
    position: relative;
    bottom: 3px;
    width: 240px;
    height: 32px;
    float: left;
    line-height: 30px;
    border-top: 2px solid #FFFFFF;
    text-align:center;
    text-transform:uppercase;
    text-shadow: 1px 1px 1px rgba(255, 255, 255, 1);
    font-weight: 900;
    color:#333333;
    

    }

    .sub_menu {
        display: none;
        position: absolute;
        bottom: 33px;
        width: 240px;
        background-color:#DBF3FD;
        opacity:0.8;
        filter: alpha(opacity=80);
    }
    

    OK I've added a filter in the submenu to have a certain transparency

    A: 

    Gentleman, Thanks for all of your responses! I'm sorry it took me so long to get back to this post.

    This whole issue has revealed a few things I don't yet understand about the way HTML elements are rendered.

    I was able to solve this problem by switching the main menu blocks to div elements instead of li elements.

    This makes no sense to me in that both are rendered approximately the same way as far as I can tell from looking through the computed styles. But, for whatever reason, once the container is a div the contained divs rendered with their proper dimensions which allowed the rest of my code to work properly. I didn't even have to change the attached CSS!

    As the main goal of this project was to finish and make the customer happy, I didn't experiment beyond this finding.

    I welcome theories on why this would be.

    Thanks again. Clif

    clifgriffin