Using Anchors with Equal Height Columns Hides Content
Asked Answered
A

2

7

The Setup

I'm making a website with a simple 2 column layout. The columns will be of varying height (one taller than the other) and dynamic height (each page's content is different). The two columns' background color should extend down to the lowest point of the longest column's content.

For the visual learners among you, CSS-Tricks has some nice illustrations

enter image description here

enter image description here

The Attempt

I'm using the One True Layout Method, mentioned on the same CSS-Tricks page about half way down.

I've recreated it on jsFiddle here.

Here is the relevant coding

HTML

<a href="#area1">Go To Section 1</a>
<a href="#area2">Go To Section 2</a>
<a href="#area3">Go To Section 3</a>

<div id="hold">
    <div id="col1">
        Content Column 1
    </div>
    <div id="col2">
        Content Column 2

        <h2 id="area1">Section 1</h2>
        <img src="http://placehold.it/100x750" alt=" placehold img" />

        <h2 id="area2">Section 2</h2>
        <img src="http://placehold.it/100x750" alt=" placehold img" />

        <h2 id="area3">Section 3</h2>
        <img src="http://placehold.it/100x750" alt=" placehold img" />
    </div>
</div>

CSS

#hold{
    height:100%;
    overflow-y:hidden;
}
#col1, #col2{
    padding-bottom:100000px;
    margin-bottom:-100000px;
}
#col1{
    float:left;
    width:200px;
}
#col2{
    margin-left:200px;
}

What Works?

The layout works entirely as expected. The column heights adapt to dynamic content and always remain the same height as each other.

The Problem

Anchors break it. That is to say, the page scrolls down to the proper anchor in the content, but everything above the anchor is hidden. I learned this is due to overflow-y:hidden; - the page is scrolling down to the content and instead of using a scroll bar it's hiding the above content and not just scrolling past it. Disabling overflow:hidden shows all content as expected, but this is not ideal due to the large bottom padding.

Other's have experienced this same problem with no recognized solutions that I could find.

Possible Solutions

I could put together a quick height check in JavaScript and set each column accordingly, but I'd really like to keep overall site layout JS free.

Some articles had mentioned absolute positioning fixed, but this won't work with dynamic content.

Change to a different column height method. But... but... but I already have this one so far! And who are we to simply cave in to an impossible a difficult coding challenge.. :)

The Call for Aid

Any ideas, fellow programmers?

Anemometer answered 11/2, 2013 at 8:51 Comment(3)
Are you concerned with IE7 compatibility?Taciturnity
At below 1% of worldwide users, not really. I mean, they need to be able to see the content still, but if design is flawed for them... meh. gs.statcounter.com/…Anemometer
+1 for the most well put together question I've seen on SOLuttrell
T
2

Since you indicated you don't necessarily care about IE7 support, you can use one of the other techniques (also found in the CSS Tricks link you referenced in your question) to use the display: table and table-cell.

This gives you the same equal height columns regardless of the dynamic content but also allows you to scroll up after clicking an in-page anchor without hiding the content completely out of view.

I really despise using invisible tables for layout purposes but in this case it doesn't force any additional DOM elements by just changing the DIV display attribute values, and isn't really any more hacky than the negative-margin positive-padding approach.

#hold{
    width:100%;
    background:#ccc;
    height:100%;
    display: table;
}
#col1, #col2{
    display: table-cell;
}
#col1{
    width:200px;
    background:#00c;
}
#col2{
    background:#c00;
}
Taciturnity answered 12/2, 2013 at 16:49 Comment(2)
This is a pretty good alternate approach, although I too rather despise having to resort to anything tables haha. +1 and I'll mark as the answer if nothing else comes up.Anemometer
Agreed, I avoid table-based layouts like the plague but really some of the other stuff is pretty hacky too and you spend way too much time trying to get around it and still have a perfect solution. I'd love to know a better way myself too though, preferably CSS-based without JavaScript.Taciturnity
G
2

you are tricking the browser but it has a side affect (it breaks the anchor). the best solution would be finding a different method for adjusting the column height but it looks like in that area you've done more research then i anyway.

given the parameters of your question (it seems like you don't want to use JavaScript for design and you don't really want to change the method you use to fix the columns) i'd say the closest you can get to that would be to use your css for design and JavaScript to fix the anchor.

this snippet should work for you

var isScrollFix = false;
document.getElementById('hold').addEventListener('scroll',function(e){
        if(!isScrollFix) {//dont copy our own scroll event onto document
              isScrollFix = true;
              var scrollTo = this.scrollTop;
              this.scrollTop = 0;
              window.scroll(0, scrollTo);
         } else {
              isScrollFix = false;
         }
});

or on jsfiddle with a little extra code to account for other situations as well http://jsfiddle.net/joshK/P72LV/5/

Giannini answered 12/2, 2013 at 15:52 Comment(4)
Not a bad idea. Any idea how a non-JS fallback would work? If someone goes to site.com#area2 with JS enabled this should work exactly as expected, but with JS disabled, the top content would still be hidden, I assume.Anemometer
i figured u don't care much for users with js disabled since its about the same percentage as IE7 users. if u want it to still work for them u can use a noscript tag with a style in it to remove the negative margin i guess..Giannini
Do you have stats on the number of users with JS disabled? I know Yahoo had an article in 2012 that said around 2% of users have it disabled, but I haven't sen anything more recent or to verify the numbers before.Anemometer
The reality that there hasn’t been any concrete statistics on that since 2010 speaks for itself. But as far as I can tell from one of my employers data the number is very insignificantGiannini
T
2

Since you indicated you don't necessarily care about IE7 support, you can use one of the other techniques (also found in the CSS Tricks link you referenced in your question) to use the display: table and table-cell.

This gives you the same equal height columns regardless of the dynamic content but also allows you to scroll up after clicking an in-page anchor without hiding the content completely out of view.

I really despise using invisible tables for layout purposes but in this case it doesn't force any additional DOM elements by just changing the DIV display attribute values, and isn't really any more hacky than the negative-margin positive-padding approach.

#hold{
    width:100%;
    background:#ccc;
    height:100%;
    display: table;
}
#col1, #col2{
    display: table-cell;
}
#col1{
    width:200px;
    background:#00c;
}
#col2{
    background:#c00;
}
Taciturnity answered 12/2, 2013 at 16:49 Comment(2)
This is a pretty good alternate approach, although I too rather despise having to resort to anything tables haha. +1 and I'll mark as the answer if nothing else comes up.Anemometer
Agreed, I avoid table-based layouts like the plague but really some of the other stuff is pretty hacky too and you spend way too much time trying to get around it and still have a perfect solution. I'd love to know a better way myself too though, preferably CSS-based without JavaScript.Taciturnity

© 2022 - 2024 — McMap. All rights reserved.