Showing submenu items in a jQuery menu system without causing the top level menu item to expand and fit

I currently have a menu system in place, which is quite simple, but there is an issue where the submenu items are larger than the top-level items. When hovering over the submenu items, the top-level menu expands to accommodate them.

Is there a way to keep the width of the top-level menu items fixed (since they are assigned a width through JS in a different section of the project) and have the submenu items displayed underneath regardless of their size, without affecting the top-level items?

Another problem is that the submenu items seem to be flashing on and off individually when hovered over, causing a flickering effect on the screen.

var auth_width = $("#nav > ul:nth-child(3) > li:nth-child(2)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(2)").css("width", auth_width);
var cart_width = $("#nav > ul:nth-child(3) > li:nth-child(3)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(3)").css("width", cart_width);
var country_width = $("#nav > ul:nth-child(3) > li:nth-child(4)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(4)").css("width", country_width);

$("#nav > ul > li").unbind("mouseover").bind("mouseover", function(){
    $(this).find("ul").fadeIn();
});
$("#nav > ul > li").unbind("mouseout").bind("mouseout", function(){
    $(this).find("ul").fadeOut();
});
#nav{
float:right;
}

#nav > ul > li {
    display:inline-block;
    list-style:none;
    vertical-align:top;
}

#nav > ul > li > ul{
    display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="nav">
<ul>
    <li>
        Item 1
    </li>
    <li>
        Item 2
        <ul>
            <li>Sub Item 1</li>
            <li>Sub Item 2</li>
        </ul>
    </li>
    <li>
        Item 3
        <ul>
            <li>Sub Item 1</li>
            <li>Sub Item 2</li>
        </ul>
    </li>
    <li>
        Item 4
        <ul>
            <li>Sub Item 1</li>
        </ul>
    </li>
</ul>
</div>

Edit

I have added this section to clarify that the widths of the top-level menu items are actually being set in another part of the script.

I require these widths to remain consistent and for the entire element to be floated to the right.

Answer №1

My preferred method for styling navbar elements is to use fixed width attributes. In most cases, this provides enough stability since menu links and sublinks don't typically change very frequently (although there are exceptions):

$("#nav > ul > li").unbind("mouseover").bind("mouseover", function(){
$(this).find("ul").fadeIn();
});
$("#nav > ul > li").unbind("mouseout").bind("mouseout", function(){
$(this).find("ul").fadeOut();
});
#nav{
float:right;
}

#nav > ul > li {
display:inline-block;
list-style:none;
  vertical-align:top;
    margin: 0;
    padding: 0;
    width: 80px;
}

#nav > ul > li > ul{
display:none;
    margin: 0;
    padding: 0;
list-style:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="nav">
<ul>
<li>
Item 1
</li>
<li>
Item 2
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
<li>
Item 3
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
<li>
Item 4
<ul>
<li>Sub Item 1</li>
</ul>
</li>
</ul>
</div>

Answer №2

To keep the submenu(s) from conflicting with their parent elements, you can set the CSS property position: absolute for them. This will allow the submenus to exist in their own space. However, since the menu is floated to the right, adjustments will need to be made such as using negative left margins margin-left: -25px; or setting default widths for the submenus.

var auth_width = $("#nav > ul:nth-child(3) > li:nth-child(2)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(2)").css("width", auth_width);
var cart_width = $("#nav > ul:nth-child(3) > li:nth-child(3)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(3)").css("width", cart_width);
var country_width = $("#nav > ul:nth-child(3) > li:nth-child(4)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(4)").css("width", country_width);

$("#nav > ul > li").unbind("mouseover").bind("mouseover", function(){
$(this).find("ul").fadeIn();
});
$("#nav > ul > li").unbind("mouseout").bind("mouseout", function(){
$(this).find("ul").fadeOut();
});
#nav{
float:right;
}

#nav > ul > li {
display:inline-block;
list-style:none;
    vertical-align:top;
}

#nav > ul > li > ul{
display:none;
    position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="nav">
<ul>
<li>
Item 1
</li>
<li>
Item 2
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
<li>
Item 3
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
<li>
Item 4
<ul>
<li>Sub Item 1</li>
</ul>
</li>
</ul>
</div>

Answer №3

To address this issue, utilize the position:absolute property as Doug suggested:

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

Here is an example:

var auth_width = $("#nav > ul:nth-child(3) > li:nth-child(2)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(2)").css("width", auth_width);
var cart_width = $("#nav > ul:nth-child(3) > li:nth-child(3)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(3)").css("width", cart_width);
var country_width = $("#nav > ul:nth-child(3) > li:nth-child(4)").outerWidth();
$("#nav > ul:nth-child(3) > li:nth-child(4)").css("width", country_width);

$("#nav > ul > li").unbind("mouseover").bind("mouseover", function(){
$(this).find("ul").fadeIn();
});
$("#nav > ul > li").unbind("mouseout").bind("mouseout", function(){
$(this).find("ul").fadeOut();
});
#nav{
float:right;
}

#nav > ul > li {
display:inline-block;
list-style:none;
    vertical-align:top;
}

#nav > ul > li > ul{
display:none;  
    position:absolute;
     width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="nav">
