简体   繁体   中英

Dynamic indenting of dropdown menu

I've created a nested list, dropdown menu.

Problem: The CSS is only handling 1 level of nested menus. I can't figure out how to set the position of nested items so it can handle multiple levels without me having to set those rules in a CSS file.

This is a fiddle I've been working with

The CSS:

ul {
  text-align: left;
  display: inline;
  margin: 0;
  padding: 15px 4px 17px 0;
  list-style: none;
  -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
  -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
}
ul li {
  font: bold 12px/18px sans-serif;
  display: inline-block;
  margin-right: -4px;
  position: relative;
  padding: 15px 20px;
  background: #fff;
  cursor: pointer;
  -webkit-transition: all 0.2s;
  -moz-transition: all 0.2s;
  -ms-transition: all 0.2s;
  -o-transition: all 0.2s;
  transition: all 0.2s;
}
ul li:hover {
  background: #555;
  color: #fff;
}
ul li ul {
  padding: 0;
  position: absolute;
  top: 48px;
  left: 0;
  width: 150px;
  -webkit-box-shadow: none;
  -moz-box-shadow: none;
  box-shadow: none;
  display: none;
  opacity: 0;
  visibility: hidden;
  -webkit-transiton: opacity 0.2s;
  -moz-transition: opacity 0.2s;
  -ms-transition: opacity 0.2s;
  -o-transition: opacity 0.2s;
  -transition: opacity 0.2s;
}
ul li ul li { 
  background: #555; 
  display: block; 
  color: #fff;
  text-shadow: 0 -1px 0 #000;
}
ul li ul li:hover { background: #666; }
ul li:hover ul {
  display: block;
  opacity: 1;
  visibility: visible;
}

Try using child selector a > b instead of descendant selector ab .

You may not need child selectors everywhere, for the common styles you can make use of the descendant selectors itself, I just used it everywhere , and it may not be the right way for you!

 var items = [{ "id": "1", "title": "Menu A", "link": "http: //www.google.com" }, { "id": "2", "title": "Menu B", "link": "http://www.google.com" }, { "id": "3", "title": "Menu C", "link": "http://www.google.com" }, { "id": "4", "title": "Menu D", "link": "http://www.google.com" }, { "id": "5", "title": "Menu E", "link": "http://www.google.com" }, { "id": "6", "title": "Menu 1A", "link": "http://www.google.com", "parent": "1;#Menu A" }, { "id": "7", "title": "Menu 2A", "link": "http://www.google.com", "parent": "1;#Menu A" }, { "id": "8", "title": "Menu 3A", "link": "http://www.google.com", "parent": "1;#Menu A" }, { "id": "9", "title": "Menu 1B", "link": "http://www.google.com", "parent": "2;#Menu B" }, { "id": "10", "title": "Menu 2B", "link": "http://www.google.com", "parent": "2;#Menu B" }, { "id": "11", "title": "Menu 1C", "link": "http://www.google.com", "parent": "3;#Menu C" }, { "id": "12", "title": "Menu 2C", "link": "http://www.google.com", "parent": "3;#Menu C" }, { "id": "13", "title": "Menu 3C", "link": "http://www.google.com", "parent": "3;#Menu C" }, { "id": "14", "title": "Menu 1D", "link": "http://www.google.com", "parent": "4;#Menu D" }, { "id": "15", "title": "Menu 2D", "link": "http://www.google.com", "parent": "14;#Menu 1D" }, { "id": "16", "title": "Menu 3D", "link": "http://www.google.com", "parent": "15;#Menu 2D" }, { "id": "17", "title": "Menu 1E", "link": "http://www.google.com", "parent": "5;#Menu E" }, { "id": "18", "title": "Menu 2E", "link": "http://www.google.com", "parent": "17;#Menu 1E" }] items = $.map(items, function(item) { return { id: item.id, title: item.title, link: item.link, parent: (item.parent) ? item.parent.split(";")[0] : false } }) console.log(items) var container = $("#container"); (function createMenu() { $.each(items, function(i, v) { //Check if item has parent if (v.parent == false) { // Check if container has first level ul if (container.find("ul#topLevel").length == 0) { container.append($("<ul>").attr("id","topLevel")) } else { console.log('firstlevel exist') } //Add items to first level container .find('ul') .append($("<li>") .text(v.title) .attr('id', v.id) ) }else{ var parent = v.parent; var parentElement = $("#"+parent); if( parentElement.find('ul').length == false ) { parentElement.append($("<ul>").attr({ id: 'subLevelFor_'+ parent })) } $("ul#subLevelFor_"+ parent) .append($("<li>") .text(v.title) .attr('id', v.id) ) } }) console.log('done') })(); 
 body { font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 20px 50px 150px; font-size: 13px; text-align: center; background: #E3CAA1; } ul { text-align: left; display: inline; margin: 0; padding: 15px 4px 17px 0; list-style: none; -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15); box-shadow: 0 0 5px rgba(0, 0, 0, 0.15); } ul > li { font: bold 12px/18px sans-serif; display: inline-block; margin-right: -4px; position: relative; padding: 15px 20px; background: #fff; cursor: pointer; -webkit-transition: all 0.2s; -moz-transition: all 0.2s; -ms-transition: all 0.2s; -o-transition: all 0.2s; transition: all 0.2s; } ul > li:hover { background: #555; color: #fff; } ul > li > ul { padding: 0; position: absolute; top: 48px; left: 0; width: 150px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; display: none; opacity: 0; visibility: hidden; -webkit-transiton: opacity 0.2s; -moz-transition: opacity 0.2s; -ms-transition: opacity 0.2s; -o-transition: opacity 0.2s; -transition: opacity 0.2s; } ul > li > ul > li { background: #555; display: block; color: #fff; text-shadow: 0 -1px 0 #000; } ul > li > ul > li:hover { background: #666; } ul > li:hover > ul { display: block; opacity: 1; visibility: visible; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"></div> 

I just changed few rules in your css:

ul li:hover > ul { /* I just added ">" so it affect's only next ul. */
  display: block;
  opacity: 1;
  visibility: visible;
}

ul ul li > ul { /* This will fix the position for children uls */
    top: 0;
    left: 100%;
}

Live example: https://jsfiddle.net/xwazzo/pk7kcqb9/

Do not override the tags directly or it will be more complicated for you to expand. Create CSS classes to save your time. If you write the css like this eg: "ul li ul li" it will going to be more complicate in future. And also try to use "ul > li" selector to apply the styles on child. not child of child.

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