Imagine building a house with no doors or windows. As soon as you place the final brick, you realize that you were standing on the inside. Oh yes, that sensation of knowing you just built something very complex, but at the same time it has blocked you into a corner, where the only way to continue is to think outside the box – pun intended.

I know this might seem like an obscure thing to write about, but the other day I found myself in that sort of predicament. Fortunately, I did find a solution. It involves a bit of jQuery and some basic math.

I had developed a menu with several levels that was centered in a relative container. The design called for the first two levels to fit into a container, and the third to span 100% of the viewport. Due to the relative positioning of sub elements, CSS alone wasn’t going to work, so I worked out a simple jQuery script to handle that third level’s tray. The whole process looks a bit like this:

First I built out the menu structure:


Next came the general design:



After that, things got a bit tricky. I realized that I couldn’t span the third level to 100% since it was relatively positioned to a smaller parent element. My first thought was to create an illusion with CSS.

.tray {
    position: relative;
    width: 200%;
    margin-left: -50%;
    z-index: -1;


The results weren’t perfect:


The “tray” was placed just before the third dropdown block (header ul ul ul .tray).  The z-index dropped it behind everything in that submenu. The margin and width created the illusion of full width.

Unfortunately, this allowed the entire website to side scroll. I didn’t have much success with overflow properties, so I turned my attention towards jQuery.

First, I needed to strip out any margin and width styles from the tray class. Then I added a 100% height to it and its parent container. That way, regardless of the content height it always stretched to fill the space. The width on the other hand, needed to be handled with my jQuery solution. This bit of code sets it to the width of the browser viewport:

$('.tray').css('width', window.innerWidth);


Next came some simple math to get the overall width of the gaps on either side of the site container. To do that I subtracted the viewport width from the container:

var width = window.innerWidth - $('.container').innerWidth();


If you hadn’t guessed, I planned to use this value as a negative margin. I took the width variable, divided it by two, and placed that into a new variable called marginLeft:

var marginLeft = width / 2;


And now for the magic– I simply subtracted this variable from the margin-left property of the tray element:

$('.tray').css('margin-left', -marginLeft);


There’s still a bit of an issue with this script though. As is, it will run once and be whatever width it started with regardless of changes in window size. I certainly don’t expect viewers to refresh every time they want the menu to span 100% so I wrapped that code in a bit of script that listens for a window resize event:

$(window).on("resize", function () { CODE GOES HERE }).resize();


After all of that I ended up with this:


If you’re dealing with a dynamically generated menu and don’t want to edit a function, you can append a tray div to the third level menu with this script:

$('header ul ul ul').prepend('<div class=“tray”></div>');


Here’s the whole thing:

$(window).on("resize", function () {
    $('.tray').css('width', window.innerWidth);
    var width = window.innerWidth - $('.container').innerWidth();
    var marginLeft = width / 2;
    $('.tray').css('margin-left', -marginLeft);


To see the menu in action, check out my fiddle.

That ought to cover it. Pretty easy, right?