Example: Left Nav with Submenus with Shadows

This example demonstrates how to add shadows to submenus of a menu built using the MenuNav Node Plugin.

Creating the Shadow HTML

Note: be sure to add the yui3-skin-sam classname to the page's <body> element or to a parent element of the widget in order to apply the default CSS skin. See Understanding Skinning.

<body class="yui3-skin-sam"> <!-- You need this skin class -->

One way to add shadows to submenus is to append decorator elements to the node representing a submenu's bounding box. As the name implies, decorator elements add no semantic value to the markup, but enable additional styles to be applied. When adding any decorator elements to create effects like shadows or rounded corners, always add those elements via JavaScript, since it is only when JavaScript is enabled that a menu's markup is transformed in a drop-down menu system via the MenuNav Node Plugin.

Each shadow will be represented in HTML as a single <div> element with a class of yui3-menu-shadow applied, and can easily be created by passing a string of HTML to Node's create method. Use the all method to retrieve Node instances for each submenu, and the append method to add the shadow to each submenu.

//  Call the "use" method, passing in "node-menunav".  This will load the
//  script and CSS for the MenuNav Node Plugin and all of the required
//  dependencies.

YUI().use('node-menunav', function(Y) {

    //  Retrieve the Node instance representing the root menu
    //  (<div id="productsandservices">)

    var menu = Y.one("#productsandservices");


    //  Use the "all" method to retrieve the
    //  Node instances representing each submenu.

    menu.all(".yui3-menu").each(function (node) {

        // Append a shadow element to the bounding box of each submenu

        node.append('<div class="yui3-menu-shadow"></div>');

    });


    //  Call the "plug" method of the Node instance, passing in a reference to the
    //  MenuNav Node Plugin.

    menu.plug(Y.Plugin.NodeMenuNav);

    //  Show the menu now that it is ready

    menu.get("ownerDocument").get("documentElement").removeClass("yui3-loading");

});
Note: In keeping with the Exceptional Performance team's recommendation, the script block used to instantiate the menu will be placed at the bottom of the page. This not only improves performance, it helps ensure that the DOM subtree of the element representing the root menu (<div id="productsandservices">) is ready to be scripted.

Styling the Shadow HTML

With the shadow element appended to each submenu, the next step is to define the style for the shadow. The shadows in this example will be 12% alpha transparent black, and offset from the left, bottom, and right edges of each submenu's content box by 3px. To create this effect, start by setting the position property to absolute and the z-index property to -1. This will position each submenu's shadow behind its content box. For the 12% alpha transparent black color, set the background-color to #000 and opacity property to .12.

Next, set the both the width and height properties to 100% so that the dimensions of the shadow match that of each submenu's bounding box. (Note: Setting the height property to 100% won't work in IE 6 Strict Mode unless the element's parent element has a height defined. For this reason the the MenuNav Node Plugin automatically sets the width and height properties of each submenu's bounding box to the values of its offsetWidth and offsetHeight properties before it is made visible.)

To create the three-sided effect for the shadow, set the padding property to 1px 3px 0 3px. As the CSS Box Model specifies that the value for padding is used to calculate the total width of of an element, the addition of the padding to the shadow makes the rendered width of the shadow 6px wider (100% + 6px) and 1px taller (100% + 1px) than that of each submenu's bounding box. Finally, setting the top property to 2px and the left property to -3px will position the shadow so that its offset from the left, bottom, and right edge of each submenu's content box by 3px.

.yui3-menu-shadow {

    position: absolute;
    z-index: -1;
    top: 2px;
    left: -3px;

    background-color: #000;
    opacity: .12;
    filter: alpha(opacity=12);  /*  For IE since it doesn't implement the CSS3
                                    "opacity" property. */

    padding: 1px 3px 0 3px;
    width: 100%;
    height: 100%;

}

Lastly, it is necessary to modify the position and dimensions of the <iframe> shim, otherwise <select> elements will poke through each submenu's shadow in IE 6. Start by setting the z-index property to -2 so that the <iframe> shim is behind the shadow element. Next, set the padding property to 3px 3px 0 3px. The core CSS file for MenuNav already sets the height and width properties to 100%, so the addition of the padding will result in the calculated width and height of the <iframe> shim being 100% + 6px and 100% + 3px respectively — enough to shim the shadow. Lastly, setting the left property to -1 syncs the left edge of the <iframe> with that of the shadow.

#productsandservices .yui3-menu .yui3-shim {

    z-index: -2;    /* Place the iframe shim behind the shadow element */

    /*
        Adjust the dimensions of the <iframe> shim to match the shadow,
        otherwise <select> elements will poke through the shadow.
    */

    left: -3px;
    padding: 3px 3px 0 3px;

}