views:

4141

answers:

3

I'm trying to build a simple multi-level UL Horizontal Accordion (or slide menu) in Jquery. Hunter Daley graciously provided the Jquery code, but I can't seem to figure out the css. I know this is newb, but I'm really stuck.

When Ul li Ul slides out it creates a linebreak, I'd like to have everything display inline, with no breaks. I've tried whitespace: nowrap, display inline etc It just won't seem to do it. Any ideas?

As per, Glavic's answer: I was trying to to use floats, but if I do Safari bugs out and flash the sub-level UL during the animation:

Using Floats:

Right, I was trying to do it without floats. I'm trying to stick with the animation function.

Safari bugs out and flashes the sub ul during the animation.

<style type="text/css">
<!--
body {
  font-size: 1em;
  line-height: 1em;
}
ul{
  background-color: yellow;
  list-style: none;
  margin: 0;
  padding: 0;
  height: 1em;
  float: left;
}
ul li {
  background-color: aqua;
  float: left;
}
ul li ul {
  background-color: blue;
}
ul li ul li {
  background-color: green;
}
a, a:link, a:hover, a:visited, a:active {
  color: black;
  text-decoration: none;
  float: left;
}
-->
</style>

Original Post:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"&gt;&lt;/script&gt;

    <title>untitled</title>
       <style type="text/css">
    <!--
    ul{ 
     list-style: none;
     background-color: yellow;
     margin: 0;
     padding: 0;
       white-space: nowrap;
            }

    ul li {
     background-color: aqua;
     display: inline;


    }

    ul li ul { 
     background-color: blue;
        }


    ul li ul li {
     background-color: green; 
    }

    a, a:link, a:hover, a:visited, a:active {
            color: black;
            text-decoration: none;

    }
    -->
    </style>

    <script type="text/javascript">
        var $current = null;
     $(document).ready(function(){
        $("ul li ul").hide(); // hide submenus by default on load

        $("ul li a").click(function(){
           var $sub = $(this).next(); 
           if ($sub.css("display") == "none")
           {
              if ($current != null)
                 $current.animate({ width: 'hide' }); // if you want to only show one sub at a time
              $sub.animate({ width: 'show' }); 
              $current = $sub;
           }
           else
           {
              $sub.animate({ width: 'hide' });
              $current = null;
           }
        });
     });

    </script>

</head>

<body>
    <ul>
            <li>
                    <a href="#">Top-level 1</a>
            </li>
            <li>
                    <a href="#">Top-level 2</a>

                    <ul>
                            <li><a href="#">Bottom Level A1</a></li>
                            <li><a href="#">Bottom Level A2</a></li>
                            <li><a href="#">Bottom Level A3</a></li>
                            <li><a href="#">Bottom Level A4</a></li>
                    </ul>
            </li>

            <li>
                    <a href="#">Top-level 3</a>
                    <ul>
                            <li><a href="#">Bottom Level B1</a></li>
                            <li><a href="#">Bottom Level B2</a></li>
                    </ul>
            </li>

            <li>
                    <a href="#">Top-level 4</a>
            </li>
    </ul>


</body>
</html>
+1  A: 

If I understand you correctly you would like to have first and second menu level in one line (horizontal) ?

Try this:

<style type="text/css">
 ul{
  list-style: none;
  background-color: yellow;
  margin: 0;
  padding: 0;
  float: left;
 }
 ul li {
  background-color: aqua;
  float: left;
 }
 ul li ul {
  background-color: blue;
 }
 ul li ul li {
  background-color: green;
 }
 a, a:link, a:hover, a:visited, a:active {
  color: black;
  text-decoration: none;
  float: left;
 }
</style>
glavić
Thanks, but Safari bugs out and flashes the sub ul during the animation.
stapler
Don't use inline, elements are better if they are blocked. Try fixed height on other ul.
glavić
A: 

I think that "display:inline" would do the trick - but the animate function is setting the display to "block" instead of "inline".

If it is okay to "snap" into place instead of animating, you could do this instead.

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"&gt;&lt;/script&gt;

    <title>untitled</title>
    <style type="text/css">
        ul{list-style:none;background-color:yellow;margin:0;padding:0;white-space:nowrap;display:inline;}
        li ul{display:inline;}
        ul li{background-color:aqua;display:inline;}
        ul li ul{background-color: blue;}
        ul li ul li{background-color: green;}
        a, a:link, a:hover, a:visited, a:active{color: black;text-decoration: none;}
    </style>

    <script type="text/javascript">
        var $current = null;
        $(document).ready(function() {
            $("ul li ul").hide(); // hide submenus by default on load

            $("ul li a").click(function() {
                var $sub = $(this).next();
                if ($sub.css("display") == "none") {
                    if ($current != null)
                        //$current.animate({ width: 'hide' }); // if you want to only show one sub at a time
                    $current.removeAttr("display").attr({ style: "display:none;" });
                    $sub.removeAttr("style").attr({ display: "inline" });
                    $current = $sub;
                }
                else {
                    $sub.removeAttr("display").attr({ style: "display:none;" });
                    $current = null;
                }
            });
        });
    </script>
</head>

<body>
    <ul>
            <li>
                    <a href="#">Top-level 1</a>
            </li>
            <li>
                    <a href="#">Top-level 2</a>

                    <ul>
                            <li><a href="#">Bottom Level A1</a></li>
                            <li><a href="#">Bottom Level A2</a></li>
                            <li><a href="#">Bottom Level A3</a></li>
                            <li><a href="#">Bottom Level A4</a></li>
                    </ul>
            </li>

            <li>
                    <a href="#">Top-level 3</a>
                    <ul>
                            <li><a href="#">Bottom Level B1</a></li>
                            <li><a href="#">Bottom Level B2</a></li>
                    </ul>
            </li>

            <li>
                    <a href="#">Top-level 4</a>
            </li>
    </ul>


</body>
</html>
Ian Robinson
Thanks Ian, but I'm trying to stick with the animation function.
stapler
You're welcome - I just can't seem to figure out how to override the display:block that the animate function uses. Its frustrating because if you change it using firebug it displays perfectly. I just don't think the animate function will allow you to use display inline. Looking for workaround... :)
Ian Robinson
This may be the wrong path for me to be going down - it may not be possible to animate an inline element in the first place...
Ian Robinson
http://docs.jquery.com/Frequently_Asked_Questions#Why_do_animations_set_the_display_style_to_block.3F
stapler
At least it's a common problem.
stapler
A: 

It's fun to build yourself. It's also fun to use this awesomeness: http://jqueryui.com/demos/accordion/

J. LaRosee
Does the jQuery accordian allow you to display the content horizontally?
Ian Robinson
Noope, it doesn't
stapler