似乎应该可以使用flexbox,但我无法弄明白。
http://codepen.io/MichaelJCole/pen/NGBVGe
目标:
这是标记:
<div id="chatBar">
<div id="chatList">
<div class="chat mine">hello world</div>
<div class="chat theirs">hello moon</div>
</div>
<input id="chatBarInput" class="form-control" type="textarea">
</div>
这就是CSS:
html, body { height: 100%; }
#chatBar {
height: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: none;
}
#chatList {
flex: 0 1 auto;
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow-y: scroll;
}
#chatBarInput {
flex: 1 0 auto;
}
.chat {
flex: none;
align-self: flex-start;
background-color: lightgreen;
}
.chat.mine {
align-self: flex-end;
background-color: pink;
}
我无法#chatBar
来&#34;挤压&#34; #chatList
没有设置高度。这是我试图通过使用flexbox避免的: - /
对不起,我是后端程序员。尝试了一堆东西,然后为CodePen削减了它。
似乎我应该能够告诉内部flexbox滚动,同时保持外部单独。我必须使用position:absolute?
答案 0 :(得分:11)
我不能让#chatBar在不设置高度的情况下“挤压”#chatList。 这是我试图通过使用flexbox来避免的。
您为所有元素设置了flex-basis
auto
。如果没有明确的高度,flex模型将自动尝试通过缩小或扩展元素来容纳可用空间内的所有内容。这就是为什么您无法让#chatList
按预期工作的原因。 div
本身以及各个聊天都在可用空间内扩展或缩小。
你应该做的就是从简单开始:
#chatBar {
height: 100%; overflow: hidden;
display: flex; flex-flow: column;
}
#chatList {
/* grow or shrink as required from flex-basis height of 20% */
flex: 1 1 20%;
display: flex; flex-direction: column;
overflow: auto;
}
/* do not grow or shrink with a flex-basis height of 80% */
#chatBarInput { flex: 0 0 80%; }
你将能够看到它正常运作。然后你可以从这里进一步。
您修改后的代码:http://codepen.io/Abhitalks/pen/ZbjNvQ/
目标:
- textarea(用于输入消息)始终保持在最低点。
- 聊天从底部开始,然后根据需要向上滚动。
- 如果您使用“Google环聊”,就像其中的消息应用程序一样。
醇>
诀窍是使用flex-direction: column-reverse
并将新消息添加到容器中,而不是附加那些消息。
我采用了我的旧答案并将布局更改为flex-model以进行此目的的演示。您可以仔细阅读代码,看看它是如何完成的。
演示小提琴:http://jsfiddle.net/abhitalks/khj4903t/
演示代码段
var btn = document.getElementById('btn'),
inp = document.getElementById('inp'),
chats = document.getElementById('chatWindow')
;
btn.addEventListener('click', postMsg);
inp.addEventListener('keyup', function(e) {
if (e.keyCode == 13) { postMsg(); }
});
function postMsg() {
var msg = inp.value,
bubble = document.createElement('div'),
p = document.createElement('p');
if (msg.trim().length <= 0) { return; }
bubble.classList.add('bubble');
bubble.classList.add('right');
p.textContent = msg;
bubble.appendChild(p);
inp.value = '';
chats.insertBefore(bubble, chats.firstChild);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
.wrap {
margin: 8px; height: 90%; width: 50%;
display: flex; flex-direction: column;
}
.container {
flex: 1 1 90%; display: flex; flex-direction: column;
background-color: #eee; border: 1px solid #ccc; overflow: auto;
}
.form { flex: 0 0 32px; display: flex; border: 1px solid #ddd; }
.form > input[type=text] { flex: 1 1 auto; border: 1px solid #eee; }
.form > input[type=button] { flex: 0 0 20%; border: 1px solid #eee; }
.bubble { flex: 1 1 auto; clear: both; } /* clear the floats here on parent */
.bubble p {
border-radius: 5px;
padding: 8px; margin: 8px 12px;
max-width: 80%; /* this will make it not exceed 80% and then wrap */
position: relative; transition: background-color 0.5s;
}
.left p { background-color: #ccc; float: left; } /* floated left */
.right p { background-color: #33c; color: #fff; float: right; } /* floated right */
/* classes below are only for arrows, not relevant */
.left p::before {
content: ''; position: absolute;
width: 0; height: 0; left: -8px; top: 8px;
border-top: 4px solid transparent;
border-right: 8px solid #ccc;
border-bottom: 4px solid transparent;
}
.right p::after {
content: ''; position: absolute;
width: 0; height: 0; right: -8px; bottom: 8px;
border-top: 4px solid transparent;
border-left: 8px solid #33c;
border-bottom: 4px solid transparent;
}
<div class="wrap">
<div id="chatWindow" class="container">
<div class="bubble left"><p>msg</p></div>
<div class="bubble left"><p>long message</p></div>
<div class="bubble right"><p>ultra long message which can wrap at eighty percent </p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>very long message</p></div>
<div class="bubble right"><p>one more message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>yet another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
</div>
<div id="inputWindow" class="form">
<input id="inp" type="text" />
<input id="btn" type="button" value="Send" />
</div>
</div>
答案 1 :(得分:1)
浏览器上的垂直滚动条存在,因为您已将height: 100%
设置为body
,而user agent stylesheet会将默认margin
应用于body
,通常是8px左右。因此,100%+ 16px启动垂直滚动。
将此添加到您的CSS:body { margin: 0; }
要将滚动条应用于内部弹性框(.chatlist
),可以进行以下两项调整:
#chatList {
flex: 0 1 75px; /* specify a height */
display: flex;
flex-flow: column nowrap;
/* justify-content: flex-end; REMOVE */
overflow-y: scroll;
}