J'ai posé une question similaire hier, mais je l'ai mal expliqué et je n'ai pas précisé mon désir d'une solution pure CSS, ce qui, je pense, devrait être possible, alors j'essaie à nouveau.
Fondamentalement, j'ai un problème où j'ai une div de messages déroulants et un champ de saisie en dessous. Lorsque je clique sur un bouton, je souhaite que le champ de saisie soit augmenté de 100 pixels, sans que la division des messages défile également.
Voici un violon qui illustre le problème dans son intégralité
Comme vous pouvez le voir, lorsque vous cliquez sur le bouton "ajouter une marge", la div des messages défile également vers le haut. J'aimerais qu'il reste où il était. De même, si vous faites légèrement défiler vers le haut de sorte que vous ne puissiez voir que l'avant-dernier message, un clic sur le bouton devrait également conserver cette position lors du clic.
La chose intéressante est que ce comportement est "parfois" préservé. Par exemple, dans certaines circonstances (que je ne peux pas vraiment déduire), la position de défilement est conservée. Je voudrais juste qu'il se comporte toujours comme tel.
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
qui défile, c'est la hauteur du div qui diminue. Alors, pourquoi est-ce important? Eh bien, cela signifie que l'scrollbar
ajustement de sa position n'est pas. La barre de défilement ne se souvient que de sa position par rapport au haut de son conteneur. Lorsque la hauteur du div diminue, il semble que la barre de défilement défile vers le haut, mais ce n'est pas le cas.Réponses:
C'est une solution amusante qui pourrait vous plaire.
Ce que nous savons sur le div, c'est qu'il ne conserve que la position supérieure de la barre de défilement, donc si la hauteur a changé pour une raison quelconque, la barre de défilement restera la même et c'est ce qui cause votre problème.
Comme solution de contournement, vous pouvez inverser le
.messages
180 degrés en utilisanttransform: rotate(180deg) scaleX(-1);
et inverser le.message
pour annuler le retournement du contenu, puis la div maintiendra automatiquement la barre de défilement inférieure (qui est en haut).la source
Le comportement normal de la barre de défilement doit être en haut, donc lorsque vous le placez au bas lors du chargement de la page, vous devez le maintenir vous-même car chaque fois que le contenu ci-dessous le poussait, le défilement div se déplacera vers le haut.
J'ai donc deux solutions pour vous:
Inversez les messages à l'intérieur de la div des messages pour que le dernier message soit le premier afin que le défilement soit toujours en haut.
J'ai créé une fonction javascript pour faire défiler vers le bas de n'importe quel élément afin que vous l'appeliez quand vous voulez faire défiler vers le bas.
Vérifier l'extrait
la source
Vous pouvez le faire dans l'autre sens, en donnant la hauteur au au
.messages
lieu de le donner au.container
dans ce cas cela n'affectera pas les messagesdiv
mais si vous le donnez au.container
il poussera votre div car la marge est à l'intérieur du principal div qui ont une hauteur.Vérifiez cet extrait
la source
.send-message
. Si vous regardez ma question précédente, cela est fait car cela s'apparente à la bosse de marge de l'ouverture du clavier virtuel sur les appareils mobiles (le bas de la marge est juste un remplacement 1: 1 pour déboguer la solution)La solution de contournement simple consiste à
scrollTop
activer / désactiver la précédente . Ici, j'utilise un ensemble de données pour stocker lascrollTop
valeur précédente , vous pouvez utiliser une variable non plus.la source
Je veux dire, ce qui suit est une solution CSS uniquement qui résout exactement votre exemple:
mais je ne pense pas que cela vous aidera avec votre problème d'origine du clavier virtuel. Mais cela peut peut-être inspirer quelqu'un d'autre à trouver une solution.
Le principal problème semble être que la barre de défilement fait déjà exactement ce que vous voulez:
Maintenir sa position pour que le contenu le plus récemment lu soit visible.
Sauf que la barre de défilement décide que vous vouliez voir le HAUT du contenu actuellement visible, pas le bas. (Il est plus facile de voir si vous utilisez des nombres: https://jsfiddle.net/1co3x48n/ )
Si vous souhaitez utiliser javascript, il existe toutes sortes de réponses: https://www.google.com/search?q=scrollbar+always+on+bottom+css+site:stackoverflow.com
Honnêtement, le fait que vous puissiez parcourir ~ 3 + pages de cela et ne trouver que des réponses Javascript me dit que vous n'allez pas trouver une réponse uniquement CSS, certainement pas une réponse largement compatible avec le navigateur.
la source
Malheureusement, aucune des solutions proposées ne semble fonctionner. Le problème avec l'utilisation
onFocus
d'une zone de texte est qu'elle ne s'applique pas si la zone de texte a déjà le focus. Je joue avec ça depuis des heures et la solution la plus proche que j'ai trouvée jusqu'à présent est la suivante:Cependant, cela ne semble que parfois fonctionner. Cela fonctionne 100% du temps lorsque vous cliquez sur la zone de texte, mais pour une raison quelconque, lorsque vous fermez le clavier virtuel, cela ne fonctionne que s'il a été suffisamment défilé. Sinon, il revient à la même position à chaque fois (près du bas, mais pas tout à fait en bas).
Je ne sais pas ce qui cause ça. Devra enquêter davantage demain je suppose. C'est le plus proche jusqu'ici cependant.
la source
Créez un conteneur comme dans les exemples ci-dessus, mais modifiez simplement le CSS lorsque vous commencez à taper.
Je ne définit pas la position de la barre de défilement, déplacez simplement le conteneur de messages vers le haut. Quelle que soit votre position de défilement, elle restera la même. Au moins vers le bas, bien sûr, vous ne pourrez pas voir les lignes en haut.
Vous devriez pouvoir ajuster le CSS à vos besoins. Vous pourriez même vous passer de JS si vous utilisez: focus ou configuration CSS légèrement différente, soyez créatif :)
la source
vous devez ajouter
document.querySelector(".messages").scrollTop = 10000;
à latest
fonction lorsque vous ajoutez de la marge, puisscrollTop
passez à la fin de la charge que vous avez définiescrolltop
et lorsque vous ajoutez ou supprimez une margescrolltop
n'a pas défini à nouveau, changez votre script pour l'aimerla source
Il semble y avoir un problème avec la fonction bascule js. Je l'ai changé en un simple cache-cache. J'ai également ajouté une largeur sur la balise d'entrée. Vous devez également ajouter une position: absolue sur la div du message d'envoi et en bas: 0 pour qu'elle reste en bas. puis placez position: relative sur le conteneur pour que le message d'envoi div reste dans le conteneur. Cela signifie que le conteneur de messages n'affectera pas les messages eux-mêmes et ne les poussera pas vers le haut.
la source
Une approche CSS imparfaite pure que je peux trouver est la suivante:
La section supérieure a un petit problème lorsque la marge est là. L'astuce consiste à utiliser une marge négative et à utiliser translate pour «faire défiler vers le haut» (pas vraiment un parchemin, juste une illusion) le
wrapper
div.la source
div
)?Il peut très simplement être adressé avec des noms d'ancrage. Regardez le violon JS sur https://jsfiddle.net/gvbz93sx/
Modification HTML
<a name="bottom"></a>
Changement JS
document.location.hash = "#bottom";
la source