Ayer hice una pregunta similar, pero la expliqué mal y no especifiqué mi deseo de una solución de CSS puro, que creo que debería ser posible, así que lo estoy intentando nuevamente.
Básicamente, tengo un problema en el que tengo un div de mensajes desplazables y un campo de entrada debajo de él. Cuando hago clic en un botón, me gustaría que el campo de entrada se incremente 100 píxeles, sin que la división de mensajes se desplace también.
Aquí hay un violín que demuestra el problema en su totalidad
Como puede ver, cuando hace clic en el botón "Agregar margen", la división de mensajes también se desplaza hacia arriba. Me gustaría que se quedara donde estaba. Del mismo modo, si se desplaza ligeramente hacia arriba para que solo pueda ver el penúltimo mensaje, al hacer clic en el botón se debe mantener esa posición de manera similar al hacer clic.
Lo interesante es que este comportamiento se conserva "a veces". Por ejemplo, en algunas circunstancias (que no puedo deducir del todo) se conserva la posición de desplazamiento. Solo me gustaría que se comportara constantemente como tal.
window.onload = function(e) {
document.querySelector(".messages").scrollTop = 10000;
};
function test() {
document.querySelector(".send-message").classList.toggle("some-margin");
}
.container {
width: 400px;
height: 300px;
border: 1px solid #333;
display: flex;
flex-direction: column;
}
.messages {
overflow-y: auto;
height: 100%;
}
.send-message {
width: 100%;
display: flex;
flex-direction: column;
}
.some-margin {
margin-bottom: 100px;
}
<div class="container">
<div class="messages">
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
</div>
<div class="send-message">
<input />
</div>
</div>
<button onclick="test()">add margin</button>
div
que se desplaza hacia arriba, es la altura del div que está disminuyendo. Entonces, ¿por qué es importante? Bueno, lo que significa es quescrollbar
no está ajustando su posición. La barra de desplazamiento solo recuerda su posición relativa desde la parte superior de su contenedor. Cuando la altura del div disminuye, parece que la barra de desplazamiento se desplaza hacia arriba, pero en realidad no lo es.Respuestas:
Esta es una solución divertida que te puede gustar.
Lo que sabemos sobre el div es que conserva solo la posición superior de la barra de desplazamiento, por lo que si la altura cambia por algún motivo, la barra de desplazamiento seguirá siendo la misma y esto es lo que causa su problema.
Como solución alternativa, puede voltear
.messages
180 grados usandotransform: rotate(180deg) scaleX(-1);
y voltear hacia atrás.message
para cancelar voltear el contenido, luego el div mantendrá la barra de desplazamiento inferior (que es superior) automáticamente.fuente
El comportamiento normal de la barra de desplazamiento es que esté en la parte superior, por lo que cuando lo configura en la parte inferior al cargar la página, debe mantenerlo usted mismo porque cuando el contenido a continuación lo empuja, entonces el desplazamiento div se moverá hacia la parte superior.
Entonces tengo dos soluciones para ti:
Invierta los mensajes dentro del div de mensajes para que el último mensaje sea el primero y el desplazamiento siempre esté en la parte superior.
Creé una función de JavaScript para desplazarse hasta la parte inferior de cualquier elemento, por lo que solo debe llamarla cuando quiera desplazarse hacia la parte inferior.
Revisa el fragmento
fuente
Puede hacerlo al revés, dando la altura al en
.messages
lugar de dárselo al.container
en este caso, no afectará los mensajes,div
pero si se lo da al.container
empujará su div porque el margen está dentro del principal div que tienen una altura.Mira este fragmento
fuente
.send-message
. Si miras mi pregunta anterior, esto se hace porque es similar al aumento de margen de abrir el teclado virtual en dispositivos móviles (el margen inferior es solo un reemplazo 1: 1 para depurar la solución)La solución simple es establecer lo anterior
scrollTop
en alternar. Aquí estoy usando el conjunto de datos para almacenar elscrollTop
valor anterior , puede usar la variable tampoco.fuente
Quiero decir, la siguiente es una solución única de CSS que resuelve exactamente su ejemplo:
pero no creo que te ayude con tu problema original del teclado virtual. Pero quizás esto pueda inspirar a otra persona a una solución.
El principal problema parece ser que la barra de desplazamiento ya está haciendo exactamente lo que desea:
Mantener su posición para que el contenido leído más recientemente sea visible.
Excepto que la barra de desplazamiento decide que desea ver la parte SUPERIOR del contenido visible actualmente, no la parte inferior. (Es más fácil ver si usa números: https://jsfiddle.net/1co3x48n/ )
Si está dispuesto a usar javascript, hay todo tipo de respuestas: https://www.google.com/search?q=scrollbar+always+on+bottom+css+site:stackoverflow.com
Honestamente, el hecho de que pueda pasar por ~ 3 + páginas de esto y encontrar solo respuestas de Javascript me dice que no va a encontrar una respuesta solo de CSS, ciertamente no una que sea ampliamente compatible con el navegador.
fuente
Desafortunadamente, ninguna de las soluciones proporcionadas parece funcionar realmente. El problema con el uso
onFocus
de un cuadro de texto es que no se aplicará si el cuadro de texto ya tiene el foco. He estado jugando con esto durante horas y la solución más cercana que he encontrado hasta ahora es esta:Sin embargo, esto solo parece funcionar a veces. Funciona el 100% del tiempo al hacer clic en el cuadro de texto, pero por alguna razón al cerrar el teclado virtual solo funciona si se desplaza lo suficiente hacia arriba. De lo contrario, se restablece a la misma posición cada vez (cerca del fondo, pero no del todo).
No estoy seguro de qué está causando eso. Tendré que investigar más mañana, supongo. Sin embargo, este es el más cercano hasta ahora.
fuente
Cree un contenedor como en los ejemplos anteriores, pero luego modifique el CSS cuando comience a escribir.
No configuro la posición de la barra de desplazamiento, solo muevo todo el contenedor de mensajes hacia arriba. Entonces, cualquiera que sea su posición de desplazamiento, permanecerá igual. Al menos hacia abajo, por supuesto, no podrá ver las líneas en la parte superior.
Debería poder ajustar el CSS a sus necesidades. Incluso podría ir sin JS si usa: foco o configuración CSS ligeramente diferente, sea creativo :)
fuente
debe agregar
document.querySelector(".messages").scrollTop = 10000;
a latest
función cuando agregue margen, luegoscrollTop
vaya al final en la carga que configuróscrolltop
y cuando agregue margen o elimine el margenscrolltop
no se configuró nuevamente, cambie su script para que le gustefuente
Parece que hay un problema con la función de alternancia js. Lo he cambiado a un simple escondite. También he agregado un ancho en la etiqueta de entrada. También debe agregar una posición: absoluta en el div de envío de mensaje y en la parte inferior: 0 para que permanezca en la parte inferior. luego coloque position: relative en el contenedor para que el mensaje de envío div permanezca dentro del contenedor. Esto significa que el contenedor de mensajes no afectará los mensajes en sí y los empujará hacia arriba.
fuente
Un enfoque CSS imperfecto puro que se me ocurre es el siguiente:
La sección superior tiene un pequeño problema cuando hay margen. El truco aquí es usar el margen negativo y usar la traducción para "desplazarse hacia arriba" (no realmente un desplazamiento, solo una ilusión) el
wrapper
div.fuente
div
)?Simplemente se puede abordar con nombres de anclaje. Mire el violín JS en https://jsfiddle.net/gvbz93sx/
Cambio de HTML
<a name="bottom"></a>
JS Change
document.location.hash = "#bottom";
fuente