i'm working on a small project where textarea are used.
And the problem with textarea is that the text always start at the top left corner...
And what i want is to have the content inside of that textarea always centered. And then if I add a line it'll expend from the middle, something like this :
I looked for thing like vertical align and thing like that, but i also saw things about inserting a div... But i was wondering if there was a solution with textarea
Thanks !
CodePudding user response:
I don't think you can align the text in textarea
vertically, but you can fake it!
HTML and CSS:
- Create a resizable
div
- Nest a
contenteditable
p
in thatdiv
- Add a
placeholder
for thep
when it's empty - Use
flexbox
to set thep
in the middle:align-items: center;
- Add
p {white-space: pre-line;}
to prevent theoverflow
when typing - Add
p {outline: 0px solid transparent;}
to remove the border on focus
JavaScript:
- Get the target (
p
) - Add an
event
onkeypress
- Check for pressing
Enter
- Prevent the
default event
and insert a line break (new line) instead - Add an
event
onclick
to thediv
to focus thep
(textarea behavior)
// Get the target
let p = document.querySelector('p');
let div = document.querySelector('div');
// Add event onkeypress
p.addEventListener('keypress', (e) => {
let keyCode = e.code || e.key;
// Check for pressing 'Enter'
if(keyCode === 'Enter') {
// Prevent the default event and insert line break (new line) instead
document.execCommand('insertLineBreak');
e.preventDefault();
}
});
// Add event onclick
div.addEventListener('click', () => {
// Focus on p to get the textarea behavior
p.focus();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
resize: both;
width: 200px;
height: 150px;
border: 1px solid;
overflow: auto;
margin: 30px auto;
display: flex;
align-items: center;
cursor: text;
}
p {
white-space: pre-line;
width: 100%;
height: fit-content;
outline: 0px solid transparent;
}
p:empty::before {
content: attr(placeholder);
color: #666666;
}
<div>
<p contenteditable="true" placeholder="Type here..."></p>
</div>