Sometimes, you may want to create a shadow effect of a rectangular window/div/image Element and not have to worry about setting it up. We cannot rely on filter effects as it’s not cross-browser compliant. We don’t want .png with transparencies because it does not work well in IE6.
And last but not least, cleaning up the shadow as you remove/dispose the parent element should be automatic. So, we are going to be relying on pure CSS and drawn elements to do this instead, here is our shadowy snippet mooShadow in action:
Element.implement({ smartDispose: function() { // dispose of an element and its dropShadow (if there is one) var rel = this.get("data-related"); if ($(rel)) { $(rel).destroy(); } this.destroy(); }, // end smartDispose dropShadow: function(options) { // creates a shadow effect to a rectangular element // define defaults var options = $merge({ id: "dropShadow" + $random(100,1000), x: 3, // offset from parent y: 3, border: "1px solid #000", background: "#555", opacity: .5, zIndex: this.getStyle("z-index").toInt() - 1 // behind parent }, options); // only apply shadow on absolutely positioned elements if (this.getStyle("position") != "absolute") return this; var c = this.getCoordinates(); new Element("div", { id: options.id, styles: { position: "absolute", left: c.left + options.x, top: c.top + options.y, width: c.width, height: c.height, background: options.background, zIndex: options.zIndex }, opacity: 0 }).injectBefore(this).fade(0, options.opacity); // store the shadow id into the element this.set("data-related", options.id); return this; } // end dropShadow });
We extend all Elements by adding a .dropShadow() method. Here is an example use that’s similar to a tooltip:
window.addEvent("domready", function() { $("runShadow").addEvent("click", function() { var c = this.getPosition(); new Element("div", { "class": "cur", styles: { border: "1px solid #000", background: "#ffffcf", position: "absolute", // required left: c.x, top: c.y+16, width: 300, height: 40, zIndex: 100, padding: 2, "font-weight": "bold" }, html: "Example info box with a dropshadow, click to close", events: { // we close click: function() { // close it via our new method, collecting dropshadow as garbage this.smartDispose(); } } }).inject(document.body).dropShadow(); // inject into dom and add shadow }); // end click event });
You may want to Run this example
In an ideal world, you could add events for the parent Element being moved as the shadow would have to follow…
[…] may notice the element has a dropshadow applied to it. If you are interested, have a look at our mooShadow for absolutely positioned elements (hence the need to setStyle to absolute and back to relative […]