Click here to Skip to main content
Click here to Skip to main content

Fixing Overlaying Layers with Dropdowns in IE

, 9 Oct 2006
Rate this:
Please Sign up or sign in to vote.
The problem I want to discuss in this article appears only in Internet Explorer. When an absolutely positioned layer (div) is overlaid with a dropdown or some ActiveX component, the z-index style sheet property does not work and the layer shows under such objects.

Sample screenshot

Introduction

The problem I want to discuss in this article appears only in Internet Explorer. When an absolutely positioned layer (div) is overlaid with a dropdown or some ActiveX component, the z-index style sheet property does not work and the layer shows under such an object.

Web developers very often use absolutely positioned layers to make navigation elements like drop-down menus, show messages, and even for making-up of whole pages. So, are there any workarounds?

Method 1: Hide all dropdowns on the page

The idea of the first method is simple – hide all the dropdowns on the page. If there won’t be any dropdowns, there is no problem. Yes, it is right, but it does not apply to ActiveX components.

To hide all dropdowns, we can use client script code. For instance, using JavaScript, we can find all the dropdowns on the form by looping through a list of all elements:

// looping through all forms on the page

for (f = 0; f < document.forms.length; f++)
{
    var elements = document.forms[f].elements;
    // looping through all elements on certain form

    for (e = 0; e < elements.length; e++)
    {
        if (elements[e].type == "select-one")
        {
            elements[e].style.display = 'none';
        }
    }
}

The first loop is for the forms array, and the second, for each element on a certain form. Also, for each element, we check the type and if the type equals “select-one”, we change the display property to “none” so the element will be hidden. Finally, add a block to show the layer and we get the function ShowLayer() which we can use to display a layer on the page:

function ShowLayer() {
    // hide all dropdowns on the page

        
    // looping through all forms on the page

    for (f = 0; f < document.forms.length; f++)
    {
        var elements = document.forms[f].elements;
        // looping through all elements on certain form

        for (e = 0; e < elements.length; e++)
        {
            if (elements[e].type == "select-one")
            {
                elements[e].style.display = 'none';
            }
        }
    }
        
    // show layer

    var layer = document.getElementById('layer');
    layer.style.display = 'block';
}

To hide a layer and show dropdowns again, we need to do similar work, but in a reverse fashion. This logic will be encapsulated in the function HideLayer():

function HideLayer() {
    // hide all dropdowns on the page

    for (f = 0; f < document.forms.length; f++)
    {
        var elements = document.forms[f].elements;
        for (e = 0; e < elements.length; e++)
        {
            if (elements[e].type == "select-one")
            {
                elements[e].style.display = 'block';
            }
        }
    }
    // hide layer

    var layer = document.getElementById('layer');
    layer.style.display = 'none';
}

In my opinion, the main disadvantage of such a solution is changing the user interface when the script hides all the dropdowns, so the user could become confused. In addition, using such an approach, we can hide the dropdowns which do not overlay the layer but have an important functionality which the user can use while the layer is shown. Let’s see what we have in method #2.

Method 2: Using IFRAME

The idea of this method is using an IFRAME. This element overlays all other elements of the form and also ActiveX components. But the beauty of this method is that we can set the z-index for it! Thus, we can make a dividing layer between dropdowns and absolutely position the layer. Let’s take a look at this simple example (instead of three dots, I placed a form with a dropdown which I used in method one):

<html>
<head>
    <title>Method Two</title>
    <style>
    #layer {
        position: absolute;
        top: 10px;
        left: 100px;
        width: 220px;
        height: 100px;
        border: 1px solid black;
        background-color: #e4e4e4;
        padding: 10px;
        z-index: 11;
    }
    #iframe {
        position: absolute;
        top: 10px;
        left: 100px;
        width: 222px;
        height: 102px;
        z-index: 10;
    }
    </style>
</head>
<body>
    <form>
    <iframe id="iframe" frameborder="0"></iframe>
    <div id="layer">
    This is absolutely positioned layer.
    </div>
    ...
    </form>
</body>
</html>

If you open this HTML page in IE, you will see that the dropdown will be under the layer. This is because I placed the third layer between the form elements like the dropdown and the layer. I set its z-index to 10, whereas for the layer, I set it 11. I also set the width and height to be exactly like the absolutely positioned layer so it’s hidden for the user and just does the work to hide everything under it.

Let’s change the functions from the example in method 1 to work with the IFRAME:

function ShowLayer() {
    // show layer

    var layer = document.getElementById('layer');
    layer.style.display = 'block';
    // show IFRAME

    var iframe = document.getElementById('iframe');
    iframe.style.display = 'block';
    iframe.style.width = layer.offsetWidth;
    iframe.style.height = layer.offsetHeight;
    iframe.style.left = layer.offsetLeft;
    iframe.style.top = layer.offsetTop;
}

function HideLayer() {
    // hide IFRAME

    var iframe = document.getElementById('iframe');
    iframe.style.display = 'none';
    // hide layer

    var layer = document.getElementById('layer');
    layer.style.display = 'none';
}

The ShowLayer function sets the width, height, left, and top values for the IFRAME depending on the layer properties. We do not need to set those values in the style sheet for a dropdown layer.

Method 3: Replacing SELECTs with SPAN

Volkan.ozcelik posted an interesting method in his article Modal Dialog – enhanced. He proposed to use a replacement to avoid "bleeding". Before a new layer is opened, a JavaScript function searches the whole HTML file and replaces all dropdowns with a SPAN tag. Using CSS, we can make the SPAN look almost like a SELECT so the form view will be changed a little and it won’t annoy users like method 1 when we hide all dropdowns.

Conclusion

I do not see any advantages in the first method. It does not help with ActiveX components and annoys users when the JavaScript hides all the dropdowns in the page. The second method helps with dropdowns and ActiveX components and doesn’t change the SELECTs. The third method helps only with dropdowns and changes the view of the form a little. Also, users cannot use the form while the layer is shown because all SELECTs will be replaced with SPANs.

The first two method examples can be found in the source files. Regarding method 3 example, refer to the Modal Dialog – enhanced article please.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alexander Kleshchevnikov
Web Developer
Ukraine Ukraine
Alexander is freelance web developer with 4 years experience. He has skills in ASP.NET/MS SQL Server, PHP/MySQL, Ruby On Rails, XHTML, CSS. You can contact with me by seigo.ua@gmail.com. Also check my homepage at www.klalex.com.

Comments and Discussions

 
Generalthe 2nd method is also known as 'SHIM technique' Pinmembersharapanoff18-Oct-06 7:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 9 Oct 2006
Article Copyright 2006 by Alexander Kleshchevnikov
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid