1

I've found several SIMILAR scenarios that have been asked already, but none that solve this particular problem. I'm hoping someone can help!

Three divs in a row. The middle div is centered, and has a set width & height. The outer two divs must expand to fill the remaining space between the edge of the window, and the edge of the center div. Like this:

http://kthornbloom.com/example.jpg

*note- I'd like to solve it with CSS, but if javascript is required, that would be ok

*note2- The purpose of this isn't to center the middle div, I know there's better ways of doing that. The purpose is for the design of the site which uses a background element that needs to be the full width of the page except in the middle.

kthornbloom
  • 3,660
  • 2
  • 31
  • 46
  • If the only reason is to have a background that spans the whole page, why not just set background-image on html? Do you need to put any specific content in div1 and 3? – Effata Mar 31 '11 at 20:13
  • Do you need IE6 or IE7 support? – thirtydot Apr 01 '11 at 09:29
  • @Effata- It's because I need a background image that spans the whole width EXCEPT in the middle. Also, I'll be animating the background image of the right div. (it's a little complicated to explain) – kthornbloom Apr 01 '11 at 13:05

3 Answers3

8

See: http://jsfiddle.net/thirtydot/xhCXq/

HTML:

<div id="container">
    <div id="left">&nbsp;</div>
    <div id="mid">mid</div>
    <div id="right">&nbsp;</div>
</div>

CSS:

#container {
    width: 100%;
    height: 200px;
    display: table
}
#left, #mid, #right {
    display: table-cell;
    background: #ccc;
    outline: 2px dashed blue
}
#mid {
    width: 400px;
    background: #f0f
}

I think that answers your question nicely, but this concerns me:

The purpose of this isn't to center the middle div, I know there's better ways of doing that. The purpose is for the design of the site which uses a background element that needs to be the full width of the page except in the middle.

Are you sure you actually need a complicated solution like this? Maybe something simpler instead:
http://jsfiddle.net/thirtydot/xhCXq/1/

