htmlcssgridcss-position

How to set absolute element inside display grid correctly?


I have below code snippet, what I want to achieve is that .child which is panel should not be shown, to the top of .content class, however, .child is setting at top of .data class. I don't understand why this is happening.

According to my understanding, absolute element takes boundary of nearest relative element, which is .content in my case. Still my .child element is taking top value from .data class. I don't understand why.

Is there something I am doing wrong here, if yes how can I achieve below case, what I want to do is that no matter how much we have scrolled, I want panel to be shown always in visible screen area of .content element.

.main {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto minmax(0, 100%);
  grid-template-areas: "header" "menu" "content";
  height: 75vh;
}

.header {
  grid-area: header;
}

.menu {
  grid-area: menu;
}

.content {
  grid-area: content;
  overflow-y: auto;
  background-color: #f5f5f5;
  position: relative;
}

.child {
  position: absolute;
  top: 0;
  right: 0;
  width: 40%;
  background-color: aqua;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "head" "body" "footer";
  height: 100%;
}

.child .head {
  grid-area: head;
  background-color: red;
}

.child .body {
  grid-area: body;
  overflow-y: scroll;
}

.child .footer {
  grid-area: footer;
  background-color: red;
}

.data {
  position: relative;
  margin-bottom: 15px;
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
}

