Video Player 4 introduces interactive playlists, social sharing and more

video player 4 hero shotI’ve been busy hardening and improving my video player lately and had so many updates for it I decided to upload it to activeden as a new file altogether. After some final bug fixes and testing it’s been approved for sale. I think it’s a huge improvement over the last video player. The video playing part is mainly the same (with a few small adjustments for better usability), but I’ve added tons to this update. It’s online at activeden for live preview and purchase.

An extensively customizable yet simple video player. Create and manage play lists for you video delivery as well as allow viewers to share and socially bookmark the video. Integrate the video into your user experience with javascript integration as well as Google Analytics tracking on the video interaction! Control functionality, layout and colors of the player easily! Plus don’t sweat the embed codes – an embed code generator included!

Check out the legend graphic for some views of the player and the different panes. There is the full video view, the playlist, share and detail panes. You can also view them all in fullscreen mode.

circlecube video player 4 legend

This new player has the following updates:

  • Includes an embed script generator built specifically for this video player! Embed script generator with a Live Preview!
  • Use an external xml playlist or set playlist values in flashvars settings. (No need for xml if you don’t want it)
  • Social Bookmarking with facebook, twitter, delicious, google buzz & linkedin
  • Send emails through the player to share the video with friends
  • Google Analytics Integration (event tracking) – Uses your analytics account on a per video setting in flashvars.
  • All colors fully customizable in flashvars or xml
  • Display video title and description – html content (may contain links) in the detail pane.
  • Video controls also in context menu (right-click menu)
  • Loop the video once, twice however many times you wish and even infinitely!
  • Disable tooltips completely if you wish
  • Keyboard shortcut integration! Press the space bar to pause/play the video just like in most video playback programs.
  • Volume setting cached across sessions for a better user experience
  • Double click video for fullscreen

As well as all that made version 3 video player great as well:

  • Supports flv, f4v and any container format using H.264: mp4, m4a, mov, mp4v, 3GP, 3G2.
  • All images and video loaded externally
  • Run this player without additional files, just pass in the flv path.
  • Supports most image file types: jpg, gif, png.
  • Google Analytics Integration (event tracking) – Uses your analytics account on a per video setting in flashvars.
  • Load any dimension video. Completely resizable
  • Set player width and height
  • Set video width and height
  • Full screen capabilities
  • All colors fully customizable
  • Use a preview/thumbnail image.
  • Auto play option
  • Auto load option – in case you had a bunch of video on one page you wouldn’t want them all to auto load.
  • Video scale/stretching options: none, exact, uniform, fill.
  • Javascript callback functions for loading video and finishing video playback.
  • Show/hide a big play button over the video option
  • Show/hide “vcr” video player controls or have them auto-hide
  • Advanced volume controls, click to mute or drag to desired volume. Volume fades rather than cuts.
  • Support for a logo
  • Controls auto-hide
  • Time code display in current time or elapsed time. click to toggle
  • Tooltips for controls
  • Send video files to player dynamically with javascript integration (with an html link on a page send a video to play)
  • Replay video after complete
  • Progressive play and load displays. Watch as the video loads and see the scrub bar update as you watch.
  • Scrub bar is interactive click and drag. Tooltip to display hovered time.
  • Animated play controls.
  • Buttons states & tooltips.
  • All player graphics are vector shapes and very small in size.
  • Fully rearrange player controls
  • Option to disable fullscreen
  • Display video title and description – html content (may contain links)

Here’s a screenshot of the embed code generator:

embed generator preview

Actionscript (as3) Javascript Communication | Call Flash to and from javascript

Often we need to have different parts of a website talk to each other. This can get tricky when we are using multiple technologies and need the communication in real-time. Going from flash to html is done through javascript on the browser side and in actionscript we use something called ExternalInterface. The ExternalInterface class is an application programming interface that enables straightforward communication between ActionScript and the SWF container– for example, an HTML page with JavaScript or a desktop application that uses Flash Player to display a SWF file. We can send things form actionscript to javascript as well as from the html and javascript into flash and actionscript.

I’ve written about this before. It got old though and I had reports that it was having issues in certain browsers, so I had a minute to look at it and decided it needed a rebuild. This version uses as3 and swfobject. I was tempted to throw jQuery in there as well, but didn’t want to confuse anyone. This is simple javascript. I did have to throw some css3 on it for style though. I did use swfobject because it makes life easier, but it’s not required.

