• 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

    • I’m still using an Xbox One S, so time for an upgrade to play this but as much as I hate Sony, I think I’ll get the ps5 pro
    • I bought this game. Played it for an hour, and then got a refund from Steam. Not a fun game at all.
    • Nothing Ear buds with active noise cancellation are at their lowest price ever with 51% off by Fiza Ali Amazon is currently offering the Nothing Ear wireless earbuds at their lowest price ever with 51% off limited prime deal. The earbuds feature an 11mm dynamic drivers with a ceramic diaphragm, and support high-resolution audio codecs including AAC, SBC, LDAC, and LHDC 5.0. They support active noise cancellation of up to 45dB across a frequency range of up to 5000Hz, and include a smart ANC algorithm, adaptive noise cancellation, and a transparency mode that allows surrounding sounds to be heard when needed. Connectivity is provided via Bluetooth 5.3, with support for multiple profiles including HFP, A2DP, AVRCP, and others. The earbuds also support dual connection, allowing them to be paired with two devices at the same time. Additional features include IP54 water and dust resistance for the earbuds and IP55 for the charging case, in-ear detection, pinch controls, low-latency mode, Google Fast Pair, Microsoft Swift Pair, and a three-microphone system per earbud for clearer voice calls. The Nothing X app, available on Android and iOS, provides access to custom EQ settings, bass enhancement, personal sound profiles, ear tip fit testing, firmware updates, customisable controls, dual-device management, and a find-my-earbuds feature. In terms of battery performance, each earbud has a 46mAh battery and the charging case has a 500mAh capacity. With active noise cancellation (ANC) turned off, the earbuds should offer up to 8.5 hours of playback on a single charge and up to 40.5 hours in total with the charging case. With ANC enabled, playback should last up to 5.2 hours on the earbuds and up to 24 hours with the case. For calls, talk time should reach up to 5 hours on the earbuds and 23 hours with the case when ANC is off, while ANC on should provide up to 4 hours on the earbuds and 18 hours with the case. Finally, fast charging should deliver up to 10 hours of playback from 10 minutes of charging when ANC is disabled. Nothing Ear Wireless Earbuds Bluetooth: $73.15 (Amazon US) - 51% off Good to know This Amazon deal is U.S. specific, and not available in other regions unless specified. We only use first-party seller links (at the time of article publishing); ensure that you purchase from a first-party seller link only. Check out Today's Deals on Amazon | or our recent tech deals. Become a Prime member (for Students or SNAP) via Neowin Get Prime Access - Prime for half price (for qualifying Medicaid, EBT, SNAP) Subscribe to Prime Video, Audible Plus, Music Unlimited or Kindle Unlimited via Neowin As an Amazon Associate, we earn from qualifying purchases.
    • Microsoft officially launched its Copilot Cowork enterprise AI agent on June 16, 2026, switching to usage-based pricing on the same day it disclosed it is considering a Microsoft-hosted version of China's DeepSeek V4 as a lower-cost engine for the platform — a pairing that puts the company on a collision course with both its enterprise customers' security teams and a White House that has spent months trying to wall off Chinese AI from American infrastructure.................... https://www.techtimes.com/articles/318647/20260618/microsoft-eyes-deepseek-v4-copilot-cowork-what-azure-hosting-cannot-fix.htm  
  • Recent Achievements

    • First Post
      AndreaB earned a badge
      First Post
    • Week One Done
      Huge Trailer earned a badge
      Week One Done
    • Week One Done
      Classifyskilleducation earned a badge
      Week One Done
    • One Month Later
      eurospharma62 earned a badge
      One Month Later
    • Week One Done
      With What earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      592
    2. 2
      +Edouard
      171
    3. 3
      PsYcHoKiLLa
      76
    4. 4
      Michael Scrip
      68
    5. 5
      neufuse
      64
  • Tell a friend

    Love Neowin? Tell a friend!