0

I have a container which wraps around three floated containers, the wrapping container has a variable width and the left most inner container has a width of 100px and the right most inner container has a width of 500px. The center container does not have a set width, but should take up as much space as possible that remains.

<style type="text/css">
    #outerContainer div:nth-child(1) {float: left; width: 100px}
    #outerContainer div:nth-child(2) {float: left}
    #outerContainer div:nth-child(3) {float: right; width: 500px}
</style>

<div id="outerContainer">
    <div>left most inner container</div>
    <div>center container</div>
    <div>right most inner container</div>
</div>

The dynamic center container has a few styles applied to it which make it's content overflow: hidden and ellipsis for presentation purposes.

<style type="text/css">
#outerContainer div:nth-child(1) {
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
}
</style>

I'm not sure what the solution is to dynamically scale the width of this inner element using ONLY css. Here's my JavaScript solution which works, but I'd like to cut it out as it seems excessive.

NS.textWidth = function(sourceSel){
    var sourceSel = sourceSel,
        html_org = $(sourceSel).html(),
        html_calc = '<span>' + html_org + '</span>';

    //Wrap contents with a span.
    $(sourceSel).html(html_calc).css({width:'100%'});
    //Find width of contents within span.
    var width = $(sourceSel).find('span:first').width();

    //Replace with original contents.
    $(sourceSel).html(html_org);

    return width;
};

adjustContainerWidth();

$(window).bind('resize', function(e){
    clearTimeout(c.resize_timeout);

    c.resize_timeout = setTimeout(function() {
        adjustContainerWidth();
    }, 200);
});

function adjustContainerWidth() {
    var winW = parseInt($(window).width());
    var firstContainer = parseInt($('#outerContainer div:nth-child(1)').width());
    var lastContainer = parseInt($('#outerContainer div:nth-child(3)').width());
    var availW = winW - firstContainer - lastContainer;
    var textW = NS.textWidth('#outerContainer div:nth-child(2)');

    if (availW > 40 && availW < textW) {
        $('#outerContainer div:nth-child(1)').css({ width : availW + 'px' });
    } else {
        $('#outerContainer div:nth-child(1)').css({ width : textW + 'px' });
    }
}
  • Are you trying to find a *better* JavaScript solution, or a CSS-only solution? Can you make a http://jsfiddle.net/ demo showing what you have so far? – thirtydot Apr 23 '12 at 21:25
  • A lot of the code mentioned here is snippets from a much larger project, I'll see what I can do about making a jsfiddle for it. Also, CSS-only is my preferred method of tackling this. –  Apr 23 '12 at 23:11

2 Answers2

0

This is, currently, untested but I think the following should work. Effectively find the width of the parent, the width of the siblings and then subtract one from the other:

var that = $(this),
    parentWidth = that.parent().width(),
    siblingsWidth = 0;

that.siblings().each(
    function(){
        siblingsWidth += $(this).outerWidth();
    });

that.width(parentWidth - siblingsWidth);

JS Fiddle demo.

I've made the #outerContainer element 1000px wide, just to ensure that all elements have space to fit side-by-side in the demo.

I've also corrected your CSS a little; CSS is one-based, not zero-based like programming languages. So #outerContainer div:nth-child(0) wasn't matching, or styling, any elements.

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • Thanks, this is a nicer JS implementation; however, I'd prefer a CSS only one. Also, Thanks for pointing out the 1 based array, I'm not actually using CSS3 for my project, that was just easier to type up for the purpose of this question. –  Apr 23 '12 at 23:09
0

pure css http://jsfiddle.net/Za8RF/

Gwyn Howell
  • 5,365
  • 2
  • 31
  • 48
  • Is there a way you can think of about making the center div drop off once it hits a certain width, say 40px? –  Apr 23 '12 at 23:12
  • what do you mean by drop off? as in its maximum width should be 40px? if so, should it right or left align? – Gwyn Howell Apr 24 '12 at 06:37
  • By drop off, I mean drop below or hide or something like that. Basically I want it to truncate down to a certain point — say 40px width — and then act as if it were a block element and break below. –  Apr 24 '12 at 19:35