简体   繁体   中英

how to add sub menus on a responsive css menu

I have this html for my css menu:

<nav class="clearfix">
    <ul class="clearix">
        <li><a href="http://www.domain.co.uk/">Homepage</a></li>
        <li><a href="/services">Services</a></li>
        <li><a href="/project-gallery">Project Gallery</a></li>
        <li><a href="/contact-us">Contact Us</a></li>  
    </ul>
    <a href="#" id="pull">Menu</a>  
</nav>

nav {
    height: 50px;  
    width: 100%;  
    background: #F00;  
    font-size: 14pt;  
    font-family: Arial;
    position: relative;  
    border-bottom: 5px solid #FFFFFF;  
}  
nav ul {  
    padding: 0;  
    margin: 0 auto;  
    width: 100%;  
    height: 50px;
    text-align: center;
}
nav li {  
    display: inline;
}  
.clearfix:before,  
.clearfix:after {  
    content: " ";  
    display: table;  
}  
.clearfix:after {  
    clear: both;  
}  
.clearfix {  
    *zoom: 1;  
}  
nav a {  
    color: #FFFFFF;  
    display: inline-block;  
    width: auto;

    text-align: center;  
    text-decoration: none;  
    line-height: 50px;  
}  
nav li a {
    box-sizing:border-box;  
    -moz-box-sizing:border-box;  
    -webkit-box-sizing:border-box;
    padding-left: 10px;
    padding-right: 10px;
}  
nav li:last-child a {  
    border-right: 0;  
}  
nav a:hover, nav a:active {  
    background-color: #000000;
    color:#FFFFFF;  
} 
nav a#pull {  
    display: none;  
}  
@media screen and (max-width: 600px) {  
    nav {   
        height: auto;  
    }  
    nav ul {  
        width: 100%;  
        display: block;  
        height: auto;  
    }  
    nav li {  
        width: 50%;  
        float: left;  
        position: relative;  
    }  
    nav li a {  
        border-bottom: 1px solid #FFFFFF;  
        border-right: 1px solid #FFFFFF;  
    }  
    nav a {  
        text-align: left;  
        width: 100%;  
        text-indent: 25px;  
    }  
}  
@media only screen and (max-width : 480px) {  
    nav {  
        border-bottom: 0;  
    }  
    nav ul {  
        display: none;  
        height: auto;  
    }  
    nav a#pull {  
        display: block;
        color:#FFFFFF;
        background-color: #F00;  
        width: 100%;  
        position: relative;  
    }  
    nav a#pull:after {  
        content:"";  
        background: url('nav-icon.png') no-repeat;  
        width: 30px;  
        height: 30px;  
        display: inline-block;  
        position: absolute;  
        rightright: 15px;  
        top: 10px;  
    }  
}  
@media only screen and (max-width : 320px) {  
    nav li {  
        display: block;  
        float: none;  
        width: 100%;  
    }  
    nav li a {  
        border-bottom: 1px solid #FFFFFF;  
    }  
}  

I am looking for a way to add sub menus and then second sub menus on on the first ones but still keep it as responsive as it is.

How can I do this?

http://jsfiddle.net/EYjnG/

logic is just simple and have with this code 逻辑很简单,并且具有此代码

#submenu,#submenu2,#submenu3{
    visibility:hidden;       /*turn all the submenus visibility hidden */
}
#top_menu li.first:hover #submenu,#submenu li.second:hover #submenu2,#submenu2     li.second:hover #submenu3{
    visibility:visible;      /*On hover turn on visibility visible */
}      

Complete code :

<div id="top_menu">  <!--MAIN MENU -->                      
    <ul>
        <li class="first">menu1                 
            <div id="submenu">   <!--First Submenu -->
                <ul class="abc">
                    <li class="second">item1    
                        <div id="submenu2">  <!--Second Submenu -->
                            <ul class="abc">
                                <li class="second">item1_1
                                    <div id="submenu3">  <!--Third Submenu -->
                                        <ul class="abc">
                                            <li class="second">item1_1_1</li>
                                            <li class="second">item1_1_2</li>
                                            <li class="second">item1_1_3</li>
                                        </ul>
                                    </div>  <!--third Submenu Ends here-->
                                </li>
                                <li class="second">item1_2</li>
                                <li class="second">item1_3</li>
                            </ul>
                        </div>  <!--Second Submenu Ends here-->                         
                    </li>
                    <li class="second">item2
                                <div id="submenu2">
                                    <ul class="abc">
                                        <li class="second">item2_1</li>
                                        <li class="second">item2_2</li>
                                        <li class="second">item2_3</li>
                                    </ul>
                                </div>                              
                    </li>
                    <li class="second">item3
                                <div id="submenu2">
                                    <ul class="abc">
                                        <li class="second">item3_1</li>
                                        <li class="second">item3_2</li>
                                        <li class="second">item3_3</li>
                                    </ul>
                                </div>                              
                    </li>
                </ul>
            </div>
        </li>   

        <li class="first">menu2
            <div id="submenu">
                <ul class="abc">
                    <li class="second">item1</li>
                    <li class="second">item2</li>
                    <li class="second">item3</li>
                    <li class="second">item4</li>
                </ul>
            </div>
        </li>

    </ul>   