thirtydot
  • 224,678
  • 48
  • 389
  • 349
  • Both examples you provided will not work in IE6 and IE7. jQuery remains the only cross browser compatible way to do this. – Hussein Apr 01 '11 at 01:46
  • @Hussein: You're right that this doesn't work in IE6/7 *at the moment*. However, he might not even care about those browsers (especially IE6 support is unlikely to be required in this day and age). And if he does require support for those browsers, I can add hacks to make it work. He should probably use my method instead in any case, because it works when JavaScript is disabled, (which is always desirable), and it looks far nicer when you're resizing. You always get a flicker with the JavaScript technique when resizing. – thirtydot Apr 01 '11 at 09:28
  • @Hussein: If he does decide to stick with your solution, make sure you account for subpixel rendering difference between different browsers (the rounding problems you're having). For relevant info, see: http://stackoverflow.com/questions/5115637/evenly-distributed-height-of-child-elements-with-css I gave you +1 :) – thirtydot Apr 01 '11 at 09:31
  • @thirtydot: Thanks for the alternate solution. I don't really care THAT much about IE6/7, but I do hate using faux tables. I have to add some images in the left and right divs which causes the layout to fall apart. I'd be happy with @Hussein's approach if I can solve the 1px problem! – kthornbloom Apr 01 '11 at 13:08
  • @KThornbloom: Any particular reason you don't want to use faux tables? They don't have *any* of the usual downsides of `` - the sole downside is no IE6/7 support without hacks to make it work. Can you edit my demo (http://jsfiddle.net/thirtydot/xhCXq/) to show me show adding images breaks it? Here's a new version that should work better with ``s inside the left and right cells: http://jsfiddle.net/thirtydot/xhCXq/2/ I'm not going to attempt to fix @Hussein's code, because it's quite tricky to make it work perfectly in all browsers (and that's his job to fix :] ).
    – thirtydot Apr 01 '11 at 13:15
  • @thirtydot: Ok, I've gotten it mostly working now. Here's the remaining issue: I basically set up two of these structures, one on top of the other. In the top one, I have a height specifically set to 21px which is fine. However, when I add an image that's 21px tall, the div gets bumped up to 25px. It's like there's phantom padding I can't get rid of. http://jsfiddle.net/xhCXq/7/ – kthornbloom Apr 01 '11 at 14:04
  • 1
    @KThornbloom: It's coming from the `` elements. See: http://jsfiddle.net/xhCXq/13/ - I've fixed it by adding `vertical-align: top`. – thirtydot Apr 01 '11 at 14:39
3

CSS is not a dynamic language, you can't use it to calculate remaining space. You can use jQuery for that. In the example below Middle div will stay 400px while remaining space will be split between left and right divs.

function calc() {
    var ww = $(window).width();
    var rem = ww - $('.div2').width();
    $('.div1, .div3').css('width', rem / 2);
}
calc();
$(window).resize(calc);

Check working example at http://jsfiddle.net/M5Ghx/3/

Hussein
  • 42,480
  • 25
  • 113
  • 143
  • 1
    There is just a small bug with this where if the user resizes the page quickly, rem will be a negative number and so the divs will fail to resize correctly. I'll edit in the fix. – Rupert Madden-Abbott Mar 31 '11 at 22:35
  • This is quite good! Thank you. The only 'bug' if you could call it that is some browsers with have a 1px gap between the divs when sized to ".5" dimensions (chrome on pc). I'd guess this is a browser limitation, not a problem with your code. I'll wait a bit longer, and mark this as the answer if no one else has other suggestions. – kthornbloom Apr 01 '11 at 00:38
  • Yes this is a browser limitation. You can get around this by wrapping all 3 divs inside another div that has a background matching the middle div. Check http://jsfiddle.net/M5Ghx/4/ – Hussein Apr 01 '11 at 01:02
  • Ok, after a lot of testing, I'd like to use this method. Is there a way to fix the problem Rupert pointed out though? Resizing the window quickly makes the right div flicker and jump up and down. – kthornbloom Apr 01 '11 at 03:08
  • We can't control Flicker do to fast window resize. – Hussein Apr 01 '11 at 03:21
  • Would there be a way to measure only in whole numbers? It seems to only happen with the calculated widths come out to '.5' at the end. – kthornbloom Apr 01 '11 at 03:25
  • Hey thank you for the help! I just have one last issue. In Firefox it appears to be about a 10px jump instead of just the 1px which is a bigger deal. It happens when resizing the window smaller, but not wider. Any thoughts? I have a test page going here: http://kthornbloom.com/K – kthornbloom Apr 01 '11 at 03:38
  • In my previous post i told you to use Math.round. Make sure it's used with parseInt. So it looks like `Math.round(parseInt(rem/2))` – Hussein Apr 01 '11 at 03:45
  • @Hussein, does using parseInt solve the Firefox problem? I guess I'm not implementing it correctly. Sorry, I'm a bit of a jQuery novice. – kthornbloom Apr 01 '11 at 13:24
  • I don't know but if you just want to change size of near divisions with best look i prefer CSS way specially using Flex. – QMaster May 08 '14 at 13:08
3

Not sure if this helps, but I discovered this fun trick. Seems to work in IE 8, IE 9, FireFox 3.6, FireFox 4, and Safari 5 (for windows, at least).

<div name="test1" id="test1" style="position:absolute; left:0px; top:95px; width:50%; height:300px; z-index:5; background: #7BCDC9;">
This starts at the left edge, and goes all the way to the middle of the screen.
</div>
<div name="test2" id="test2" style="position:absolute; left:50%; top:95px; width:50%; height:300px; z-index:5; background: #4D3627;">
Starts in the middle, and goes all the way to the right edge.
</div>

Then, add your centered div over the top (using your favorite method), using z-index:10; to make it "on top of" the other elements.

sodabob
  • 31
  • 1