chadct
chadct

Reputation: 43

Page layout two divs side by side: right scrollable only, left expandable to fit content

I am trying to build this layout

enter image description here

I want :

I have been trying for a while for the best solution, this is what I came up with so far:

<style>
    html, body {
            height: auto;
        }
        #wrapper {
            overflow: hidden;
            height: 100%;

        }
        div#banner {
            width: 35%;
            float: left;
            padding-bottom: 1000px;
            margin-bottom: -1000px;
            overflow:hidden;
            height:100%;
            background: rgba(0, 0, 0, 0.74);
            z-index: 999;


        }
        div#content {
            width: 65%;
            float: left;
            background-color: grey;
            padding-bottom: 1000px;
            margin-bottom: -1000px;
            overflow:auto;
            background: blue;
            height:100%;
            color:white;
        }
</style>
<div id="wrapper">
    <div id="banner">
      <header>
            header content
        </header>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text2<br>
    </div>
    <div id="content" style="">
        right
        text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>
    </div>
</div>

(update) https://jsfiddle.net/nze5ug5t/5/

How can I achieve this layout?

Upvotes: 2

Views: 3862

Answers (2)

tao
tao

Reputation: 90138

This cannot be done without JavaScript. You need to check and apply different CSS rules depending on viewport height, left column height, right column height and scroll position. I guess it needs further testing, but this should do the trick:

document.checkBanner = function() {
  var ch = $('.contentWrapper').innerHeight(),
    left = $('.left-banner-content'),
    lh = left.innerHeight(),
    s = $(document).scrollTop(),
    wh = $(window).height();
  if (wh > lh) {
    left.css({
      'top': s + 'px'
    })
  } else {
    if ((s + wh) > lh) {
      left.css({
        'top': (s + wh - lh - 20) + 'px'
      });
    } else {
      left.css({
        'top': 0
      });
    }
  }
  if ($(document).height() > ch) {
    $(document).scrollTop(ch - wh);
  }
}
$(document).scroll(function() {
  document.checkBanner();
});
$(document).resize(function() {
  document.checkBanner();
});
body {
  margin: 0;
}
.wrapper {
  margin: 0;
  position: relative;
}
.left-banner {
  position: absolute;
  min-height: 100%;
  height: 100%;
  width: 210px;
  background-color: rgba(0, 76, 0, .84);
  color: white;
}
.left-banner-content {
  position: relative;
  padding: 0 20px 5px;
}
.contentWrapper {
  padding-left: 210px;
  min-height: 100%;
  background-image: url(http://www.plafondchauffant.fr/modules/pm_advancedbackgroundchanger/uploads/slides/53d177879b0e2.jpg);
  -webkit-background-size: cover;
  background-size: cover;
}
.content {
  min-height: 100vh;
  background: rgba(255, 255, 255, .9);
  padding: 0 20px;
  overflow-y: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="left-banner">
    <div class="left-banner-content">
      <h3>This is left banner</h3>
      <ul>
        <li>some item</li>
        <li>some other item</li>
        <li>yet another item</li>
        <li>and another one</li>
        <li>...</li>
        <li>this is getting boring</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
        <li>...</li>
      </ul>
    </div>
  </div>
  <div class="contentWrapper">
    <div class="content">
      <h1>This is content</h1>
      <p>Ennui pinterest kogi freegan +1, try-hard leggings pickled chillwave chartreuse raw denim 8-bit brooklyn. Cardigan sustainable marfa bitters vice. Humblebrag everyday carry leggings, shoreditch cold-pressed tacos before they sold out gastropub sriracha
        master cleanse distillery migas. Helvetica seitan humblebrag, jean shorts godard organic affogato. Mlkshk XOXO bicycle rights four dollar toast letterpress fap pitchfork salvia, forage meditation irony knausgaard next level. Pabst kogi echo park
        YOLO. Williamsburg ugh drinking vinegar messenger bag offal selvage.</p>

      <p>Actually selvage before they sold out, affogato dreamcatcher squid taxidermy chia cornhole deep v ethical meggings quinoa. Four dollar toast retro green juice, ramps squid truffaut etsy williamsburg artisan. Everyday carry ennui bicycle rights sustainable
        twee, umami portland cornhole blue bottle street art. 90's meh kale chips kitsch. Ennui tattooed pour-over, whatever small batch ethical disrupt YOLO four dollar toast echo park cronut keytar selvage tacos. You probably haven't heard of them master
        cleanse meditation single-origin coffee, ramps trust fund viral pitchfork letterpress yuccie marfa etsy. Keffiyeh mustache ramps put a bird on it slow-carb keytar.</p>

      <p>Locavore kickstarter freegan, pinterest authentic celiac portland four dollar toast affogato cray kogi hashtag direct trade. Dreamcatcher 90's trust fund, occupy fap fanny pack irony shoreditch readymade austin. Asymmetrical aesthetic iPhone, wayfarers
        try-hard dreamcatcher gluten-free kinfolk williamsburg hammock mumblecore sriracha. Migas farm-to-table pickled disrupt, plaid actually four loko bicycle rights vegan try-hard ramps banh mi. Trust fund portland intelligentsia organic. Etsy thundercats
        blue bottle, sartorial taxidermy hella fap flannel kogi seitan echo park. Drinking vinegar paleo pop-up synth roof party food truck.</p>

      <p>Cronut mixtape +1 YOLO helvetica bicycle rights. Offal polaroid authentic mixtape vinyl. Quinoa ramps banh mi ethical, banjo XOXO cornhole asymmetrical tumblr direct trade artisan salvia. Kitsch drinking vinegar gentrify tousled salvia, schlitz
        before they sold out slow-carb gluten-free. Offal viral pork belly plaid wayfarers single-origin coffee, green juice lo-fi kogi cardigan. Sartorial forage ugh pork belly, viral direct trade hashtag austin cronut celiac letterpress helvetica franzen
        chillwave. Vice chicharrones artisan next level pickled seitan.</p>
    </div>
  </div>
</div>


UPDATE: After fiddling with the rendering problems behind such a solution I realized there's no way someone didn't already code something similar. And I was right: here's lockfixed. Nicely wrapped as a jquery plugin. You should have googled your problem first :).

Cheers!

Upvotes: 2

Will
Will

Reputation: 453

Any answer to your question will be heavily dependent on where all these elements will be living. However, is this what you're trying to achieve?

https://jsfiddle.net/efpygvxq/1/

The CSS is below. the HTML is too long. The salient point here is to make use of position: absolute with top: x; right: x; bottom: x; left: x and specify overflow-x and overflow-y behaviors.

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  font-family: arial;
}
.header {
  padding: 1rem;
  font-weight: bolder;
}
.wrapper {
  position: absolute;
  top: 10%;
  right: 0;
  bottom: 0;
  left: 0;
  border: 1px solid black;
}
.menu {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 20%;
  border: 1px solid green;
  overflow-x: hidden;
  overflow-y: scroll;
}
.menu-item {
  margin: 1rem;
  padding: 0.5rem;
}
.menu-item:hover {
  color: white;
  background-color: #505050;
}
.content {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 20%;
  border: 1px solid blue;
  overflow-y: scroll;
}
.content p {
  margin: 1rem;
}

Upvotes: 0

Related Questions