2

I'm trying to make a a page container with a navigation bar on the left (inside of the container). When the outer page is wider than the container, I would like just the navigation bar to extend left up to a certain size while the rest of the container's contents to remain the same and stay in the middle of the outer page.

To illustrate my idea, here are the before and after images, with black representing the outer page, blue the page container, pink the leftnav, and green the rest of the container. Before large screenAfter large screenAfter large screen Here is also the general structure of the code I am writing. The jsfiddle link includes some css for detail.

<div id="page">
<div id="container">
    <div id="leftCol">
        LEFT
    </div>
    <div id="rightCol">
        RIGHT
    </div>
</div>

https://jsfiddle.net/6L1zrj6e/1/

Currently, my container has a fixed width and automatic margins so as to center it. Is what I am trying to achieve even possible with the current layout? Would I need to move the leftnav div outside of the container?

Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
QuantumRich
  • 886
  • 2
  • 9
  • 21
  • I can't seem to come up with a pure css solution. However this can be done using CSS3 `calc()` or with a simple javascript window resize event handler. Are these options okay with you? – Yotam Omer Jun 22 '15 at 13:53
  • Yes, I am totally fine with not just using css! I would prefer the calc() option, but if it is too complicated anything is fine. – QuantumRich Jun 22 '15 at 13:54
  • @QuantumRich, your pics imply that you want the left col to overlap the container div, but this seems odd. Can you clarify that? If that's not your intention then it's pretty simple to achieve in pure css. – beercohol Jun 22 '15 at 14:26
  • @beercohol My intention was to have the leftnav shown on top of everything, regardless of the layout. – QuantumRich Jun 22 '15 at 14:36
  • OK I'm not sure what you mean by "on top"... In your example your left and right cols are next to each other, and the only thing they're on top of is the container... I'm gonna post an answer based on what I think you mean, you can bash me if I'm wrong! – beercohol Jun 22 '15 at 14:44
  • I removed my proposed answer. I thought you wanted to have the left nav on the side of the main content, not overlapping it. – JeffT Jun 22 '15 at 14:48
  • @JeffT Actually, no you were fine. Your answer was almost what I wanted. The only thing is I want the right side's "page" to be expanding even as the leftnav is expanding to its full size (aka the black in my example picture to show on the right even though it has not shown on the left yet). – QuantumRich Jun 22 '15 at 15:19
  • Hi Rich, I'm still finding those pics a bit confusing - please see my updated answer, although the example only gives you a right margin, as you asked. (with a note as to how to make left/right even). The updated pic looks like you actually do want even left/right margins? – beercohol Jun 22 '15 at 15:29
  • @Rich. Ok, I undelete it then, but I'm not 100% sure to understand what you're after ;) – JeffT Jun 22 '15 at 15:53

5 Answers5

2

Here's a pure css solution: fiddle

This is a trick I learned here: here where you have to put the float first, then make the div respect it by creating a new block formatting context, then the div will expand to the remaining space. Throw in a couple min/max widths to conform it and a wrapper with min/max widths as well and it falls into place. The html background makes the body background not extend past the body as it normally would. Another little trick.

    <div class="wrap">
        <main></main>
        <nav></nav>
    </div>

    html {
        background: white;
    }
    body {
        background: purple;
        padding: 0;
        margin: 0;
    }
    .wrap {
        margin: 0 auto;
        max-width: 1080px;
        min-width: 920px;
    }
    nav {
        overflow: auto; /* force a new context to respect float */
        background: red;
        height: 300px;
        min-width: 200px;
        max-width: 360px;
    }
    main {
        float: right;
        background: green;
        height: 300px;
        width: 720px;
    }
Community
  • 1
  • 1
Dan Kahle
  • 21
  • 3
1

You can try the following: Full screen example

jsFiddle

HTML: (Took leftCol out of container)

<div id="page">
    <div id="leftCol">
            LEFT
        </div>
    <div id="container">       
        <div id="rightCol">
            RIGHT
        </div>
    </div>
</div>

JS: (Update the width on page resize and on load)

$(window).on('resize', function(){
    var containerWidth = 980;
    var pageWidth = $(window).width();

    var tempW = Math.max(0, pageWidth-containerWidth) / 2;
    tempW  += 200;
    var w = Math.min(tempW, 360); // 360 = max width
    var l = Math.max(0, tempW - w);
    $('#leftCol').css({'width': w+'px', 'left': l+'px'});
}).resize();

CSS: (Removed floats, using absolute position for leftCol)

#page{
    background-color: purple;
    position:relative;
}
#container {
    background-color: blue;
    width: 980px;
    height: 300px;
    margin: 0 auto;
}
#leftCol {
    position:absolute;
    top: 0;
    left: 0;
    background-color: red;
    height: 300px;
    width: 200px;
}
#rightCol {
    padding-left:200px;
    background-color: green;
    height: 300px;
    width: auto;
}
Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
1

This is what I think you're after - forgive me if I'm wrong!

EDIT: Added outer container wrapper for right margin:

Updated HTML:

<div id="page">
    <div id="outercontainer">
    <div id="container">
        <div id="leftCol">
            LEFT
        </div>
        <div id="rightCol">
            RIGHT
        </div>
    </div>
    </div>
</div>

And the CSS:

