JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/4.0.2/autosize.min.js"></script>
<div class="app">
<div class="app__main">
<ul>
<li>001</li>
<li>002</li>
<li>003</li>
<li>004</li>
<li>005</li>
<li>006</li>
<li>007</li>
<li>008</li>
<li>009</li>
<li>010</li>
<li>011</li>
<li>012</li>
<li>013</li>
<li>014</li>
<li>015</li>
<li>016</li>
<li>017</li>
<li>018</li>
<li>019</li>
<li>020</li>
<li>021</li>
<li>022</li>
<li>023</li>
<li>024</li>
<li>025</li>
<li>026</li>
<li>027</li>
<li>028</li>
<li>029</li>
<li>030</li>
</ul>
</div>
<div class="app__footer">
<textarea rows="1"></textarea>
</div>
</div>
CSS
.app {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.app__main {
flex: 1 1 0%;
min-height: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.app__footer {
flex: 0 0 auto;
padding: 10px;
background: #eee;
}
textarea {
display: block;
box-sizing: border-box;
overflow: auto;
overflow-x: hidden;
padding: 0;
width: 100%;
height: auto;
max-height: 160px;
font-size: 16px;
line-height: 20px;
resize: none;
}
ul {
margin: 0 40px;
padding: 0;
}
li {
padding: 20px;
border: 1px solid #ccc;
}
JavaScript
function resizeSpy(element, callback) {
var width, height, oldWidth, oldHeight;
var pos = getComputedStyle(element).position;
if (pos === 'static') {
element.style.position = 'relative';
};
var frame = document.createElement('iframe');
frame.style.cssText = 'position: absolute; z-index: -1; top: 0; left: 0; width: 100%; height: 100%; margin: 0; border: 0; padding: 0; pointer-events: none;';
element.insertBefore(frame, element.firstChild);
oldWidth = frame.contentWindow.innerWidth;
oldHeight = frame.contentWindow.innerHeight;
frame.contentWindow.onresize = function() {
console.log('resize');
callback({
width: frame.contentWindow.innerWidth,
height: frame.contentWindow.innerHeight,
oldWidth: oldWidth,
oldHeight: oldHeight,
});
oldWidth = frame.contentWindow.innerWidth;
oldHeight = frame.contentWindow.innerHeight;
};
return function() {
frame.contentWindow.onresize = width = height = oldWidth = oldHeight = null;
};
};
var appMain = document.querySelector('.app__main');
var appFooter = document.querySelector('.app__footer');
var input = document.querySelector('textarea');
function handler(data) {
var diff = data.height - data.oldHeight;
appMain.scrollTop += diff;
}
autosize(input);
resizeSpy(appFooter, handler);
handler({
height: appFooter.offsetHeight,
oldHeight: appFooter.offsetHeight
});