SiteEdit with positive z-indexes

When you have used SDL Tridion you will no doubt also have encountered SiteEdit and will have seen how useful it can be to easily maintain your web content. With Modular Templates the implementation of SiteEdit has been made really easy, but getting it to work for you properly within your own website design can sometimes be some more work.

This article will discuss the chalenges you face when your HTML/CSS design uses positive z-indexes (http://www.w3schools.com/cssref/pr_pos_z-index.asp) and offer two solutions for it.

SiteEdit

Before we identify the issue, let us first take a look at what SiteEdit is made of. SiteEdit adds a set of controls on top of your (staging) website, allowing you to edit your content directly from your (staging) website. These controls consists of some HTML elements, which are injected in the webpage using JavaScript.

The HTML elements used are: DIV, SPAN, SELECT, INPUT, TEXTAREA and IMG, all of these have no class and contain inline styling. Considering that "basic" HTML element all have a z-index of 0, each of the SiteEdit elements have gotten a z-index of 1 to ensure they will appear on top of your website. While this works fine for most web designs, it also directly shows an issue if your HTML/CSS design uses positive z-indexes itself, as this will mean that certain SiteEdit controls might not be on top anymore and appear hidden behind your website. Image 1 shows an example of a SitEdit inline edit box, being hidden below the HTML design.

Hidden inline SiteEdit control

Image 1. SiteEdit inline edit box hidden behind HTML design because the use of a positive z-index.

Solutions

To solve this issue there are two solutions, the first one being quite straight forward (this is the recommended approach by SDL Tridion Customer Support). Do not use positive z-indexes in your HTML/CSS design. While this option is completely valid, it does rely heavily on your HTML/CSS. For example if you are designing your website from scratch, it is quite easily done to start your visible layer at z-index 0 (the default) and ensure that all elements you want below that get a negative z-index. So if you want to hide (part of) a div, you give that a z-index of -1. However if your design has been made using a different approach (i.e. designed from the bottom up, starting at z-index 0 and giving all elements on top of that a higher z-index value) then you might have a difficult time changing all the CSS so that it does not use positive z-indexes anymore. Since, while it should be possible to rearrange all z-indexes from positive to negative, it might mean that you have to give each an every element in your CSS a z-index value, starting with the HTML and BODY element.

To come to the rescue for such an issue we have solution number two. This solution relies on the use of JavaScript and jQuery to dynamicly alter the z-index of all elements generated by SiteEdit. Before we can do this we need to identify these elements exactly, else we run the risk of acidentally giving a element of our web design a different z-index, which will break the layout. As mentioned before, the SiteEdit control elements are: DIV, SPAN, SELECT, INPUT, TEXTAREA and IMG, all of which do not contain a class and have inline styling. So if we ensure that our web design only contains elements with a class or elements without inline styling, we can easily distinguish the SiteEdit elements (this might still require you to change your HTML if it does not meet the forementioned condition).

Lets start with focussing on the form input elements (SELECT, INPUT and TEXTAREA). even if you are using these in your website design, they will all need to be on the visible layer, so giving them a positive z-index should never have a negative effect on the web design. The form input elemnts generated by SiteEdit all get a z-index of 1 by default, but we can override this by adding the following line to our website's CSS:

SiteEdit styling

Now all the form elements will always be on top of the rest of the HTML (when visible). This simple solution will make sure that the SiteEdit inline editing elements are visible, but it does not solve possible issues with the SiteEdit borders around Component Presentations and the control buttons. For this we need to call in the help of some JavaScript, with the following jQuery function we can change the z-index of all SiteEdit elements:

SiteEdit jQuery fix

[UPDATE: December 16th, 2011 - removed the need for the patch, please use the code below now]
Most of the SiteEdit elements are generated after we enable SiteEdit, when all the Component Presentations on the page are loaded. We can make use of the events which are fired by the SiteEdit JavaScript code to ensure our function is applied at the right time. These changes have been tested on SiteEdit 2009 SP3 (with hotfix SE_2.3.0.77444 which you can find in the downloads section).

/* SITE EDIT 2009 SP3 */
var onEndInitState = function () {
    $("div, span, textarea, img, input, select").each(function () {
        if ((this.className == "" && this.style != "") || this.className == "ajax__calendar_message") {
            this.style.zIndex = "999";
        }
    });
    // give an indication that the fix is applied
    var tmpDiv = document.createElement("div");
    tmpDiv.innerHTML = "[SiteEdit fixed]";
    tmpDiv.style.color = "green";
    tmpDiv.style.fontSize = "12px";
    tmpDiv.style.position = "absolute";
    tmpDiv.style.right = "5px";
    tmpDiv.style.top = "5px";
    tmpDiv.style.zIndex = "1000";
    $("body")[0].appendChild(tmpDiv);
};
var onStartFieldEditing = function () {
    // reapply fix in case any new elements have been generated
    $("div, span, textarea, img, input, select").each(function () {
        if ((this.className == "" && this.style != "") || this.className == "ajax__calendar_message") {
            this.style.zIndex = "999";
        }
    });
};
var onIFrameUnload = function () {
    var m = top.$SeEventManager.getInstance();
    top.$SePageController.getInstance().get_events().removeHandler("endInitState", onEndInitState);
    m.Unsubscribe("startFieldEditing", onStartFieldEditing);
    m.Unsubscribe("iframeUnload", onIFrameUnload);
}
try {
    if (typeof (top.$SeEventManager) != "undefined") {
        var m = top.$SeEventManager.getInstance();
        top.$SePageController.getInstance().get_events().addHandler("endInitState", onEndInitState);        
        m.Subscribe("startFieldEditing", onStartFieldEditing);
        m.Subscribe("iframeUnload", onIFrameUnload);
    }
} catch (e) { }

This code will only fire when SiteEdit is enabled and initialized and additionally apply the z-index change when a SiteEdit control element is selected to ensure we also cover any elements created at runtime. While this code only runs when SiteEdit is enabled, it and the additional CSS we applied to the page before should ideally only be available on your staging website.

Conclusion

This second solution will fix most of the issues encountered when your web design makes use of positive z-indexes, with my personal tests I haven't found any issues so far. However if it will be usable in your own situation will completely depend on the suitability of your HTML/CSS design. 

If you happen to come accross any issues in my solution, please contact me through the forum or through email, so we can make it available to the community.

About the Author
Bart Koopman
Community Development Consultant

As a Community Development Consultant, Bart is the evangelist of all SDL Tridion products. Bart used to be a consultant and trainer at SDL Tridion, supporting both partners and customers with their implementations.

SDL CMT division