</div>

ul{
    padding:10px;
    padding-right:0px;
}
li.first{
    display:block;
    display:inline-block;
    padding:5px;
    padding-right:25px;
    padding-left:25px;
    cursor:pointer;
}
li.second{
    list-style:none;
    margin:0px;
    padding:5px;
    padding-right:25px;
    margin-bottom:5px;
    cursor:pointer;
}
#submenu li.second:hover{
    background:red;
    border-radius:5px;
}

#submenu2 li.second:hover{
    background:green;
    border-radius:5px;
}
/*********MAIN LOGIC***************/

#submenu,#submenu2,#submenu3{
    visibility:hidden;
}
#top_menu li.first:hover #submenu,#submenu li.second:hover #submenu2,#submenu2 li.second:hover #submenu3{
    visibility:visible;
}
/**********STYLING SUBMENUS**************/
#submenu{
    padding-right:0px;
    text-align:left;
    position:absolute;
    background:white;
    box-shadow:0px 0px 5px;
    border-radius:5px;
}
#submenu2{
    text-align:left;
    position:absolute;
    left:70px;
    top:0px;
    background:red;
    box-shadow:0px 0px 5px;
    border-radius:5px;
}
#submenu3{
    text-align:left;
    position:absolute;
    left:80px;
    top:0px;
    background:green;
    box-shadow:0px 0px 5px;
    border-radius:5px;
}

just understand the logic behind this code and you can made as many submenus as you want.

There are many ways to go ahead about this.

I usually hide the sub menu ul s with display: none and take them out of the content flow with position: absolute . Give the li containing the sub menu position: relative so that the sub menus are relative to their direct parents, then position the sub menus however you please using the top , right , bottom and left properties. Finally, change the sub menu to display: block through a :hover or whatever.

Here's a bare-bones example of this:

Markup:

<nav>
  <ul>
    <li><a>Link</a>
      <ul>
        <li><a>Sub link</a></li>
        <li><a>Sub link</a></li>
        <li><a>Sub link</a></li>
      </ul>
    </li>
  </ul>
</nav>

CSS:

nav li {
  position: relative;
}

nav li > ul {
  position: absolute;
  top: 100%;
  display: none;
}

nav li:hover > ul {
  display: block;
}

Here's a pen with this example . It looks like crap but you get the drill.

You can just keep nesting more sub-menus, but you'll probably want to use different positioning for second-and-lower-levels of sub menus.

However, please note that mobile browsers don't really support :hover . At least they don't treat it the same. You shouldn't make your sub menus accessible only on :hover . Consider adding some sort of class name toggle on click with javascript instead.

I am not 100% sure if your asking how to make the id menu have a menu functionality or just a sub menu for your main nav.

If it is pertaining to a sub menu for your main nav then this will work just fine. If it's for the mobile menu then let me know and I'll work something out for you. (SOLVED)

This fiddle has the sub menu working while still being responsive the entire time. You can style it to your needs but it is a solid start.

nav ul li ul {
  display: none;
  position: absolute;
  width: 100%;
  top: 100%;
  background: #000;
  color: #fff;
}

nav ul li:hover ul {
  display: block;
}

nav ul li ul li {
  display: block;
  -webkit-transition: .6s ease;
  -moz-transition: .6s ease;
  -ms-transition: .6s ease;
  -o-transition: .6s ease;
}

nav ul li ul li:hover {
  background: #c1c1c1;
  color: #2b2b2b;
}

JSFIDDLE

JSFIDDLE with relative sized sub menu

Here is the mobile navigation working and the biggest problem was you had no jQuery library selected for the fiddle to run off of.

Mobile Nav

HTML

<div id="pull"><span>Menu</span>

</div> 

CSS

div span {
  color: #FFFFFF;  
  display: inline-block;  
  width: auto;
  text-align: center;  
  text-decoration: none;  
  line-height: 50px;
  padding-left: 10px;
  padding-right: 10px;
}

I changed the id pull to a div because when it was an anchor tag all of the navs would lose their text color.

I have made a drop-down with a drop-down in it while still being responsive! Take a peak at this jsfiddle.

JSFIDDLE Drop-Down with a nested Drop-Down

use hover in css like:

a:hover

or if your div id is "div1":

#div1:hover 

Here's my take: http://codepen.io/teodragovic/pen/rmviJ