.btn {
  display: block;
  margin-block: 15px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>HTML + CSS</title>
  <link rel="stylesheet" href="styles.css" />
</head>

<body>
  <div class="main">
    <section class="header">This is header</section>
    <section class="menu">This is menu</section>
    <section class="content">
      <div class="data">
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
      </div>
      <div class="child">
        <div class="head">child head</div>
        <div class="body">
          vel fermentum ligula pellentesque sed. Nam nibh ex, placerat sed finibus non, bibendum id mauris. Phasellus porta felis velit, vel fringilla tellus condimentum quis. Ut sollicitudin venenatis nulla vel maximus. Suspendisse rutrum nibh ut est tempus, a
          pretium ex bibendum. Phasellus euismod sagittis massa at hendrerit. Nam eget maximus nisi. Quisque convallis, magna id lobortis consectetur, magna libero mollis lorem, sed cursus diam est nec felis. Sed ultricies leo nec lacinia mattis. Donec
          tincidunt sodales mi, id fringilla lectus dignissim quis. Donec enim enim, tincidunt nec ante eu, mollis cursus justo. Cras dictum diam non nibh tristique, vel convallis mauris varius. Aenean blandit massa erat, vitae hendrerit purus finibus
          a. Aenean tempor pellentesque ligula, ut lobortis quam eleifend et. Praesent convallis efficitur porta. Pellentesque rutrum maximus diam, et volutpat ligula ornare vitae.
        </div>
        <div class="footer">child footer</div>
      </div>
    </section>
  </div>
  <script>
    const btns = document.querySelectorAll(".btn");
    const child = document.querySelectorAll(".child")[0];
    btns.forEach(function(button) {
      button.addEventListener("click", () => {
        child.style.display = child.style.display == "none" ? "grid" : "none";
      });
    });
  </script>
</body>

</html>

const btns = document.querySelectorAll(".btn");
const child = document.querySelectorAll(".child")[0];
btns.forEach(function(button) {
  button.addEventListener("click", () => {
    const isVisibleLastTime = child.style.display == "grid"
    child.style.display = !isVisibleLastTime ? "grid" : "none";
    // Work around solution
    if (!isVisibleLastTime) {
      const content = document.querySelectorAll(".content")[0]
      content.scrollTop = 0 // I am manually setting scroll position to top 0
    }
    btns.forEach(b => UpdateAllButtonText(b, isVisibleLastTime))
  });
});

function UpdateAllButtonText(btn, isVisible) {
  btn.textContent = !isVisible ? "Hide Panel" : "Show Panel"
}
.main {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto minmax(0, 100%);
  grid-template-areas: "header" "menu" "content";
  height: 75vh;
}

.header {
  grid-area: header;
}

.menu {
  grid-area: menu;
}

.content {
  grid-area: content;
  overflow-y: auto;
  background-color: #f5f5f5;
  position: relative;
}

.child {
  position: absolute;
  top: 0;
  right: 0;
  width: 40%;
  background-color: aqua;
  display: none;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "head" "body" "footer";
  height: 100%;
}

.child .head {
  grid-area: head;
  background-color: red;
}

.child .body {
  grid-area: body;
  overflow-y: scroll;
}

.child .footer {
  grid-area: footer;
  background-color: red;
}

.data {
  position: relative;
  margin-bottom: 15px;
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
}

.btn {
  display: block;
  margin-block: 15px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>HTML + CSS</title>
  <link rel="stylesheet" href="styles.css" />
</head>

<body>
  <div class="main">
    <section class="header">This is header</section>
    <section class="menu">This is menu</section>
    <section class="content">
      <div class="data">
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
        <button class="btn">showPanel</button>
      </div>
      <div class="child">
        <div class="head">child head</div>
        <div class="body">
          vel fermentum ligula pellentesque sed. Nam nibh ex, placerat sed finibus non, bibendum id mauris. Phasellus porta felis velit, vel fringilla tellus condimentum quis. Ut sollicitudin venenatis nulla vel maximus. Suspendisse rutrum nibh ut est tempus, a
          pretium ex bibendum. Phasellus euismod sagittis massa at hendrerit. Nam eget maximus nisi. Quisque convallis, magna id lobortis consectetur, magna libero mollis lorem, sed cursus diam est nec felis. Sed ultricies leo nec lacinia mattis. Donec
          tincidunt sodales mi, id fringilla lectus dignissim quis. Donec enim enim, tincidunt nec ante eu, mollis cursus justo. Cras dictum diam non nibh tristique, vel convallis mauris varius. Aenean blandit massa erat, vitae hendrerit purus finibus
          a. Aenean tempor pellentesque ligula, ut lobortis quam eleifend et. Praesent convallis efficitur porta. Pellentesque rutrum maximus diam, et volutpat ligula ornare vitae.
        </div>
        <div class="footer">child footer</div>
      </div>
    </section>
  </div>
</body>

</html>


Solution

  • Change the .child's position to sticky and add bottom and left to stick it to the place you want:

    .main {
      display: grid;
      grid-template-columns: 1fr;
      grid-template-rows: auto auto minmax(0, 100%);
      grid-template-areas: "header" "menu" "content";
      height: 75vh;
    }
    
    .header {
      grid-area: header;
    }
    
    .menu {
      grid-area: menu;
    }
    
    .content {
      grid-area: content;
      overflow-y: auto;
      background-color: #f5f5f5;
      position: relative;
    }
    
    .child {
      position: sticky;
      bottom: 0;
      left: 60%;
      width: 40%;
      background-color: aqua;
      display: grid;
      grid-template-columns: 1fr;
      grid-template-rows: auto 1fr auto;
      grid-template-areas: "head" "body" "footer";
      height: 100%;
    }
    
    .child .head {
      grid-area: head;
      background-color: red;
    }
    
    .child .body {
      grid-area: body;
      overflow-y: scroll;
    }
    
    .child .footer {
      grid-area: footer;
      background-color: red;
    }
    
    .data {
      position: relative;
      margin-bottom: 15px;
      display: flex;
      flex-wrap: wrap;
      gap: 15px;
    }
    
    .btn {
      display: block;
      margin-block: 15px;
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta http-equiv="X-UA-Compatible" content="ie=edge" />
      <title>HTML + CSS</title>
      <link rel="stylesheet" href="styles.css" />
    </head>
    
    <body>
      <div class="main">
        <section class="header">This is header</section>
        <section class="menu">This is menu</section>
        <section class="content">
          <div class="data">
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
            <button class="btn">showPanel</button>
          </div>
          <div class="child">
            <div class="head">child head</div>
            <div class="body">
              vel fermentum ligula pellentesque sed. Nam nibh ex, placerat sed finibus non, bibendum id mauris. Phasellus porta felis velit, vel fringilla tellus condimentum quis. Ut sollicitudin venenatis nulla vel maximus. Suspendisse rutrum nibh ut est tempus, a
              pretium ex bibendum. Phasellus euismod sagittis massa at hendrerit. Nam eget maximus nisi. Quisque convallis, magna id lobortis consectetur, magna libero mollis lorem, sed cursus diam est nec felis. Sed ultricies leo nec lacinia mattis. Donec
              tincidunt sodales mi, id fringilla lectus dignissim quis. Donec enim enim, tincidunt nec ante eu, mollis cursus justo. Cras dictum diam non nibh tristique, vel convallis mauris varius. Aenean blandit massa erat, vitae hendrerit purus finibus
              a. Aenean tempor pellentesque ligula, ut lobortis quam eleifend et. Praesent convallis efficitur porta. Pellentesque rutrum maximus diam, et volutpat ligula ornare vitae.
            </div>
            <div class="footer">child footer</div>
          </div>
        </section>
      </div>
      <script>
        const btns = document.querySelectorAll(".btn");
        const child = document.querySelectorAll(".child")[0];
        btns.forEach(function(button) {
          button.addEventListener("click", () => {
            child.style.display = child.style.display == "none" ? "grid" : "none";
          });
        });
      </script>
    </body>
    
    </html>

    Edit: to answer your additional questions in the comment:

    "Why setting right:0 is not working why we have to make left:60%"

    In position: absolute case, right: 0 means "make the distance between my right edge and my closest positioned ancestor's right edge exactly 0, but don't response to scrolling". When we change to position: sticky, right: 0 changes its meaning to "keep the distance between my right edge and my nearest scrolling ancestor's right edge no less than 0, and keep adjusting while scrolling". Since .child's original place is the bottom left corner, the distance between its right edge and .content's right edge was already greater than 0, it will stay where it is. That why we need left instead.

    Why you have removed display:grid from .content class

    I think there's some confusion here. In your original code, there's no display:grid in .content class?