Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix the width of textarea in number of characters? (cols attribute does NOT work)

Tags:

html

css

I want to specify the width of textareas in terms of the maximum numbers of monospace characters they should be able to hold in each line with neither excess leftover space nor overflow.

There are a few SO similar questions, but the consensus answer, namely to use the cols attribute, decidedly does not work, as shown in this jsFiddle. The HTML for it is this:

<textarea cols="1"  rows="2">1</textarea><br/>
<textarea cols="10" rows="2">1234567890</textarea><br/>
<textarea cols="20" rows="2">12345678901234567890</textarea><br/>
<textarea cols="40" rows="2">1234567890123456789012345678901234567890</textarea><br/>
<textarea cols="80" rows="2">12345678901234567890123456789012345678901234567890123456789012345678901234567890</textarea><br/>

The actual width is always substantially greater than the necessary width. (In Safari at least the excess seems to remain constant, irrespective of the specified value of cols; with Chrome, however, the excess grows as the value of cols grows.)

I also tried using the CSS width property with em and ex units. The latter results in fields that are several characters narrower than needed, while the former results in even greater widths than those resulting from the cols attribute.

Finally, I investigated setting the width, in ex units, as the number obtained by multiplying the number of characters by some fudge factor. This is not only disgusting (we shouldn't be doing the browser's work), but also is not cross-browser: the fudge factors I found for Chrome and Safari (for example) are substantially different (1.333 vs 1.415).

Is there a professional1 way to do this?


1i.e. cross-browser, guesswork-free, hack-free, documented, well-thought-out, etc.

like image 762
kjo Avatar asked Jan 25 '15 18:01

kjo


1 Answers

The col attribute gives accurate results, but the width is somewhat larger than needed for the characters, since there is room for vertical scroll bar on the right (or left, depending on directionality). You can see this by entering a few more lines in the area.

You can remove the room for scroll bar by removing scrollability, using overflow: hidden.

An alternative to set the width in ch units, but browser support is more limited.

textarea {
    resize:none;
    background-color:lightgray;
    padding:0;
    font-family: monospace;
}
.fix {
    overflow: hidden;
}
.w18 {
    width: 18ch;
}
<textarea cols="18" rows="2">123456789012345678</textarea>
<p>See what happens when vertical scrolling is needed:<br>
<textarea cols="18" rows="2">123456789012345678
123
123</textarea>
<p>Fixed by removing space for scroll bar:<br>
<textarea cols="18" rows="2" class="fix">123456789012345678</textarea>
<p>Fixed by setting width in `ch` units:<br>
<textarea cols="18" rows="2" class="w18">123456789012345678</textarea>

As the demo shows, overflow: hidden also removes the space for a horizontal scroll bar. Browsers generally leave such a space, so that the area seems to have one row more than the value of rows, even though browsers normally do not show a horizontal scroll bar as they used to (they visually break lines instead). Using overflow-y: hidden instead keeps that space

You need to consider what the removal of scroll bars implies in terms of usability. If the intent is to show the user the maximum allowed line length, maybe you can do that by forcing a scroll bar instead of removing it.

<textarea cols="18" rows="2" style="overflow-y: scroll; overflow-x: hidden; resize: none">123456789012345678</textarea>
like image 131
Jukka K. Korpela Avatar answered Oct 17 '22 09:10

Jukka K. Korpela