Daniel Birowsky Popeski
Daniel Birowsky Popeski

Reputation: 9266

Middle (vertically) align text inside a <textarea>

I have a multi-line search box, and I want everything aligned in the middle. Is it possible to vertically center the content of a <textarea>?

Upvotes: 39

Views: 76740

Answers (8)

Jeffery ThaGintoki
Jeffery ThaGintoki

Reputation: 457

The hack was to set rows to 1 in my case

Upvotes: 0

Kshatra
Kshatra

Reputation: 425

Simplest solution without contenteditable and other heavy stuff (Jquery used for quickness). The core concept is padding trick (mentioned above) with input event listener that will always scroll to the vertical center of text inside textarea. this.scrollHeight - this.offsetHeight gives the actual height of text block. Scrollbar inside textarea ranges exactly for that height. So by scrolling to 50% of it we have a solution.

$(document).on("input focus", "textarea", function() {
  this.scrollTo(0, (this.scrollHeight - this.offsetHeight) / 2);
});
textarea {
  --textarea-height: 6em;
  
  width: 30em;
  height: var(--textarea-height);
  padding: calc(var(--textarea-height) / 2) 0;
  text-align: center;
  overflow: hidden;
  box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea></textarea>

Upvotes: 2

mfluehr
mfluehr

Reputation: 3178

You cannot vertically center the content of a <textarea>. Instead, use a <div> with content editing enabled. Then use Flexbox layout to center the text.

[contenteditable] {
  /* Use Flexbox to center the content */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  
  /* Apply min height of 4 lines */
  line-height: 1.2;
  min-height: calc(1.2em * 4);
  
  /* Border styles */
  border: 1px solid gray;
  border-radius: 5px;
}
<div contenteditable="true">This text is editable.<br>Go ahead and change it.</div>

Upvotes: 2

alex
alex

Reputation: 490143

You can fake the centering with vertical padding.

textarea {
  padding: 30px 0;
}

You can also vertically center text by using the line-height property, but that does not work with more than one line of text.

Upvotes: 13

Karlus da Wakoko
Karlus da Wakoko

Reputation: 291

not a solution but a workaround, wrap it in a label and set the position of the textarea to the middle. caveat: must recalculate the textarea rows once the text content reaches its limit.

fiddle: https://jsfiddle.net/syjfoqzx/

Upvotes: 0

Daniel Birowsky Popeski
Daniel Birowsky Popeski

Reputation: 9266

Back in the days when i was asking this, i tried achieving this with textarea which is really not possible without scripting. The answer was adding HTML5's contenteditable="true" on a table cell with style="vertical-align: middle". If one's project allows modern HTML, this is a rather simple and effective solution.

If instead of adding <table> and <tr> and <td> to your markup, you would like something regular like a <div>, you would still need two of them:

<div style="display: table">
  <div 
    style="display: table-cell; vertical-align: middle"
    contenteditable="true">
    I am vertically aligned
  </div>
</div>

Upvotes: 13

Petryk P&#39;yatochkin
Petryk P&#39;yatochkin

Reputation: 332

There is the HTML5 contenteditable attribute. http://www.w3schools.com/tags/att_global_contenteditable.asp

Maybe the div tag instead of textarea can solve your problem.

Upvotes: 8

David Houde
David Houde

Reputation: 4778

You might be able to make a script that determines the elements height, line height, and lines of text and calculate a padding-top, or even \n to prepend the text.

I do not think this is possible with just CSS though.

Upvotes: 1

Related Questions