问题
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:
I made the
ul
grid item a flex container withflex-direction: column
andjustify-content: flex-end
.I made the
ul
grid item a flex container withflex-direction: column
and appliedmargin-top: auto
to the firstli
flex item.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