So, just like in as2, communication between actionscript and javascript still requires our friend ExternalInterface to link them but the setup/syntax changed a bit with as3. From the docs here are a few pointers of what we can accomplish with External Interface:

From ActionScript, you can do the following on the HTML page:

  • Call any JavaScript function.
  • Pass any number of arguments, with any names.
  • Pass various data types (Boolean, Number, String, and so on).
  • Receive a return value from the JavaScript function.

From JavaScript on the HTML page, you can:

  • Call an ActionScript function.
  • Pass arguments using standard function call notation.
  • Return a value to the JavaScript function.

It’s really cool that we can pass various data types. Here I’ve got an example that simply sends a string back and forth. We have the actionscript to javascript lane as well as the javascript to actionscript lane. So to set it up we need to know the names of our functions. Here I’ve tried to name them exactly what they are. There is a function in my javascript to both send and receive text to actionscript. Also, there are corresponding functions in my actionscript code: one to send and one to receive. These functions pass the data back and forth.

The magic is set up with the call and addCallback methods of ExternalInterface.

To call a javascript function from actionscript we use the call method. The first argument is the name of the javascript function as a String and any following (optional) arguments are the parameters that are passed to said function. So we need a function in the javascript on that page which is set up to accept some data or at least set up to do something (we don’t actually have to pass data, it could be just a trigger for something on the page). Then in our actionscript we call:
ExternalInterface.call("name_of_js_function", "data passed to js");

Then to go back from javascript to actionscript there is a little bit more set-up involved. We will use the addCallback method here and this sets the actionscript function to be able to accept a call from javascript. The first argument is the function name in javascript (again as a String), and the second argument is the function name in actionscript that you want to be called:
ExternalInterface.addCallback("name_of_js_function", name_of_as3_function);
Then you write your actionscript function to do what you want:
function name_of_as3_function():String {
//do something
return something;
}

Demo

View the actionscrip javascript communication DEMO
If that doesn’t make sense try the demo to see it in action. I’ve got the source code listed on the demo page as well as the working example.

Source Code

JavaScript

[cc lang=”javascript”]
function receiveTextFromAS3(Txt) {
document.getElementById(‘htmlText’).value = Txt;
}
function sendTextToAS3(){
var Txt = document.getElementById(‘htmlText’).value;
var flash = document.getElementById(“as3_js”);
flash.sendTextFromJS(Txt);
document.getElementById(‘htmlText’).value = “”;
}

var flashvars = {};
var params = {};
var attributes = {};
attributes.id = “as3_js”;
//attributes.name = “as3_js”;
swfobject.embedSWF(“AS3_Javascript.swf”, “alt”, “450”, “450”, “9.0.0”, false, flashvars, params, attributes);
[/cc]

HTML

[cc lang=”html”]

[/cc]

Actionscript – AS3

[cc lang=”actionscript”]
import flash.external.ExternalInterface;

//Set up Javascript to Actioscript
ExternalInterface.addCallback(“sendTextFromJS”, receiveTextFromJS);
function receiveTextFromJS(t:String):void {
theText.text = t;
}

//Actionscript to Javascript
function sendTextFromAS3(e:MouseEvent):void {
ExternalInterface.call(“receiveTextFromAS3”, theText.text);
theText.text = “”;
}
button.addEventListener(MouseEvent.CLICK, sendTextFromAS3);
button.buttonMode = true;
[/cc]

Source Files

Download the source files here:
FLA, HTML, SWF, ZIP.

Style vs Design

So what’s the difference between design and style?

I’ve had to explain that to quite a few clients that think all they need is a good looking website and they will make millions. It has to work and the design has to (subconsciously) show users how it works and it’s a perk if it looks good (style).

I’ve been thinking about this a lot and about what a web designer should focus on. Is it all about functionality of a site and making everything “work” or is it all about making it look “pretty” and fresh. Facetious I know, obviously it sits happily in between the two somewhere. But where is the question. I love reading articles and stumbled on this (apparently 2005) gem for the first time recently: Jeffrey Zeldman’s Style vs Design. Don’t ask me how I haven’t come across it before, but it’s awesome and it hit the nail on the head for me so I thought I’d share.

dilbert usability comic

Web designers need to not only make a site work, but make it appealing to the intended audience. What looks good on a website for one audience won’t necessarily apply to another.

