mattyniner
mattyniner

Reputation: 1

vertically distributing divs in a responsive site

first-time poster - I'll try to fit in :) I have a div on the left of my page at width 75% and a sidebar on the right with four divs in a vertical column. I would like those sidebar divs distributed evenly with the height of the main div, as the window resizes. Obviously, as it does so, the main div's content will dictate that height.

I have managed this with the below script. I don't know if it is the most elegant solution, or the most sensible, but it seems to work for me!

var mrrHeight = document.getElementById('mrrBody').clientHeight;
document.getElementById("side1").style.height = (mrrHeight/4)-21 + "px";
document.getElementById("side2").style.height = (mrrHeight/4)-21 + "px";
document.getElementById("side3").style.height = (mrrHeight/4)-21 + "px";
document.getElementById("side4").style.height = (mrrHeight/4)-21 + "px";

Now I need to get it to work in a more real-time manner - at present it only works on load and the sidebar divs are the wrong size when the window is resized. Generally, that is (almost) acceptable - it works on different sized devices, but I'll look a bit silly the day someone resizes their browser window and the layout screws up. Would I use a listener, and where would I put it? I figured out that my script HAS to be after the mrrBody div.

I could probably get the right result using tables, but "In general, web developers consider table-based layout a taboo" - is that making my life unnecessarily difficult for myself? I started using divs in my site precisely to get away from my old table-based layout!

Upvotes: 0

Views: 70

Answers (3)

pizzarob
pizzarob

Reputation: 12039

You can use a flex based layout. Your 75% width container and the side bar container would live inside a wrapping container with flex properties. The side bar would also use flex properties. No JS needed. The right column items would resize based on the content of the left.

.flex-wrap {
  display: flex;
  justify-content: space-between;
}

.left {
  height: 500px;
  width: 75%;
  display: flex;
}

.left-inner {
  background: blue;
  border-radius: 6px;
  flex-grow: 1;
}

.left, .right {
  padding: 5px;
  box-sizing: border-box;
}

.right {
  flex: 1;

  display: flex;
  flex-direction: column;
}

.side-content-box {
  flex-grow: 1;
  padding: 5px;
  box-sizing: border-box;
  display: flex;
}

.inner {
  border-radius: 6px;
  background-color: #fff;
  box-shadow: 0 0 8px #000;
  flex-grow: 1;
}
<div class="flex-wrap">
  <div class="left">
    <div class="left-inner">
    hi
    </div>
  </div>
  <div class="right">
    <div class="side-content-box">
     <div class="inner"></div>
    </div>
    <div class="side-content-box">
      <div class="inner"></div>
    </div>
    <div class="side-content-box">
      <div class="inner"></div>
    </div>
    <div class="side-content-box">
      <div class="inner"></div>
    </div>
  </div>
</div>

Upvotes: 0

Michael Coker
Michael Coker

Reputation: 53684

You can use a flex column layout for this, and set the divs you want to be evenly distributed to flex: 1 0 0 so they will flex-grow to fill the parent.

* {margin:0;}
  
aside {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 25vw;
}

aside > div {
  flex: 1 0 0;
  background: #09c;
  border-bottom: 1px solid white;
}
<aside>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</aside>

Upvotes: 0

Blue Boy
Blue Boy

Reputation: 610

You can use the window.onresize event:

window.onresize = function(event) {
    var mrrHeight = document.getElementById('mrrBody').clientHeight;
    document.getElementById("side1").style.height = (mrrHeight/4)-21 + "px";
    document.getElementById("side2").style.height = (mrrHeight/4)-21 + "px";
    document.getElementById("side3").style.height = (mrrHeight/4)-21 + "px";
    document.getElementById("side4").style.height = (mrrHeight/4)-21 + "px";
};

Upvotes: 1

Related Questions