0
<div class="grid">
  <div class="grid__item topbar"></div>
  <div class="grid__item title"></div>
  <div class="grid__item box1"></div>
  <div class="grid__item box2"></div>
  <div class="grid__item box3"></div>
  <div class="grid__item box4">
    <button class="add-content-btn">Add content</button>
    <p>Dynamic content</p>
  </div>
  <div class="grid__item sidebar">
    <button class="add-content-btn">Add content</button>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
    <p>Dynamic content</p>
  </div>
</div>

body {
  padding: 16px;
}

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-areas: 
    "topbar topbar"
    "title  sidebar"
    "box1   sidebar"
    "box2   sidebar"
    "box3   sidebar"
    "box4   sidebar";
  grid-template-columns: 70% 30%;
  grid-template-rows: 28px 30px 500px 50px 20px auto;
}

.grid__item {
  border: 1px solid black;
}

.topbar {
  grid-area: topbar;
}

.title {
  grid-area: title;
}

.box1 {
  grid-area: box1;
}

.box2 {
  grid-area: box2;
}

.box3 {
  grid-area: box3;
}

.box4 {
  grid-area: box4;
  padding: 10px;
}

.sidebar {
  grid-area: sidebar;
  overflow: scroll;
  padding: 10px;
}

const btns = document.querySelectorAll('.add-content-btn');
btns.forEach(btn => {
  btn.addEventListener('click', e => {
    const parent = e.target.parentElement;
    for (let i = 0; i < 3; i++) {
      const newLine = document.createElement('p');
      newLine.innerText = 'Dynamic content';
      parent.append(newLine);
    }
  });
})

http://codepen.io/dye/pen/YVyoVd

In this layout, I have 2 columns that can each grow in size. I want the height of the right column to be controlled by the height of the left column, but not the other way around.

Clicking the "Add content" button in the bottom left box will grow the left column as well as the right column. That works as intended.

At the moment, clicking the "Add content" button in the right column will grow the left column. This is unintended. I would like the height of the right column to be at most the height of the left column, and have content inside be scrollable. Is this possible with CSS grid or do I need to use JS?

2
  • 1
    you can try max-height and overflow, but specification are unclear about this and firefox will show the scroll where chrome will not codepen.io/gc-nomade/pen/Wjryym you should relay on javascript or use an extra element set in absolute position within sidebar codepen.io/gc-nomade/pen/JNGZwW Is this your answer ? Commented Apr 19, 2017 at 20:40
  • The buffer solution looks great. I'll look into that. Thanks! Commented Apr 19, 2017 at 20:47

1 Answer 1

1

you may use an extra wrapper in absolute position to avoid interaction with the original layout.

const btns = document.querySelectorAll('.add-content-btn');
btns.forEach(btn => {
  btn.addEventListener('click', e => {
    const parent = e.target.parentElement;
    for (let i = 0; i < 3; i++) {
      const newLine = document.createElement('p');
      newLine.innerText = 'Dynamic content';
      parent.append(newLine);
    }
  });
})
body {
  padding: 16px;
}

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-areas: "topbar topbar" "title  sidebar" "box1   sidebar" "box2   sidebar" "box3   sidebar" "box4   sidebar";
  grid-template-columns: 70% 30%;
  grid-template-rows: 28px 30px 500px 50px 20px auto;
}

.grid__item {
  border: 1px solid black;
}

.topbar {
  grid-area: topbar;
}

.title {
  grid-area: title;
}

.box1 {
  grid-area: box1;
}

.box2 {
  grid-area: box2;
}

.box3 {
  grid-area: box3;
}

.box4 {
  grid-area: box4;
  padding: 10px;
}

.sidebar {
  grid-area: sidebar;
  position: relative;
}

.buffer {
  padding: 10px;
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  overflow:auto;
}
<div class="grid">
  <div class="grid__item topbar"></div>
  <div class="grid__item title"></div>
  <div class="grid__item box1"></div>
  <div class="grid__item box2"></div>
  <div class="grid__item box3"></div>
  <div class="grid__item box4">
    <button class="add-content-btn">Add content</button>

    <p>Dynamic content</p>
  </div>
  <div class="grid__item sidebar">
    <div class="buffer">
      <button class="add-content-btn">Add content</button>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
      <p>Dynamic content</p>
    </div>
  </div>
</div>


from my comment:

you can try max-height and overflow, but specification are unclear about this and firefox will show the scroll where chrome will not http://codepen.io/gc-nomade/pen/Wjryym

You should relay on javascript or use an extra element set in absolute position within sidebar http://codepen.io/gc-nomade/pen/JNGZwW

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.