The web used to look like a phone book. Now much of it looks like a design portfolio. In fact, it looks like the design portfolio of 20 well-known designers, whose style gets copied again and again by young designers who consider themselves disciples.

I worry because young designers who confuse style with design are learning to copy their heroes’ technical tricks and stylistic flourishes, but not necessarily learning to communicate in this medium.

It is cool to make a new effects and transitions with css3 and the like, but let’s not add these styles to a design that doesn’t call for them. We should ask each client/project what their needs and audience is and work on solving that problem aesthetically for that situation.

More to read:

circlecube Relaunch

Not just a redesign but a whole new site and location! After having built loads of sites for clients/friends I kept learning things I wanted to employ on my own site, but the cobblers kids are always barefoot right? I kept implementing new things and knew that they were making my clients lives easier and I wanted it easier as well.

circlecube logo
I’d already updated my logo a number of times since my last redesign and I wasn’t happy with how my collection of sites all looked different and required repetitive work to maintain. circlecube-sketch-3Well, I did some sketches and committed to working on it just a few minutes a day. I really work best as I visually think through a design so sketching is always the first step in my designs. After I nailed down the basic elements and concepts I needed in the site through sketches I installed a new wordpress site, the thematic framework and then got started on a child theme. I really surprised myself and in a mere couple weeks I had a short list of things to do before I could “flip the switch”. The hardest part by far was trying to do 301 redirects from all the old posts which lived on either my blog or portfolio sub-domains. But thanks to my friend we were able to iron that out and I learned more than I ever wanted to know about mod rewrites and such. I was able to combine my blog and portfolio and my home page all into one site. I always felt weird pushing friends/potential clients and everyone else to my blog or my landing page or portfolio… but now they can all simply go to the same place!

circlecube-sketch-1My goal was to enable all content to be updated in the back-end, I didn’t want any content in the theme. And I didn’t want to have to redo the css or layout to move something from the header to the footer or sidebar for example. I placed a lot of content in widgets and a few pages that were wholly widget areas. I also needed a portfolio section that displayed a little gallery of images and possibly flash content automatically. It needed to be easy if I were going to ever update the portfolio, so I used custom post types and custom fields to attach images and other data to each portfolio item. Then one of my favorite pages is the social page, it’s just a collection of my social feeds all displayed neatly in one place.

While I’d love to release the theme for everyone, I cheated and used quite a few plug-ins to accomplish my designs so the theme itself doesn’t include all the functionality and I’m pretty sure it’s bad for to require plug-ins and set up to get a theme functional, but if you’re interested, let me know.

As usually happens though, I learned some more tricks as I built this site. So I have a list of things I’m ready to write and share about on the blog: custom post types, custom taxonomies, thematic customizations, css tricks, fancybox, custom fields, jquery, widgets, htaccess, importing/exporting wordpress, new favorite plug-ins and more… So be excited!

My only regret so far is the lack of texture on the site so I may come back and apply slight noise to the site background to make it more tangible. But I also like the clean look. Well, to see snapshots of the site I added the circlecube redesign to the portfolio section of this site (cheesy to include my own site in my portfolio? yep, but I’m excited to use the feature and I always retrospectively wish I’d documented site updates).

Still, there may be a few things that don’t fully connect, so please, please let me know if you see anything broken or experience a broken link. But stay tuned for some posts since I’m not spending time building the site I’ll put a little time each day into putting content on the site again.

Redworks

redworksI just realized that I hadn’t updated the site about it, but I’m now (since a couple months) interactive designer/developer with Redworks, subsidiary or Ogilvy & Mather in Atlanta! I’ll be doing all kinds of interactive designing and programming, specifically with flash and I’m stoked to be waist deep in Flash and as3 daily.

What? You ask is RedWorks? Well, I have been explaining it to so many that I figured I’d post this awesome video that explains it better than I ever could! Enjoy, this if from the RedWorks 3D office in NY.

Circelcube Video Player 3.0 Stock Flash Video Player at ActiveDen

hero-image

My latest stock flash video player of mine was just added to the database of stock flash items at activeDen. Go check it out and if you like it, download it for use in your projects! I’ve got lots in it for you. I’m using the principles I used as the architect for the video player for stomperNet and then at cornerstone media group in this decked out video player. Go get circlecube’s awesome stock flash video player.

circlecube-video-player-3-preview

