JSFiddle - React, Tailwind, and code Playground
by dswitzer
HTML
<div class="textbox-control">
<div class="textbox-control-header">
Top Toolbar
</div>
<textarea class="textbox-form-control" oninput="this.parentNode.classList[this.value.length ? 'add' : 'remove']('textbox-control-has-content'); this.parentNode.dataset.textContent = this.value;"></textarea>
<div class="textbox-control-footer">
Bottom Toolbar
</div>
</div>
CSS
* {
box-sizing: border-box;
}
.textbox-control {
position: relative;
display: grid;
border: 1px solid #ccc;
max-width: 800px;
}
/* for autosize textarea */
.textbox-control::after {
/* Note the weird space! Needed to preventy jumpy behavior */
content: attr(data-text-content) " ";
/* This is how textarea text behaves */
white-space: pre-wrap;
/* Hidden from view, clicks, and screen readers */
visibility: hidden;
}
.textbox-control:focus-within
.textbox-control-has-content {
outline: 1px solid blue;
}
.textbox-control:focus-within .textbox-control-header,
.textbox-control:focus-within .textbox-control-footer,
.textbox-control-has-content .textbox-control-header,
.textbox-control-has-content .textbox-control-footer {
visibility: visible;
}
.textbox-control-header,
.textbox-control-footer {
position: absolute;
left: 0;
right: 0;
background-color: rgba(204, 204, 204, 0.25);
padding: 0.25em 1em;
height: 1.7em;
z-index: 2;
visibility: hidden;
}
.textbox-control-header {
top: 0;
}
.textbox-control-footer {
bottom: 0;
}
.textbox-control::after,
.textbox-form-control {
padding: 2.5em 0.5em;
width: 100%;
border: 0;
z-index: 1;
outline: 0;
/*
resize: vertical;
*/
/* for autosizing */
/* Place on top of each other */
grid-area: 1 / 1 / 2 / 2;
font: 1em monospace;
line-height: 1.25em;
}
/* for autosizing */
.textbox-form-control {
resize: none;
/* Firefox shows scrollbar on growth, you can hide like this. */
overflow: hidden;
}