<ul>
<li>
Item 1
</li>
<li>
Item 2
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
<li>
Item 3
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
</ul>
</li>
<li>
Item 4
<ul>
<li>Sub Item 1</li>
</ul>
</li>
</ul>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Seamless flow from one image to the next

I'm working on a project with a slideshow, but I've noticed that when it transitions between images, it can be quite abrupt. I'd like to find a way for it to change smoothly from one image to the next. <div> <img class="mySli ...

Guide on transforming Color to HTML color with .NET Standard 2.0

How can I convert a color to HTML color in .NET Standard 2.0? Thank you. Is there a way to achieve the same functionality in .NET Core? System.Drawing.ColorTranslator.ToHtml(color); Or is this only available in DotNet Framework? ...

Error: An unexpected character was found in the Gulpfile.js

Having an issue in my Gulpfile.js: gulp.task('webpack', gulp.series(async () => { const option = yargs.argv.release ? "-p" : "-d"; execSync(`node_modules/webpack-cli/bin/cli.js ${option}`, { stdio: [null, process.stdout, proce ...

Using $window.print() in angularjs results in the print preview displaying an empty page

Encountering a strange issue where using $window.print in angularjs results in only the date, page name, page number, and url appearing on the printed page. The rest of the content is missing even though the original page has plenty of it. I suspect the p ...

A Fresh Approach for Generating Unique UUIDs without Bitwise Operators

To generate UUIDs in TypeScript, I have implemented a method inspired by the solution provided on Stack Overflow. The code effectively converts JavaScript to TypeScript. generateUUID(): string { let date = new Date().getTime(); if (window.performa ...

Using React PropTypes with Auth0

How can Auth0 be integrated with React PropTypes? index.js import App from '../components/App'; import WelcomeRoute from './Welcome'; import SettingsRoute from './Settings'; import CampaignRoute from './Campaign'; ...

Can you show me a method to integrate this HTML and CSS code into a Teachable page successfully?

Hey there, I've been encountering some challenges while working with HTML and CSS on a platform known as Teachable. Essentially, I'm aiming to create a layout with 2 columns: - Column 1 - Image - Column 2 - Text Whenever I apply <div class=" ...

I am encountering difficulties with generating images on canvas within an Angular environment

I am trying to crop a part of a video that is being played after the user clicks on it. However, I am encountering the following error: ERROR DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may no ...

Is the session timeout reset with every new request?

Is the session timeout reset on every request even if we do not check session variables? Should we always use at least one session variable to maintain the session? Do Ajax requests, such as Update Panel, jQuery ajax, etc., cause the session timeout to re ...

ng-if not working properly upon scope destruction

While working on a isolate scope directive, I encountered an issue. In the link function of this directive, I am compiling an HTML template and then appending it to the body of the document. const template = `<div ng-if="vm.open"></div>`; body ...

Observing data within an AngularJS service

I am currently working with a service called sharedData and a controller named HostController. My goal is to have the HostController monitor the saveDataObj variable within the sharedData service, and then update the value of host.dataOut, which will be re ...

Display the option to "Delete" the link only when there are multiple images in my image collection

I am using jQuery and Ajax to remove banner images from my website. However, I want to make sure that if there is only one image left, it cannot be deleted. Each image in the list has a corresponding delete link: echo '<a class="delete j_bannerd ...

Ways to ensure certain code is executed every time a promise is resolved in Angular.js

Within my Angular.js application, I am executing an asynchronous operation. To ensure a smooth user experience, I cover the application with a modal div before initiating the operation. Once the operation is complete, regardless of its outcome, I need to r ...

Is there a way to design a mosaic-style image gallery featuring images of varying sizes in a random and dynamic layout, all without relying

In my quest to create a unique mosaic-style image gallery, I have scoured the internet for suggestions and have come across numerous recommendations for using available plugins. However, I am curious if there is a way for me to personally create a mosaic ...

What are the best methods for looping through ids in MongoDB and executing actions on them?

I am working with an entity object that has the following response: [ { "public": false, "_id": "5eb6da3635b1e83", "createdAt": "2020-05-09T16:28:38.493Z", "updatedA ...

Put the browser into offline mode using JavaScript

Currently, I am utilizing selenium for application testing purposes. Although I typically start my browser in the usual manner, there comes a point where I must transition to offline mode. I have come across various sources indicating that switching to off ...

Ways to incorporate a dynamic value into a chart created with chart.js?

I want to create a doughnut chart representing the number of individuals who have tested positive for Coronavirus and the number of deaths related to it. How can I transfer the same data from the top container into the chart? The confirmedCases and deaths ...

Issue with Jade not displaying external JSON data

I am struggling with a jade template that is supposed to display all possible solutions from the QPX Express search request: { kind: 'qpxExpress#tripsSearch', trips: { kind: 'qpxexpress#tripOptions', requestId: 'RwDOf6H ...

Stylish Bootstrap sidebar featuring a vibrant background hue

I am facing an issue with my bootstrap layout where I have two columns - one on the LEFT and one on the RIGHT. The left column should be 8 units wide using the Bootstrap's 12 column grid format, while the right column should be 4 units wide as shown b ...

Steps to avoid TypeError: e.target.getAttribute is not a function

My goal is to make the inner code (result) function only when a Validity attribute is present. However, my target lacks said attribute, so I'm looking for a way to use an if statement to prevent the inner code from executing. How can I avoid the Type ...