An extensively customizable yet simple video player. Integrate the video into your user experience with javascript integration as well as Google Analytics tracking on the video interaction! Control functionality, layout and colors of the player easily! Plus don’t sweat the embed codes – an embed code generator included!

Let your video be the focus!

Features

  • Includes an embed script generator! With options for swfobject implementation or simple valid html object tags (or both)!
  • Embed generator makes setting your settings easy with a Live Preview!circlecube-video-embed-preview
  • Supports flv, f4v and any container format using H.264: mp4, m4a, mov, mp4v, 3GP, 3G2.
  • All images and video loaded externally
  • Run this player without additional files, just pass in the flv path and thumbnail path.
  • Supports most image file types: jpg, gif, png.
  • Google Analytics Integration (event tracking) – Uses on page analytics account or a specified account on a per video setting in flashvars.
    analytics-overview
  • Load any dimension video. Completely resizable
  • Set player width and height
  • Set video width and height
  • Full screen capabilities
  • All colors fully customizable in flashvars
  • Use a preview/thumbnail image.
  • Auto play option
  • Auto load option – in case you had a bunch of video on one page you wouldn’t want them all to auto load.
  • Supports Window Mode options. window, transparent, opaque
  • Video scale/stretching options: none, exact, uniform, fill.
  • Javascript callback functions for loading video and finishing video playback.
  • Show a big play button over the video
  • Show/hide “vcr” video player controls
  • Advanced volume controls, click to mute or drag to desired volume. Volume fades rather than cuts.
  • Support for a logo
  • Controls auto-hide
  • 60k file size
  • Time code display in current time or elapsed time. click to toggle
  • Tooltips for controls
  • Send video files to player dynamically (with an html link on a page send a video to play)
  • Replay video after complete
  • Progressive play and load displays. Watch as the video loads and see the scrub bar update as you watch.
  • Scrub bar is interactive click and drag. Tooltip to display hovered time.
  • Animated play controls.
  • Buttons states & tooltips.
  • All player graphics are vector shapes and very small in size.
  • Fully rearrange player controls
  • Option to disable fullscreen
  • Display video title and description – html content (may contain links)
  • Video controls also in context menu

legend-image

Javascript to show/hide elements update with jQuery

I never expected it, but one of the most popular (most commented) posts on this blog is a javascript post from about 3 years ago. I was showing how to hide and show elements on a web page with some simple javascript using getElementById and altering the display or visibility attributes of the element. It still works – although I hear every once in a while that certain browsers have issues with is sometimes, but the truth is I haven’t used this code almost since I wrote it. I have converted to jQuery! And it is much easier to code, easier to read and even nicer to browsers. So I’m writing this update post to proclaim the antiquity (3 years on the internet is a long time) of getElementById and the benefits of jQuery!

There isn’t much more to say about it really. I hope you’ve heard of jquery and if not, please go check it out it’s pretty easy to pick up! One thing I will mention is the potential bloat to having to load a javascript library. But most of my projects lately have included jQuery because I’ve been using it much more than just showing and hiding elements. But remember our friend cache? Remember that if you’re using jQuery on a whole site, the user only loads it once, and if you load it from the google hosted version of jQuery they likely will already have the script in their cache. The current version is hosted at http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js, so just link to that script on your page and you’re free to throw in any jquery onto your page.

Well, check out the code; I hope it’s pretty self explanatory and you can see it in action. I always have to see things work to understand them and learn from them.

Javascript