HTML

<nav>
  <input type="checkbox" id="nav-toggle-1" />
  <label for="nav-toggle-1" class="pull sub"><a>Menu</a></label>  
  <ul class="lvl-1">
    <li><a href="http://www.domain.co.uk/">Homepage</a></li>
    <li>
      <input type="checkbox" id="nav-toggle-2" />
      <label for="nav-toggle-2" class="sub"><a>Services</a></label>
      <ul class="lvl-2">
        <li><a href="#">Service 1</a></li>
        <li><a href="#">Service 2</a></li>
        <li>
          <input type="checkbox" id="nav-toggle-3" />
          <label for="nav-toggle-3" class="sub"><a>Service 3</a></label>
          <ul class="lvl-3">
            <li><a href="#">Service 3 a</a></li>
            <li><a href="#">Service 3 b</a></li>
          </ul>
        </li>
        <li><a href="#">Service 4</a></li>
      </ul>
    </li>
    <li><a href="/project-gallery">Project Gallery</a></li>
    <li><a href="/contact-us">Contact Us</a></li>  
  </ul> 
</nav>

CSS

@import "compass";

/* globals */
* {box-sizing:border-box;}

ul {
  margin: 0;
  padding: 0;
}

input {
  position: absolute;
  top: -99999px;
  left: -99999px;
  opacity: 0;
}

nav {
  height: 50px;
  background: #F00;  
  font: 16px/1.5 Arial, sans-serif;
  position: relative;
}

a {  
  color: #FFFFFF;  
  display: inline-block;
  text-decoration: none;  
  line-height: 50px;  
  padding: 0 20px;
  &:hover,
  &:active {
    background-color: #000000;
    color:#FFFFFF;
  }
}

/* nav for +600px screen */

ul.lvl-1 { 
  text-align: center;
  @include pie-clearfix;
  li {
    display: inline;
  }
}

ul.lvl-2, 
ul.lvl-3 {
  position: absolute;
  width: 100%;
  background: lighten(red, 15%);
  display:none;
}
ul.lvl-3 {background: lighten(red, 30%);}    

#nav-toggle-2:checked ~ ul.lvl-2,
#nav-toggle-3:checked ~ ul.lvl-3 {
  display: block;
}

.pull {display: none;}

/* arrow thingy - crappy positioning, needs tinkering */
.sub {
  position: relative;
  cursor: pointer;
  &:after {  
    position: absolute;
    top: 40%;
    right: 0;
    content:"";  
    width: 0;
    height: 0;
    border-right: 6px solid transparent;
    border-left: 6px solid transparent;
    border-top: 6px solid white;
  }  
}

/* medium-ish nav */

@media screen and (max-width: 600px) {  

nav {height: auto;}

a {  
  text-align: left;  
  width: 100%;  
  text-indent: 25px;
  border-bottom: 1px solid #FFFFFF;
}

ul > li {  
  width: 50%;  
  float: left;
  &:nth-of-type(odd) {
    border-right: 1px solid white;
  }
}

li:nth-of-type(even) ul.lvl-2,
li:nth-of-type(even) ul.lvl-3 {
  position: relative;
  width: 200%;
  left: -100%;
}

li:nth-of-type(odd) ul.lvl-2,
li:nth-of-type(odd) ul.lvl-3 {
  position: relative;
  width: 200%;
  left: 1px;
}

ul.lvl-2 li {background: lighten(red, 15%);}
ul.lvl-3 li {background: lighten(red, 30%);}

}

/* small-ish nav */

@media only screen and (max-width : 480px) {

.pull {
  display: block;
  width: 100%;  
  position: relative;  
}

ul {
  height: 0;  
  > li {
    width: 100%;
    &:nth-of-type(odd) {
      border-right: none;
    }
  }
}  

#nav-toggle-1:checked ~ ul.lvl-1 {
  height: auto;
}

#nav-toggle-2:checked ~ ul.lvl-2,
#nav-toggle-3:checked ~ ul.lvl-3 {
  //reverting stuff from previous breakpoint
  left: 0;
  width: 100%;
}

}

Markup is little modified from original since I find it easier to use classes than general selectors, especially when nesting lists.

It's CSS only (I'm using SASS+compass). :checked pseudo-class are used for toggling menus on and off. I removed link for services assuming that it will be used just for opening sub-menu (content-wise, you could always add something like "all services" in submenu if you want to keep that page in navigation).

Biggest challenge was styling middle breakpoint. Depending on position of parent list item (odd or even), child list is stretched to 200% (because parent is 50% wide) and positioned so it floats from left side. Small bug appears on level 3 regarding width of the list causing color bleed on edges.

Additionaly, display: block and display:none selectors could be replaced with max-height to add some cool css animation effects

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM