Scroll doesn't work when grid item aligned to the end / bottom

天大地大妈咪最大 提交于 2020-02-04 01:19:06

问题


I want to create a chat using CSS grid and ran into the problem that I cannot combine align-self: end; and overflow-y: auto;.

The ul holds all the messages and should be aligned to the bottom, so that even when there is only one message, it appears on the bottom.

The header and the footer of the chat are fixed and you only scroll through the messages (like Whats App and similar applications).

I created this pen with some messages. The messages go through the header and it never allows me to scroll.

html,
body {
  margin: 0;
  height: 100%;
}

#chat {
  display: grid;
  height: inherit;
  grid-template-rows: 50px auto 50px;
}

header,
footer {
  background: #4081ff;
}

ul {
  overflow-y: auto;
  align-self: end;
}
<section id="chat">
  <header>header</header>
  <ul>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>last message</li>
  </ul>
  <footer>footer</footer>
</section>

回答1:


My solution with scrollbar. I added additional div.

https://codepen.io/anon/pen/zWaRJY

<section id="chat">
  <header>header</header>
  <div id="content">
  <ul>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>last message</li>
  </ul>
  </div>
  <footer>footer</footer>
</section>

html, body {
  margin: 0;
  height: 100%;
}

#chat {
  display: grid;
  height: inherit;
  grid-template-rows: 50px auto 50px;
}

header, footer {
  background: #4081ff;
}

#content {
  overflow-y: auto;
}

ul {
  display: flex;
  flex-direction: column;
  justify-content: end;
  min-height: 100%;
  margin: 0;
}



回答2:


This appears to be a bug.

Analysis

You are using align-self: end to pin the middle grid item (ul) to the bottom of the row. That fails to render a vertical scrollbar.

I tried various alternatives:

  1. I made the ul grid item a flex container with flex-direction: column and justify-content: flex-end.

  2. I made the ul grid item a flex container with flex-direction: column and applied margin-top: auto to the first li flex item.

  3. I tried switching from

    grid-template-rows: 50px auto 50px
    

    to

    grid-template-rows: 50px 1fr 50px
    

Nothing worked. In all cases, the browser failed to generate a vertical scrollbar.

However, in all cases, when there is no "end" alignment (in other words, the grid item is aligned to the default "start" position), vertical scroll works fine.

Because the scrollbar works in "start" but fails in "end", I think it's fair to call this a bug.

Here's the same problem in flexbox: Can't get vertical scrollbar with justify-content: flex-end


Solution #1: Chrome only

If you make the ul grid item a (nested) grid container with align-content: end, that seems to work in Chrome, but not Firefox and Edge. I didn't test in Safari, IE11 or other browsers.

#chat {
  display: grid;
  height: 100vh;
  grid-template-rows: 50px 1fr 50px;
}

ul {
  overflow-y: auto;
  display: grid;
  align-content: end;
}

header,
footer {
  background: #4081ff;
}

body {
  margin: 0;
}
<section id="chat">
  <header>header</header>
  <ul>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>last message</li>
  </ul>
  <footer>footer</footer>
</section>

revised codepen


Solution #2: All browsers

This solution takes advantage of the fact that vertical scroll works fine with items in the start position. You can insert another li or, even better, a pseudo-element (as they are considered grid items when applied to grid containers). This li will be empty and set to occupy all free space, which will pin the actual items to the bottom.

#chat {
  display: grid;
  height: 100vh;
  grid-template-rows: 50px auto 50px;
}

ul {
  overflow-y: auto;
  display: grid;
  grid-template-rows: 1fr; /* applies to the first row, the only explicit row;
                              all subsequent rows, which are implicit rows, will
                              take `grid-auto-rows: auto` by default */
}

ul::before {
  content: "";
  border: 1px dashed red; /* demo only */
}

header,
footer {
  background: #4081ff;
}

body {
  margin: 0;
}
<section id="chat">
  <header>header</header>
  <ul>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>Message 1</li>
    <li>last message</li>
  </ul>
  <footer>footer</footer>
</section>

revised codepen



来源:https://stackoverflow.com/questions/49598338/scroll-doesnt-work-when-grid-item-aligned-to-the-end-bottom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!