[cc lang=”javascript”]
$(document).ready(function() {

$(‘.hide_it’).click(function(){ $(‘.to_hide’).hide(); });

$(“.show_it”).click(function () { $(“.to_show”).show(“slow”); });

$(“#toggle_it”).click(function () { $(“.to_toggle”).toggle(); });

$(‘.fade_it’).click(function() { $(“.to_fade”).fadeTo(“slow”,0); });

$(‘.fade_out’).click(function() { $(“.to_fade_out”).fadeOut(); });

$(‘.reset_all’).click(function() {
$(‘.to_hide’).show();
$(“.to_show”).hide();
$(“.to_toggle”).show();
$(“.to_fade”).fadeTo(“slow”,100);
$(“.to_fade_out”).fadeIn();
});
});
[/cc]

show-hide-jquery-screenshot

HTML Code

see it in action on the demo page
[cc lang=”html”]

testing hide js div

hide it


Show me slowly.


testing the toggle functionality of jQuery


testing fade out. you’ll notice that this is set to display:none once the fade is complete.

fade out


testing fade to 0. this fades out just as fadeOut, but it does no make the display none, so the page layout isn’t modified, just the visibility of this element.

fade it


[/cc]

Notice that with jQuery we can use a class or an id as a selector. This is great because you can show a whole slew of elements that share the same class at once. Remember that you can only have one id on a page at once since it must be unique.

See the demo page for working examples.

And don’t forget to read up on the api for jQuery here jQuery hide, jQuery show, jQuery toggle, jQuery fadeOut, jQuery fadeIn, jQuery fadeTo.

Update a thematic child-theme for wordpress 3.0 menu


The new menu system in wordpress, while not perfect (yet), is a huge step in the right direction. I have had to update many old themes to support this feature, and as most of my theming is down with thematic, I finally got a standard block of code together to add to a functions.php file of a child theme to add theme support for menus and add them to the theme. Here is the code, all you do is add it to your functions file and then you can manage menus thorugh the new menu page in your pw dashboard! Enjoy!
[cc lang=”php”]
//// Add support for new menu in WP3
// declare that our theme supports wp_nav_menu()
add_theme_support( ‘menus’ );

// Register the a new menu for the theme called “Primary Menu”
function register_primary_menu() {
register_nav_menu( ‘primary-menu’, __( ‘Primary Menu’ ) );
}
add_action( ‘init’, ‘register_primary_menu’ );

// Remove the standard Thematic menu
function remove_menu() {
remove_action(‘thematic_header’,’thematic_access’,9);
}
add_action(‘init’, ‘remove_menu’);

// Create the new wp_nav_menu called “Primary Menu” in theme
function new_access() { ?>

Better jquery mega-menu tutorial

My earlier simple mega menu implementation post displayed some simple css and jquery to explode a standard navigation menu into a mega-menu… I’ve made it even better. My biggest issue with that implementation was that it did not keep the order like you’d expect. It read left to right in columns rather than down each column. In the example you can see the first column of three would read from the top: a, d, g, j… this could potentially be confusing. So I wanted to update it to keep the order better and just stack the columns of elements rather than the elements themselves.

I used some different jquery to execute this. First we walk through the menu elements and calculate which column they should be in. We basically map that element’s (li)index to the column it should be, some big math. Luckily I had some experience from actionscript in my arsenal doing just that, so porting the function to javascript I was ready to go. If your number X falls between A and B, and you would like to convert it to Y which falls between C and D follow this formula: Y = (X-A)/(B-A) * (D-C) + C. Plugging this function in and cancelling out the zeros and adding some rounding to get integers I got: Math.floor((liindex / $total * $cols)+1). Using this I added a class to each ‘li’ designating which column it should be in, and then used wrapAll to wrap them into column divs. Very simple and a much better implementation overall anyways. Better code, better user experience… what more can you ask… so here’s the example and jquery code. I’m thinking I should make this into a jquery plugin or something, any thoughts?

better-mega-menu-screenshot

See the mega menu in action

Javascript code

[cc lang=”javascript”]
jQuery(document).ready(function() {
//clean up the row of the mega menu. add css class to each element on bottom row.
//only if more than 7 elements. if more than 16, mm-3
jQuery(‘#nav li ul’).each(function(ulindex, ulele){
$total = jQuery(this).children(‘li’).size();
if ($total <= 7) { jQuery(this).addClass('mm-1'); } else { $cols = Math.floor(($total) / 8) + 1; $remainder = $total % $cols; $rows = Math.ceil($total / $cols); jQuery(this).addClass('mm-' + $cols + ' total-' + $total + ' rem-'+$remainder );jQuery(this).children().each(function(liindex, liele){ //alert("total: "+$total+", remainder: "+ $mod+", ulindex: "+ulindex+", liindex: "+liindex); //If your number X falls between A and B, and you would like to convert it to Y which falls between C and D follow this formula: Y = (X-A)/(B-A) * (D-C) + C. jQuery(this).addClass('col-' + Math.floor((liindex / $total * $cols)+1) ); if( (liindex+1) % $rows == 0) { jQuery(this).addClass('last'); } });for (var colcount = 1; colcount<= $cols; colcount++){ jQuery(this).children('.col-'+colcount).wrapAll('

‘);
}
}
});
});
[/cc]

css

[cc lang=”css”]
ul { list-style:none; }

/********** < Navigation */ .nav-container { float:left; background: #398301; margin: 10em 0; width: 960px; } #nav { border: 0px none; padding:3px 0 2px 44px; margin:0; font-size:13px; }/* All Levels */ #nav li { text-align:left; position:relative; } #nav li.over { z-index:999; } #nav li.parent {} #nav li a { display:block; text-decoration:none; } #nav li a:hover { text-decoration:none; } #nav li a span { display:block; white-space:nowrap; cursor:pointer; } #nav li ul a span { white-space:normal; }/* 1st Level */ #nav li { float:left; } #nav li a { float:left; padding:5px 10px; font-weight:normal; color: #fff; text-shadow: 1px 1px #1b3f00; } #nav li a:hover { color: #fff; text-shadow: 1px 1px 3px #ccc; } #nav li.over a, #nav li.active a { color:#fff; }/* 2nd Level */ #nav ul { position:absolute; width:15em; top:26px; left:-10000px; border:1px solid #1b3f00; border-width: 0 1px 2px 1px; background:#398301; padding: 6px 0 6px; } #nav ul div.col { float:left; width: 15em; } #nav ul li { float:left; padding: 0; width: 15em; } #nav ul li a { float:none; padding:6px 9px; font-weight:normal; color:#FFF !important; text-shadow: 1px 1px #1b3f00; border-bottom:1px solid #1b3f00; background:#398301; } #nav ul li a:hover { color:#fff !important; text-shadow: 1px 1px 3px #ccc; background: #2b6301; } #nav ul li.last > a { border-bottom:0; }
#nav ul li.last.parent > a { border-bottom:0; }

#nav ul li.over > a { font-weight:normal; color:#fff !important; background: #1b3f00; }
#nav ul.mm-1 { width: 15em; }
#nav ul.mm-2 { width: 30em; }
#nav ul.mm-3 { width: 45em; }
#nav ul.mm-4 { width: 60em; }
/* 3rd+ leven */
#nav ul ul { top:-6px; background: #1b3f00; }

/* Show Menu – uses built-in magento menu hovering */
#nav li.over > ul { left:0; }
#nav li.over > ul li.over > ul { left:14em; }
#nav li.over ul ul { left:-10000px; }

/* Show Menu – uses css only, not fully across all browsers but, for the purpose of the demo is fine by me */
#nav li:hover > ul { left:0; z-index: 100; }
#nav li:hover > ul li:hover > ul { left:14em; z-index: 200; }
#nav li:hover ul ul { left:-10000px; }
[/cc]

Download

Visit this demo page and view source or save as…

A simple mega menu implementation with CSS and jquery

I’ve been skinning quite a few ecommerce sites with the magento platform and wanted a simple way to explode the navigation menus. Some sites end up getting a long list of categories and sub-categories, so I wanted to do a mega-menu style navigation. One way to do it was to rewrite the html code for the navigation and pop each column into another nested unordered list. I’m not a fan of doing this because one – I didn’t want to manipulate the html. I like the simplicity of ul navigation with a clear flat list of li elements. Of course for nested sub-navigation any li can contain another ul. I wanted to just use some css and maybe javascript to visually accomplish the same thing. I also wanted it to be portable, so I could take it and use it on a wordpress install or even a plain html site. I went to my favorite: jquery. I knew there was a likely plugin out there already that would do something similar, but nothing after my initial search, but I realized that it was a simple procedure and mostly accomplished with some css.
mega menu screenshot
I’ll walk you through the process here and let you inspect the code yourself and see it in action on the demo page. Assign each ul to be a default width of 15em, then each li element we float:left and also give it a width of 15em. This way we can change the ul width to 30em and automatically I have 2 columns! Assigning the nested ul a specific width according to it’s class is done through css, mm-0 will be 15em and incrementally each next one will be 15em more. mm-1 is 30 and mm-2 is 45. Then we use jquery to determine the number of elements in the list and assign it a class accordingly. This involves some math and some preferences. Using the magic ui number 7, I determined that a menu with more than 7 elements should explode into multiple columns. So anything less than or equal to 7 I assign the class ‘mm-1’ which in the css sets the width to the standard 15em (ie 1 mega menu column). More than 7 should pop into columns no more than 8 tall. So dividing the total by 8 will give us the number of columns we want. We’ll add a class of mm-x, where x would be the number of columns. And the li elements will float to the left and fill in the space in columns.
One specific issue is the last element in the menu, sometimes we need to style that element differently. I’ll loop through each child of the nested ul element and if it is on the bottom row apply a class of ‘last’. But this was a little tricky in calculating which would be last because were never sure how many elements there will be or how many columns. I just used the remainder after dividing the total by the number of columns, then if the remainder could be used to know which elements are on the bottom row.

OK, now that that’s out of the way, let’s look at the code.

HTML

This I won’t show, you can inspect the source of the demo if you wish to see it, it a basic nested collection of unordered lists. It’s the standard that is created by magento, wordpress and most other CMS platforms.

CSS

[cc lang=”css”]
html, body { margin:0; padding:0; }
ul { list-style:none; }

/********** < Navigation */ .nav-container { float:left; background: #186C94; margin: 10em 0; width: 960px; } #nav { border: 0px none; padding:3px 0 2px 44px; margin:0; font-size:13px; }/* All Levels */ #nav li { text-align:left; position:relative; } #nav li.over { z-index:999; } #nav li.parent {} #nav li a { display:block; text-decoration:none; } #nav li a:hover { text-decoration:none; } #nav li a span { display:block; white-space:nowrap; cursor:pointer; } #nav li ul a span { white-space:normal; }/* 1st Level */ #nav li { float:left; } #nav li a { float:left; padding:5px 10px; font-weight:normal; color: #fff; text-shadow: 1px 1px #111; } #nav li a:hover { color: #fff; text-shadow: 1px 1px 3px #ccc; } #nav li.over a, #nav li.active a { color:#fff; }/* 2nd Level */ #nav ul { position:absolute; width:15em; top:26px; left:-10000px; border:1px solid #104A65; border-width: 0 1px 2px 1px; background:#186C94; padding: 6px 0 6px; } #nav ul div.col { float:left; width: 15em; } #nav ul li { float:left; padding: 0; width: 15em; } #nav ul li a { float:none; padding:6px 9px; font-weight:normal; color:#FFF !important; text-shadow: 1px 1px #111; border-bottom:1px solid #104A65; background:#186C94; } #nav ul li a:hover { color:#fff !important; text-shadow: 1px 1px 3px #ccc; background: #135575; } #nav ul li.last > a { border-bottom:0; }
#nav ul li.last.parent > a { border-bottom:0; }

#nav ul li.over > a { font-weight:normal; color:#fff !important; background: #104A65; }
#nav ul.mm-1 { width: 15em; }
#nav ul.mm-2 { width: 30em; }
#nav ul.mm-3 { width: 45em; }
#nav ul.mm-4 { width: 60em; }
/* 3rd+ leven */
#nav ul ul { top:-6px; background: #104A65; }

/* Show Menu – uses built-in magento menu hovering */
#nav li.over > ul { left:0; }
#nav li.over > ul li.over > ul { left:14em; }
#nav li.over ul ul { left:-10000px; }

/* Show Menu – uses css only, not fully across all browsers but, for the purpose of the demo is fine by me */
#nav li:hover > ul { left:0; z-index: 100; }
#nav li:hover > ul li:hover > ul { left:14em; z-index: 200; }
#nav li:hover ul ul { left:-10000px; }
[/cc]

Javascript

Don’t forget to include jQuery (I prefer using the google hosted version at http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js)
[cc lang=”javascript”]
jQuery(document).ready(function() {
//clean up the row of the mega menu. add css class to each element on bottom row.
//only if more than 7 elements. if more than 16, mm-3
jQuery(‘#nav li ul’).each(function(ulindex, ulele){
$total = jQuery(this).children(‘li’).size();
if ($total <= 7) { jQuery(this).addClass('mm-1'); } else { $cols = Math.floor(($total) / 8) + 1; $remainder = $total % $cols; jQuery(this).addClass('mm-' + $cols + ' total-' + $total + ' rem-'+$remainder );jQuery(this).children().each(function(liindex, liele){ //alert("total: "+$total+", remainder: "+ $mod+", ulindex: "+ulindex+", liindex: "+liindex); if( liindex + $remainder >= $total || $remainder == 0 && liindex + $cols >= $total ){
//alert(“total: “+$total+”, remainder: “+ $remainder+”, index: “+liindex);
jQuery(this).addClass(‘last’);
}
});
}
});

});
[/cc]

See the demo in action