0

I'm always looking for different menu styles for websites and ran across this really simple menu here: http://www.w3schools.com/howto/howto_js_topnav.asp

What I like about the menu is that it is responsive and works out of the box with my menu (for the most part). The only problem I ran into is the submenus. This menu doesn't seem to have any css for the submenus, but I figured it shouldn't be too hard, right? I got really close, but I think I need a little tweak to get the submenu functioning.

The JavaScript:

<script>
    /* Toggle between adding and removing the "responsive" class to topnav when the user clicks on the icon */
    function myFunction() {
        var x = document.getElementById("myTopnav");
        if (x.className === "topnav") {
            x.className += " responsive";
        } else {
            x.className = "topnav";
        }
    }
</script>

The HTML (although I removed some of the default WordPress classes and list URL's so it's easier to follow):

<ul class="topnav" id="myTopnav">
    <li><a href="http://url.com/">Home</a></li>
    <li>
        <a href="http://url.com/">Pictures</a>
        <ul class="children">
            <li><a href="http://url.com/">Beaver</a></li>
            <li>
                <a href="http://url.com/">Duck</a>
                <ul class="children">
                    <li><a href="http://url.com/">Fever</a></li>
                </ul>
            </li>
            <li><a href="http://url.com/">Frog</a></li>
        </ul>
    </li>
    <li><a href="http://url.com/">Nominations</a></li>
    <li><a href="http://url.com/">Contact</a></li>
    <li class="icon">
        <a href="javascript:void(0);" onclick="myFunction()">&#9776;</a>
    </li>
</ul>

The CSS:

/* Remove margins and padding from the list, and add a black background color */
ul.topnav {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #333;
}

/* Float the list items side by side */
ul.topnav li {float: left;}

/* Style the links inside the list items */
ul.topnav li a {
    display: inline-block;
    color: #f2f2f2;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none;
    transition: 0.3s;
    font-size: 17px;
}

/* Change background color of links on hover */
ul.topnav li a:hover {background-color: #555;}

/* Hide the list item that contains the link that should open and close the topnav on small screens */
ul.topnav li.icon {display: none;}

/* When the screen is less than 680 pixels wide, hide all list items, except for the first one ("Home"). Show the list item that contains the link to open and close the topnav (li.icon) */
@media screen and (max-width:680px) {
    ul.topnav li:not(:first-child) {display: none;}
    ul.topnav li.icon {
        float: right;
        display: inline-block;
    }
}

/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens */
@media screen and (max-width:680px) {
    ul.topnav.responsive {position: relative;}
    ul.topnav.responsive li.icon {
        position: absolute;
        right: 0;
        top: 0;
    }
    ul.topnav.responsive li {
        float: none;
        display: inline;
    }
    ul.topnav.responsive li a {
        display: block;
        text-align: left;
    }
}

The Submenu CSS:

/* CSS I added */
ul.topnav .page_item_has_children ul {
    display: none;
}

ul.topnav .page_item_has_children:hover ul {
    display: block;
}

ul.topnav .page_item_has_children:hover li {
    width: 100%;
}

I'm not sure what I did wrong here, but I was expecting the menu to function like: http://blog.teamtreehouse.com/wp-content/uploads/2015/01/css-dropdown.png

Right now, when I hover over the menu the menu the secondary menu spans the entire screen even if I put a max-width on it.

I think I'm making this a lot more complicated than it needs to be, anyone have any ideas?

LIVE example: http://joshrodg.com/site/

1 Answer 1

0

Ok...

So, after some poking around, I got something to work.

I basically combined the menu I found here: https://webdesignerhut.com/css-dropdown-menu/ with the responsiveness of my original menu.

The final code looks like...

The JavaScript:

<script>
    /* Toggle between adding and removing the "responsive" class to topnav when the user clicks on the icon */
    function myFunction() {
        var x = document.getElementById("myTopnav");
        if (x.className === "topnav") {
            x.className += " responsive";
        } else {
            x.className = "topnav";
        }
    }
</script>

The HTML (although I removed some of the default WordPress classes and list URL's so it's easier to follow):

<nav>
    <ul class="topnav" id="myTopnav">
        <li><a href="http://url.com/">Home</a></li>
            <li>
                <a href="http://url.com/">Pictures</a>
                <ul class="children">
                    <li><a href="http://url.com/">Beaver</a></li>
                    <li>
                        <a href="http://url.com/">Duck</a>
                        <ul class="children">
                            <li><a href="http://url.com/">Fever</a></li>
                        </ul>
                    </li>
                    <li><a href="http://url.com/">Frog</a></li>
                </ul>
            </li>
            <li><a href="http://url.com/">Nominations</a></li>
            <li><a href="http://url.com/">Contact</a></li>
            <li class="icon">
                <a href="javascript:void(0);" onclick="myFunction()">&#9776;</a>
            </li>
        <li class="icon">
            <a href="javascript:void(0);" onclick="myFunction()">&#9776;</a>
        </li>
    </ul>
</nav>

The CSS: /* Hide the list item that contains the link that should open and close the topnav on small screens */ ul.topnav li.icon {display: none;}

/* When the screen is less than 680 pixels wide, hide all list items, except for the first one ("Home"). Show the list item that contains the link to open and close the topnav (li.icon) */
@media screen and (max-width:680px) {
    ul.topnav li:not(:first-child) {display: none;}
    ul.topnav li.icon {
        float: right;
        display: inline-block;
    }
}

/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens */
@media screen and (max-width:680px) {
    ul.topnav.responsive {position: relative;}
    ul.topnav.responsive li.icon {
        position: absolute;
        right: 0;
        top: 0;
    }
    ul.topnav.responsive li {
        float: none;
        display: inline;
    }
    ul.topnav.responsive li a {
        display: block;
        text-align: left;
    }
}

/* Giving a background-color to the nav container. */
nav {
    margin: 100px 0;
    background-color: #E64A19;
}

/* Removing padding, margin and "list-style" from the "ul",
* and adding "position:reltive" */
nav ul {
    padding:0;
    margin:0;
    list-style: none;
    position: relative;
}

/* Positioning the navigation items inline */
nav ul li {
    margin: 0px -7px 0 0;
    display:inline-block;
    background-color: #E64A19;
}

/* Styling the links */
nav a {
    display:block;
    padding:0 10px;
    color:#FFF;
    font-size:20px;
    line-height: 60px;
    text-decoration:none;
}
/* Background color change on Hover */
nav a:hover {
    background-color: #000000;
}

@media screen and (min-width:681px) {
    /* Hide Dropdowns by Default
    * and giving it a position of absolute */
    nav ul ul {
        display: none;
        position: absolute;
        top: 100%;
    }

    /* Display Dropdowns on Hover */
    nav ul li:hover > ul {
        display:inherit;
    }

    /* First Tier Dropdown */
    nav ul ul li {
        min-width:170px;
        display:list-item;
        position: relative;
    }

    /* Second, Third and more Tiers
    * We move the 2nd and 3rd etc tier dropdowns to the left
    * by the amount of the width of the first tier.
    */
    nav ul ul ul {
        position: absolute;
        top:0;
        left:100%;
    }

    /* Change ' +' in order to change the Dropdown symbol */
    nav li > a:after { content:  ' +'; }
    nav li > a:only-child:after { content: ''; }
}

CodePen: http://codepen.io/joshrodgers/pen/GrWZBj

Woot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.