最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - "white-space: pre;" CSS style does not seem to work according to W3C spec in <textarea&

programmeradmin0浏览0评论

I wish to make a textarea HTML element wrap lines only on newlines without collapsing leading whitespace.

The W3C spec says the CSS style element white-space: pre; should give me the behavior I want, but it does not work - it does not collapse leading whitespace, but it always wraps, not just on newlines.

white-space: nowrap; does not wrap except on newlines like I want, but unfortunately it collapses leading whitespace.

The only thing that works the way I need it to is the wrap="off" HTML attribute, but that is not supported in the W3C spec. It works perfectly though, and seems to work in all browsers I have tried. It bothers me it is unsupported by the spec though.

Can anyone tell me why this seems to be the case and give a means of doing this that is supported by W3C? Maybe it is something else I am overlooking like a default for some other style element or something? Maybe there is a way using JavaScript?

The pertinent section in the W3C spec is found HERE.

Here is some code that shows the problem:

<textarea style="white-space: pre; width: 400px">          This line will wrap but the spec seems to indicate it should not.  SHOULD work?</textarea><br>
<textarea style="white-space: nowrap; width: 400px">          I could do this but it collapses leading whitespace unfortunately</textarea>
<textarea wrap="off" style="width: 400px;">          This works but is not part of the standard.  It should be unsupported.  It is the only thing that does what I want.</textarea>

I wish to make a textarea HTML element wrap lines only on newlines without collapsing leading whitespace.

The W3C spec says the CSS style element white-space: pre; should give me the behavior I want, but it does not work - it does not collapse leading whitespace, but it always wraps, not just on newlines.

white-space: nowrap; does not wrap except on newlines like I want, but unfortunately it collapses leading whitespace.

The only thing that works the way I need it to is the wrap="off" HTML attribute, but that is not supported in the W3C spec. It works perfectly though, and seems to work in all browsers I have tried. It bothers me it is unsupported by the spec though.

Can anyone tell me why this seems to be the case and give a means of doing this that is supported by W3C? Maybe it is something else I am overlooking like a default for some other style element or something? Maybe there is a way using JavaScript?

The pertinent section in the W3C spec is found HERE.

Here is some code that shows the problem:

<textarea style="white-space: pre; width: 400px">          This line will wrap but the spec seems to indicate it should not.  SHOULD work?</textarea><br>
<textarea style="white-space: nowrap; width: 400px">          I could do this but it collapses leading whitespace unfortunately</textarea>
<textarea wrap="off" style="width: 400px;">          This works but is not part of the standard.  It should be unsupported.  It is the only thing that does what I want.</textarea>

Share Improve this question edited Feb 24, 2016 at 2:20 Solomon Ucko 6,1093 gold badges27 silver badges48 bronze badges asked Feb 4, 2014 at 1:12 XitalogyXitalogy 1,6122 gold badges15 silver badges17 bronze badges 4
  • CSS can't control the layout of <textarea> contents. – Pointy Commented Feb 4, 2014 at 1:14
  • @Pointy It seems to be able to - nowrap collapses leading white space, for instance, in the sample code I show. It also does not wrap on newlines, but pre does, and other CSS style elements have other effects on the visual layout of the contents. – Xitalogy Commented Feb 4, 2014 at 1:17
  • Well it can affect some things: padding, font, color, background, border, etc. – Pointy Commented Feb 4, 2014 at 1:21
  • @Pointy It can affect both collapse/non-collapse of white space and wrapping, which is what this entire question is about :) It just does not seem to do it per the spec int he browsers I have tried – Xitalogy Commented Feb 4, 2014 at 1:23
Add a comment  | 

3 Answers 3

Reset to default 7

The textarea element has always had special implementations with variation across browsers. The original idea in HTML 2.0 was that the user can enter arbitrarily long lines, with horizontal scrollbars provided by the browser as needed, and only line break actually entered by the user would produce new lines. Implementations introduced both “soft” and “hard” wrapping, however, and gradually made “soft” wrapping (lines are wrapped visually but not internally – submitted data still has only user-entered line breaks) the default. The attribute wrap=hard was introduced as a nonstandard way of getting “hard” wrapping (wrapping also adds actual line breaks to the element’s value), and for quite some time, the nonstandard attribute wrap=off was the only way to achieve the behavior that was then standard!

HTML 4 then partly retrofitted the specification to implementations; it says: “Users should be able to enter longer lines than [the value of the cols attribute], so user agents should provide some means to scroll through the contents of the control when the contents extend beyond the visible area. User agents may wrap visible text lines to keep long lines visible without the need for scrolling.” It does not define any way for authors to specify whether “soft” wrapping takes place (or to ask for “hard” wrapping).

In HTML5 drafts, as noted, there is the wrap attribute, but with only two conforming values hard and soft, and the latter really means “no hard wrapping” – the text may or may not visually wrap, and this is apparently left to be handled in CSS. There is some logic here, since the attribute is now for functional control only (whether wrapping causes line breaks to be added to the actual value).

But although wrap=off is declared nonconforming (forbidden, obsolete), the HTML5 drafts describe its effect. As noted here in comments, the description is in the “Rendering” section and as “suggested rendering” and as affecting via CSS. This means that the drafts do not require browsers to support wrap=off, just “expects” it, and only as part of the CSS cascade, i.e. only when CSS is enabled and there is no CSS rule that overrides it.

Thus, although wrap=off works well and there is little reason to expect it to stop working, it is not conforming and it is not “guaranteed” to work (i.e., HTML5 drafts do not impose a requirement on browsers).

The varying support to white-space for textarea in browsers makes it an unreliable tool here.

As a workaround, you might consider creating a simulation of textarea with an editable block, e.g. with

<div class=textarea contenteditable=true>...</div>

and CSS code like

.textarea { 
  font-family: Consolas, monospace;
  white-space: pre;
  word-wrap: normal;
  padding: 0.1em 0.3em;
  border: solid thin;
  overflow: auto;
  width: 25em; /* fallback for browsers not supporting ch */
  width: 60ch;
}

And if the data is to be submitted as part of form data, you would need to copy it to a hidden field before submission.

This would work reasonably (even old versions of IE support contenteditable), except that it is too powerful: browsers typically let users enter “rich text” in an editable element. Moreover, they tend to generate markup (tags) like <br> rather than newline chaacters when the user hits Enter, so your JavaScript code would need to do some cleanup to turn the content to plain text.

So the workaround isn’t particularly good, but it’s probably the best approach if you need to conform to HTML5 drafts and still get the functionality.

To quote the great and mighty Chris Coyier:

To prevent text from wrapping normally in CSS, you use #whatever { white-space: nowrap; }. But for whatever reason, that doesn't work with textareas. If you want to be able to type into textareas and would rather lines do not break until you press return/enter (a horizontal scrollbar is triggered instead), you'll have to use the wrap="off" attribute.

<textarea wrap=off ...>
  Hello world
</textarea>

You need to replace the spaces extra spaces with a non breaking space.

<textarea style="white-space: nowrap; width: 400px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Leading space will still be there and the line will not wrap.</textarea>

JSFiddle

Now to get IE to play along, overflow:scroll needs to be added to force the scrollbars

<textarea style="white-space: nowrap; width: 400px; overflow-x:scroll">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Leading space will still be there and the line will not wrap.</textarea>

JSFiddle

And the kicker, Firefox does not support whitespace on a textarea, so until they fix bug: 82711, you need to use the nowrap attribute.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论