#page{
    background-color: purple;
    height: 300px;
}
#outercontainer {
    margin: 0 5% 0 0;
}
#container {
    background-color: blue;
    height: 300px;
    margin: 0 auto;
    min-width: 300px;
    max-width: 600px;
    position: relative;
}
#leftCol {
    background-color: red;
    height: 300px;
    margin-right: 200px;
}
#rightCol {
    position: absolute;
    background-color: green;
    width: 200px;
    top: 0;
    right: 0;
    bottom: 0;
}

This gives the #container a min and max width, and the margins will show beyond the max. These are set quite small to show up well in JSFiddle.

leftCol will expand to fit the available space, and it's right-margin prevents it overflowing the rightCol.

rightCol is absolutely positioned (within #container) in the leftCol's margin.

JSFiddle here: https://jsfiddle.net/xuew6og5/1/

The #outerwrapper allows a visible right margin, until the page gets to minimum width at least. If you want the margins to be balanced, change its margin to 0 5%

Update: New JS Fiddle with right margin: https://jsfiddle.net/xuew6og5/2/

Update 3: Sorry, I missed your requirement for a max-width of 360px on the leftCol. Updated the CSS above, and a fiddle here: https://jsfiddle.net/xuew6og5/4/

beercohol
  • 2,577
  • 13
  • 26
  • Edit: Updated bad JSFiddle link! – beercohol Jun 22 '15 at 14:52
  • This is almost what I would like, it's just that I want the right side's "page" to be expanding even as the leftnav is expanding to its full size (aka the purple to show on the right even though it has not shown on the left yet). – QuantumRich Jun 22 '15 at 15:03
  • OK, I understand. That requires an outer wrapper with it's own margin. I've updated my answer accordingly. – beercohol Jun 22 '15 at 15:20
  • Is it possible to have the right margin be the same size as how much bigger the leftnav is than its original size? (so as to make the point where the leftnav and the rightCol touch each other virtually stay at the same spot in the container?) at least until the leftnav reaches its full size. – QuantumRich Jun 22 '15 at 15:43
  • Yes, possibly. It depends on a few things though - do you want a left margin to appear ever? If so at what point? At the moment, the "meeting point" of the left and right stays fairly static until the document exceeds the max-width, at which point everthing becomes centered within the margins. – beercohol Jun 22 '15 at 15:48
  • The left margin should appear once the leftnav reaches full size. The left and right margins should not be equal ever really - the left margin should be smaller (less wide i.e.) by however much larger the leftnav is from its min width. – QuantumRich Jun 22 '15 at 15:55
  • Rich, please see my updated answer with a max-width of 360px on the leftCol. – beercohol Jun 22 '15 at 16:19
  • it is almost there, and I would prefer your css solution because it would load more responsively. It seems like it works when the leftnav has reached its max size. However, the right purple always seems to be the same size during the "expansion" transition. – QuantumRich Jun 22 '15 at 20:01
  • The right purple margin does grow somewhat during the "expansion" stage, but not much, as it's set to 5%. This is the only way I know to get it to move a bit, as you can't simply use "auto" here. I suggest you play around with that value and see if it works for you. I don't know of a way to get that margin to grow equally to the leftCol until max-width is reached. – beercohol Jun 22 '15 at 20:47
0

In order to achieve the wanted effect you need to move the leftCol outside of your container and give your rightCol a margin-left with the size of your leftCol.

Also add a min-width and max-width to your lefCol and a width using calc to adjust it's width to your goals.

Note: lefCol width is calculated like this:

100% / 2 - (Container width / 2 - leftCol min-width)

So your altered html looks like this:

<div id="page">
    <div id="leftCol">
        LEFT
    </div>
    <div id="container">
        <div id="rightCol">
            RIGHT
        </div>
    </div>
</div>

Your new CSS looks like this:

#page{
    background-color: purple;
}
#container {
    background-color: blue;
    width: 300px;
    height: 300px;
    margin: 0 auto;
}
#leftCol {
    float: left;
    background-color: red;
    height: 300px;
    min-width:100px;
    width:calc(100%/2 - 50px);
    max-width:200px;
}
#rightCol {
    margin-left:100px;
    background-color: green;
    height: 300px;
    width: 200px;
}

Take a look at the updated example:

https://jsfiddle.net/xxyv7nwf/2/

  • I edited the answer in order to take care of the variable width for `leftCol`. But apart from that i think the solution works pretty well for what the OP requested. – Jörg Bayreuther Jun 22 '15 at 14:19
  • I'm sorry if I wasn't clear, but I wanted the leftnav to the stick next to the content even as it got bigger. – QuantumRich Jun 22 '15 at 15:08
0

CSS solution using CSS3 calc. Edited. According to OP updates.

@media screen and (min-width: 1600px)  {
            #container{
                margin:0 auto;          
          }

        }
        body {
            overflow-x:hidden;
        }
        #page{
            background-color: purple;
            height:300px;

        }
        #container{
            background-color: blue;
            min-width:980px;
            max-width: 1140px;

        }

        #leftCol {
            float: left;
            background-color: red;
            height: 300px;
            width: calc(100% - 780px);
        }
        #rightCol {
            float: left;
            background-color: green;
            height: 300px;
            width: 780px;
        }

HTML

        <div id="page">
        <div id="container">
            <div id="leftCol">
                LEFT
            </div>
            <div id="rightCol">
                RIGHT
            </div>
        </div>
    </div>
JeffT
  • 145
  • 1
  • 8
  • I would like the purple to appear on the right side once the red leftCol starts expanding and expand at the same pace as the red as the screen size grows. You can use Yotam's example (final version) for a js example. – QuantumRich Jun 22 '15 at 20:05