For a fluid Navigation Menu, how to adjust padding dynamically for each Breadcrumb?
Asked Answered
U

2

2

I am currently building a site with a fluid layout. None of the mainstream fluid templates out there actually come with a stock horizontal navigation that can adjust itself as the window is resized or loads at different widths.

I've been pouring through online tutorials and other Stack Overflow solutions that try to tackle similar problems, some are extremely clever and come really close but none are able to handle a block-like hover effect a {display:block; padding:10px 40px;} a:hover {background:#ccc;}. Others use clever ways of creating block links that are identical widths that adjust with the window widht; however, this is not precise enough and I am not looking to create identical widths among the link blocks but to have identical left/right padding between links. This is much more precise as the distance between links is identical.

I've given up on doing this with CSS, maybe someone else has a solution for handling a variable padding, or something that acts very close to that. In any case, I decide to try to work on it in jQuery.

I have never actually written any jQuery before but have worked with several plugins for years. I thought I should at least try to come up with something before posting. I have it working, I am wondering is it possible to add the ability for it to adjust on the fly if the user resizes the window, not just on page load. I am also wondering if there is anything wrong with they way I have done it.

Here is a link to where I've gotten to: http://jsfiddle.net/XZxMc/3/

The HTML:

<div class="container">
    <div class="row">                        
        <div class="twelvecol">
            <ul>
                <li><a href="#">short</a></li>
                <li><a href="#">longer</a></li>
                <li><a href="#">even-longer</a></li>
                <li><a href="#">really-really-long</a></li>
                <li><a href="#">tiny</a></li>  
            </ul>               
        </div>
    </div>
</div>

The CSS:

.container {
    background:#ccc; 
    font-family:arial, helvetica;
}

.row {
    width: 100%;
    max-width: 700px; 
    min-width: 600px; 
    margin: 0 auto;
    overflow: hidden;
    background:white;
}

.row .twelvecol {
    width:100%; 
    float:left;
}

ul {
    text-align:center;
}

ul li {
    display:inline-block;     
    zoom:1; 
    *display: inline;
}

ul li a {
    padding:12px 39px;
    display:block;
}

a {text-decoration:none;}
a:hover {background:blue; color:white;}

​​The JavaScript:

// Initial left/right padding of links set in css
var paddingIni = 39;
// Initial max-width of .row
var widthIni = 700; 
// Number of links multiplied by 2; 2 because we will be reducing the padding by multiples of 2px total, 1px left, 1px right
var linkQ = 5*2; 

// Current width of link container
var twelveWidth = $(".row .twelvecol").width(); 
// (Initial width / 10) - (Current width / 10); this gives us how much to subtract from our inital padding of 39
// Is there anything wrong with the way this is written?
var paddingSub = (widthIni/linkQ)-(twelveWidth/linkQ); 
// Simply subtracting above computation from our inital padding of 39
var paddingNew = paddingIni-paddingSub;

$("ul li a").css("padding-left",paddingNew);
$("ul li a").css("padding-right",paddingNew);

Also, if someone wouldn't mind explaining why this doesn't work, it's my attempt to do it all in one equation:

var whyisthiswrong = 39 - ( (700/(5*2)) / ($(".row .twelvecol").width()/(5*2)) );
Universally answered 16/7, 2012 at 23:37 Comment(3)
@arttronics very true, I also wonder how changing paddings will make this appear as anticipated on all screens. Change font-size perhaps or just kill the 100% width idea and go for a grid system.Waggon
deflime, You may be interested in the last jsFiddle in my Answer based on the tutorial version that allows for fluid Navigation Bar width-size, including auto-centering in the viewport, and all with equal auto-padding on the sides of the link buttons. Cheers!Anticlinal
defime, did I understand your point correctly this time around?Anticlinal
W
1

On the HTML part, if you plan to only have one horizontal navigation I would make sure it has an id. Also I don't think this is necessary:

<div class='twelvecol'><ul>...</ul></div> 

You can have the same by doing

<ul id='hmenu' class='twelvecol'>...</ul>

CSS wise you just make sure your unsorted list has a display block or inline-block (since it's horizontal and therefore inline). This way you can also get rid of the CSS hack on the list items if I'm correct.

According to this post auto resize text (font size) when resizing window? For the jQuery part to trigger the window resize use:

$(function() {
    // trigger once dom is ready
    resizeMe();
    // trigger on window resize
    $(window).bind('resize', function()
    {
        // your resize function
        resizeMe();
    }).trigger('resize');
});

var resizeMe = function(){
    // your stuff here
};

You can adjust CSS in one time with a JSON param string or when it's only just padding:

$("#hmenu li a").css("padding", "12px " + paddingNew + "px 12px " + paddingNew + "px");

or

$("#hmenu li a").css({"padding-left": paddingNew, "padding-right": paddingNew});

Not to sure on the px concatenation. It may not be necessary.

Added jsfiddle, you can play with the "result window" sizes to see what happens: http://jsfiddle.net/tive/tKDjg/

Waggon answered 17/7, 2012 at 0:26 Comment(1)
Thanks for taking a look, I will give the function a try shortly. Regarding my HTML markup, it was just for the example, and it included some of the required elements from the fluid template I am using, Andy Taylor's 1140px CSSGrid, so it doesn't paint a complete picture. And thanks for combining my last two jQuery lines into one.Universally
A
1

Reference: jsFiddle

I've edited your jsFiddle with comments provided on added/removed items to allow your fluid Navigation menu to work correctly.

Notably, I used white-space: nowrap; on .container, removed min/max width on .row, and used jQuery .resize(); listener to handle on-the-fly updates to the Navigation Bar.



REVISED: Status Update:    jsFiddle Newer Method (Tutorial)

I've approached your objective from a different angle. Instead of working with what you don't want (the boxed breadcrumbs), I've tackled the padding allocation head-on (from the outside in).

Note: Breadcrumb Buttons are demonstrated.

Here's the process I used:
1. Create HTML layout that has all breadcrumbs on a single row. No padding, no margin, just raw links.
2. Next, measure the left-over space in pixels. This will be the total padding available.
3. In the HTML Navigation markup, dynamically count the number of padding spans used.
4. The total padding available is divided by the padding spans. This becomes the Shared Portion.
5. The Shared Portion from total padding available is set on page load & window resize event.

This method is simple to understand once you see the code and allows for easy changes or custom adjustments without much fuss. Extended notes included. Tested in Chrome, Firefox, IE8 with no issues.


The jQuery Highly Optimized Version:

function fluidNavBar(){
    $('.breadcrumbPadding').css('width',0);
    if($('.links').width() < $('body').width()){
        $('.breadcrumbPadding').css('width', $('.navPaddingTotal').width() / $('.breadcrumbPadding').size());
    }
}

// RUN ON PAGE LOAD
window.onload = function() {
    $('.navBar').css('min-width', $('.links').width());
    fluidNavBar();
};

// RUN ON WINDOW RESIZE
$(window).resize(function() {
    fluidNavBar();
});


In the updated jsFiddle, you will see the previous Navigation Bar which is now pinned to the bottom for comparison.

Pick your flavor:
jQuery original tutorial
jQuery without comments
jQuery code highly optimized
jQuery original tutorial + Style

jQuery this it the one you really want Demo
jQuery this it the one you really really want Demo (because it's sizeable and auto-centers)

Anticlinal answered 17/7, 2012 at 4:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.