views:

121

answers:

3

I have a block element that is positioned absolutely and some other elements on page that are positioned fixed. The effect is the block on top floats over the page which works well.

The links in the elements at the bottom underneath are not clickable. They shouldn't be when the content of the div is over them, but when the "marginal" areas which are transparent are over the links they are visible, but clicks only register to the covering div.

The problem only happens when the padding covers the div. But if I just rely on the margin the bottom margin is ignored by browser so the scroll doesn't go high enough up. To solve this I resort to padding at the bottom. This is the problem.

Is there a clean way around this? I realize I could have the underneath elements doubled and place on top, but opacity set to 0. That is an undesirable solution however.

Sample of the problem:

<!DOCTYPE html>
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'&gt;
  <head>
    <style>
      #top, #bottom {
        position: fixed;
        border: 1 px solid #333;
        background-color: #eee;
        left: 100px;
        padding: 8px;
      }
      #top {
        top: 0;
        z-index: 1;
      }
      #bottom {
        bottom: 0;
        z-index: 2;
      }
      #contentWrapper {
        position: absolute;
        margin: 100px 0 0 0;
        /* Padding is used to make sure the scroll goes up further on the page */
        padding: 0 0 100px 0;
        width: 600px;
        z-index: 3;
      }

      #content {
        border: 1 px solid #333;
        background-color: #eee;
        height: 1000px;
      }
    </style>
  </head>
  <body>
    <div id='top'><a href="#">Top link</a></div>
    <div id='bottom'><a href="#">Bottom link</a></div>
    <div id='contentWrapper'>
      <div id='content'>Some content</div>
    </div>
  </body>
</html>
A: 

As far as I know, the only way you could do that would be to handle the events on the covering <div>, and use the mouse coordinates in the event to figure out which link to trigger. It makes me uncomfortable to even think about doing that, but it might be possible. Long before I got close to trying that, I'd work hard on coming up with a better way of positioning the top layer so that the padding wasn't necessary.

Pointy
Yea that's exactly how I feel. Doing something nasty that almost seems like exploiting HTML doesn't seem like a good solution.
Adam
A: 

Try making the covering div as small as possible.

Or more specifically, if the 'clear' sections are 'square' in shape than perhaps you could create the floating area from multiple smaller divs instead. This would make the 'transparent' areas actually 'div free' and so the links will be clickable in these areas.

I don't think it's possible to make links clickable through a div in any other way?

Matthew James Taylor
+1  A: 

The problem is your padding. The link at the top is still clickable because the margin on your content displaces it, meaning that your element is no longer covers your link when the user has scrolled to the correct place. With the padding-bottom the element is extended and the element covers the links at the bottom. The solution is therefore found when considering the problem: how do we extend where the page can scroll to without using #contentWrapper?

Here's one solution which works regardless of the height of your content:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html>
  <head>
    <style>
    #top, #bottom {
        position: fixed;
        background-color: #00F;
        left: 100px;
        padding: 8px;
    }
    #top {
        top: 0;
    }
    #bottom {
        bottom: 0;
    }
    #contentWrapper {
        position: absolute;
        margin: 100px 0 0 0;
        width: 600px;
        z-index: 10000;
        overflow: visible;
    }
    #heightFix {
        position: absolute;
        bottom: -100px;
        height: 0;
        overflow: hidden;
        font-size: 0;
    }

    #content {
        background-color: #F00;
        height: 1000px;
    }
    </style>
  </head>
  <body>
    <div id="top"><a href="#">Top link</a></div>
    <div id="bottom"><a href="#">Bottom link</a></div>
    <div id="contentWrapper">
      <div id="heightFix"></div>
      <div id="content">Some content</div>
    </div>
  </body>
</html>
icio
Thanks, I'd tried something similar, but creating an element after will work. Sadly the content size changes over the life of the page, but a setInterval on a half second timer can adjust the placement of the second fix block.
Adam
That's a horrifying thought. JavaScript just to get your CSS to work? No thanks. Please, take this edit and second solution instead.
icio
Ohh yes, Javascript is so not the way I wanted to, I abandoned it shortly after I tried it anyway, such a bad taste in my mouth.So yes this works perfectly! Thank you, thank you, thank you, I've spent too much time on this silly problem.I am a bit curious why this works though. Are nested absolute positioned elements positioned relative to their container?
Adam
Yes, I believe that is the case: absolute positioning "Generates an absolutely positioned element, positioned relative to the first parent element that has a position other than static." [http://www.w3schools.com/css/pr_class_position.asp]
icio