• 0

[JS] Center a menu that is floated left.


Question

I found the following snippet of javascript (uses jQuery) that would allow me to centre a menu/nav that is set to float:left. It seems to work in IE and Opera OK. But in FF and Safari, it works sometimes and other times trips out (keep refreshing the page and it will eventually work/fail). In Chrome it doesn't work at all.

Here is the code:

$(function() {
	var menu_width = $('#nav').css('float', 'left').width();
	$('#nav').css({float : 'none', width : menu_width, margin : '0 auto'});
});

I don't know js so I can't figure out what the problem is. If anyone can help it would be much appreciated.

Here is the page running the code:

http://www.islandrobot.com/vanessa/

Cheers,

Jordan

15 answers to this question

Recommended Posts

  • 0

Sorry, yes I am trying to centre the entire navigation on that blue strip. Without the js it would be aligned to the left. With the js it should be centred.

P.s. I made an edit to my above post and then deleted it. If you saw the edit, just ignore it ;)

  • 0

That would be the easy way out, yes. But I would rather have it centre automatically since the client may add/remove/rename items from the menu at any time which would mean manually recalculating and changing the width. Since they don't know CSS I wouldn't expect them to have to do that.

  • 0

It wasn't the easy way out when I looked over your code but rather the logical solution to your problem based only on your initial post (which didn't say that the menu would actually be dynamic versus static.)

That being said the best bet is to replace float: left for display:inline. Then you can have all list items centered under the unordered list without needing any javascript.

  • 0

That being said the best bet is to replace float: left for display:inline. Then you can have all list items centered under the unordered list without needing any javascript.

I tried this method at first but encountered problems with the drop down menus. I couldn't get them to fall directly under their parent li. Instead, the drop-downs always appeared in the far left corner (beginning of the root ul) regardless of which li you were mousing over (if that makes any sense). I played around with it for a while but couldn't get it to behave the way I wanted.

I also tried using inline-blocks which worked nicely except in FF2 which doesn't support it. -moz-inline-box didn't help either because of the drop-down menus.

JS seems like my last and only resort to have a centred, horizontal menu of unknown width and with drop down menus.

  • 0

Hi sweetsam. That seems to have helped a little bit. It at least works in Chrome now sometimes where as it didn't work at all before. However, it is still failing on some page loads. If you keep refreshing the page in FF/Chrome/Safari (Opera and IE seem stable) it will eventually get screwed up. Is this a common problem with javascript? Could it be a jQuery issue?

  • 0

An update:

I've almost got it pegged now. Previously I did not have float:left; applied to #nav (which is the ul). I only had it applied to the li's. As I understood it, the .css('float', 'left') part of the script was trying to add the float to #nav for me??? Well I took that part out and just added float:left; to #nav in the css. This made #nav wrap snug around the li's and allowed for the correct width to be determined. Now everything seems stable in FF.

EDIT: FF is still giving the same problem as Chrome and Safari

Chrome and Safari still seem to be having slight problems getting it perfectly centred though. Sometimes its a bit more to the left and other times it's perfect.

I have also simplified the script down to this:

$(function() {
        var mleft = Math.round(($('#nav-wrap').width() - $('#nav').width()) * 0.5);
        $('#nav').css('margin-left', mleft);
});

  • 0

Ok I am pretty sure now that the problem is a simple matter of the calculations being made before the navigation part of the page has been drawn up (if that makes sense). I realize this as some testing showed that occasionally $('#nav-wrap').width() and $('#nav').width() were returning results like 1407 and 1367 respectively. This would also explain why the browsers with faster javascript engines are having the problem more frequently. How can I make sure that the calculations are only made AFTER the html/css has been drawn up by the browser?

Sorry for all these posts, as I said in the beginning I don't know much about js so figuring this out is a whole learning experience :/

EDIT: HOT DAMN.... I guess it was as simple as moving my stylesheet above the javascript. All good now :)

  • 0

To avoid this kind of problem though you should have done this :


$(document).ready(function() {
$(function() {
 var mleft = Math.round(($('#nav-wrap').width() - $('#nav').width()) * 0.5);
 $('#nav').css('margin-left', mleft);
});});

It ensures any jquery is applied after the dom has been fully parsed, most of the time the effect is instant.

  • 0

I was actually reading up on the .ready() function when I discovered that I could just move the css above the js.

