0

I have a div (#box) on a page that is absolutely positioned a percentage from the top and bottom of the window. Naturally, this will resize when the window dimensions change,

Inside this div is content that can be anything from a few lines to several paragraphs. I would like this content to be vertically centred at all times, never exceeding #box's height - with the main content overflowing when necessary.

HTML:

<div id="box">

    <div id="content">
        <h1>HEADING</h1>
        <div id="left">
            <p>
            // Lorem ipsum etc...
            </p>
        </div>
    </div>

</div>

CSS:

#box{
    position:absolute;
    top:15%; bottom:15%;
    background:white;
    left:50%;
}
#content{
    position:absolute;
    top:50%;
    overflow:auto;
    background:lightgrey;
}

jQuery(JavaScript):

function alignContent(){

    // Position box
    $box = $('#box');
    $box.css({
        'width' : $box.height() + 'px',
        'margin-left' : '-' + $box.height()/2 + 'px'
    });

    // Position content
    $content = $('#content');
    console.log( $content.outerHeight() );
    $content.css({
        // Set maxheight smaller for aesthetic purposes
        'max-height' : $box.height()-72 + 'px',
        'margin-top' : '-' + ($content.outerHeight()/2) + 'px'
    });
}
alignContent();

// Update when resized
$(window).resize(function(){
    alignContent();
});

See it working.

The approach is - I think - quite simple and works most of the time. The problem arises when the content is too tall for the #box on page load - the content is incorrectly positioned (notice also that the console.log returns the wrong value). Resizing aligns everything correctly again.

What's making it align incorrectly on page load, when the content is taller than the container - and is it easily fixable?

Edit: Excuse my British inclination to spell it "centre"

verism
  • 1,106
  • 1
  • 12
  • 35

2 Answers2

1

The resize event isn't triggered on page load, and your explicit call is too early during the DOMReady (it's fired when the DOM is complete, but does not yet have all secondary assets and stuff loaded) event. You need to explicitly do the same for the document onLoad by adding:

$(window).load(function(){
    alignContent();    
});

Fiddle sample here, works fine.

More info on difference between onDOMReady and onLoad found here.

Community
  • 1
  • 1
Niels Keurentjes
  • 41,402
  • 9
  • 98
  • 136
  • Excellent, thank you. Just one more question: if I remove the first function call, but still leave the `$(window).load`... it still doesn't fire properly on page load. That strikes me as strange behaviour. – verism May 24 '13 at 13:31
  • Funny, I hadn't noticed that. You can actually also solve the problem by [calling it twice](http://jsfiddle.net/Curry/aSue8/4/) in `DOMReady`. I suspect that your explicit setting of `max-height` changes the initial box size, causing the earlier call to `$box.height()` returning wrong data as a base for setting the `width`. On the second call it's correct this because the `max-height` is applied. – Niels Keurentjes May 24 '13 at 13:35
  • 1
    Keep in mind that if the content contains images the double invocation during `DOMReady` will **not** be enough - it'll need the second one during `Load` unless you specify the `img` sizes correctly in `width` and `height` attributes. – Niels Keurentjes May 24 '13 at 14:17
-1

Change the CSS for the box as below. Add the overflow:scroll;. It'll work.

#box{
    position:absolute;
    top:15%; bottom:15%;
    background:white;
    left:50%;
    overflow:scroll;
}
ARC
  • 437
  • 3
  • 3