To quote the .ready() page of the jQuery site that tipped me off:

When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.

Is it still advisable that I also use the .ready any ways?

  • 0

Yes. But you were using it already. Following pieces of code are equivalent. The problem was being caused by the fact that the styles were being applied after the script swung in to action. Scripts should always be the last to run and more importantly should be included after the stylesheets. Sometimes you will see scripts attached to the end of the document for the same reason.


$(function(){

})

and

$(document).ready(function(){

})

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Each of the devices displayed on this page now has a little volume meter next to it to show if there is audio actively playing. About time.
    • Owing to the nature of Windows feature enablement updates, it was distributed over Windows Update services as a complete system upgrade rather than as an ordinary cumulative update
    • Microsoft confirms Windows 11 26H2, urges IT admins to prepare for release by Usama Jawad Windows 11 typically follows an annual update cycle, but Microsoft recently broke that tradition a bit by releasing a "26H1" version in the first half of this year as a "scoped" build for select new silicon PCs only. This version was not available for customers using 24H2 and 25H2 builds, as Microsoft is busy preparing version 26H2 for them, confirmed officially for the first time. In a Windows IT Pro blog, Microsoft has urged IT admins to prepare for the upcoming release of Windows 11 version 26H2. The company has confirmed that this will be a small enablement package (eKB) that will simply light up certain disabled features that are already present in the operating system's code base. This means that the "refined" Windows update and deployment experience will be simpler and quicker, with minimal disruptions, as the feature update will simply toggle a few flags rather than performing a complete replacement. Microsoft has explained that this is all possible because the standard Windows 11 releases share the same servicing branch and hence, the same source code. However, this also means that Windows 11 26H1 users won't be able to upgrade to 26H2 as that is a different branch, but this is something we have known for a while now. Similar to previous annual feature updates, Windows 11 26H2 will offer the following support cycles: 24 months of support for Home, Pro, Pro EDU, and Pro for Workstations editions 36 months of support for Enterprise, Education, IoT Enterprise, and Enterprise Multi-session editions Microsoft has not confirmed a concrete release date for Windows 11 26H2, but noted that it is "coming soon". If we go by the ongoing release cadence, we can expect it to begin rolling out in early October 2026. As such, IT admins have been encouraged to begin validating Windows Insider releases in the Experimental Channel, plan rollout rings, and strategize the utilization of their existing deployment tools.
    • Windows 11 gets new audio improvements in the latest builds by Taras Buria Today's Experimental builds (26H1 and Future Platforms, formerly Canary) pack several audio-related improvements. If your device is enrolled in the Experimental Channel (26H1), you can download build 28120.2315, while those in the Future Platforms version have build 29613.1000 to try. Here is what is new in build 29613.1000: [Audio] Following up on our previous improvements, we’re making some more adjustments to Settings > System > Sounds based on your feedback. Namely, we’ve updated the “All sound devices” page so: You now have the ability to change default devices from this page. Each of the devices displayed on this page now has a little volume meter next to it to show if there is audio actively playing. We’ve adjusted the page design slightly so now you can filter whether you’re viewing input or output devices. We’ve added toggles so you can choose if you want to hide or show disabled, disconnected, and unplugged devices on this page. We’ve also updated the input and output audio properties page for devices in Settings to now include jack information for those that need it. And here is the changelog for build 28120.2315: This update includes a small number of minor bug fixes and improvements. [Accessibility] This update improves caption style responsiveness by redrawing captions immediately for caption style changes. If no current caption is visible, a sample caption string is displayed. [Audio] This update improves the reliability of the inbox HD Audio driver. You can find the official release notes for build 28120.2315 here and for build 29613.1000 here.
  • Recent Achievements

    • Collaborator
      ryansurfer98 went up a rank
      Collaborator
    • Week One Done
      Eurosoft10 earned a badge
      Week One Done
    • One Month Later
      Eurosoft10 earned a badge
      One Month Later
    • One Year In
      Skeet Campbell earned a badge
      One Year In
    • One Month Later
      Sharbel earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      576
    2. 2
      +Edouard
      189
    3. 3
      Michael Scrip
      79
    4. 4
      PsYcHoKiLLa
      78
    5. 5
      neufuse
      72
  • Tell a friend

    Love Neowin? Tell a friend!