5 ms·
HTML whitespace is broken (2024)
- wesammikhail 2y agoThe number of hours I've wasted over the years on trying to resolve whitespace problems over the years is... not okay to say the least. Great writeup though!
- TheChaplain 2y agoIt's hard to take any article seriously with a header like "X is broken" when it obviously isn't for a ridiculously large majority.
- perching_aix 2y agoWhat a puzzling reply, HTML parsers are famously mistake-tolerant and convention driven. Its standard is almost a suggestion, there can be plenty wrong with it without causing practical everyday issues, as the modern web is very established.
- agos 2y agoI find more puzzling that the author, after declaring it "broken", offers a solution that is as broken but also laughable.
- shiomiru 2y agoThrowing any codepoint sequence at two separate compliant HTML5 parsers will result in the same DOM, and to my knowledge, all major browsers use compliant parsers.
- nilslindemann 2y agoIt should remove all whitespace before and after line breaks ("\n"), including the line break itself. And otherwise replace inline whitespace with one space. In pre's keep the whitespace. Well, at least we have display:flex.
- ximm 2y agoI expected an uninformed rant and actually got a really well informed, balanced rant. I don't agree that this is a major issue, but every time I thought of a counter argument it was immediately addressed in the article. Well done!
- jraph 2y agoYep. I don't agree with the premise, and I'm never reaching for the pre tag as they seem to do, but the content is informative and goes into a lot of details. The topic is very well researched. I think HTML whitespace handling is a good compromise. It has drawbacks but they are workable. I wouldn't want the quoting solution (suddenly you'd need an additional escaping mechanism, which complexifies things, and I do believe it would make authoring HTML harder). And I'm not sure how could HTML do better without such a quoting solution. I'm particularly not convinced by the CMS argument: - A CMS can let users write stuff in HTML with a wysiwyg editor - A CMS can trim printed strings, and replace new lines with br elements. If you need people to be able to break lines while writing, you can use something like markdown or whatever HN does. As for prettifying HTML with automated tools in the editor, I never bothered. That scares me exactly because I'm afraid they will break my careful handling of whitespaces or do ugly stuff, I just prefer doing it by hand. XML and SGML ought to have a deintent syntax that would allow indenting the code without indenting the content in the pre tag, though.
- shiomiru 2y agoIt seems well-intentioned, but not particularly well informed... * It mixes concerns of HTML and CSS - e.g. <pre> eating newlines is a result of the HTML parser, but whitespace collapsing is specified in CSS. * It suggests turning HTML from a markup language into... whatever incompatible thing the author came up with. Arguably it's not much worse than XHTML, but I don't expect better adoption. * The final suggestion is to add a character reference to CSS - the sole issue being that CSS does not see character references, those are turned by HTML into Unicode codepoints. Also, the set of character references is closed, for good reasons.[0] * (Nit, but "block formatting context" does not mean what the author thinks it means. Flex items behave like blocks because they become blockified - BFCs solve a separate, similarly hairy issue (floats & margin collapsing.)) [0]: https://github.com/whatwg/html/blob/main/FAQ.md#html-should-add-more-named-character-references https://github.com/whatwg/html/blob/main/FAQ.md#html-should-...
- ximm 2y agoConcerning text-to-speech and the missing separation of HTML and CSS: There are several open issues about this in the spec that defines how accessible names and descriptions are computed from HTML elements: https://github.com/w3c/accname/issues?q=state%3Aopen%20label%3A%22topic-whitespace%22 https://github.com/w3c/accname/issues?q=state%3Aopen%20label...
- radium3d 2y agoI do the “you’re probably not going to do” mentioned all the time. Maybe that’s why I haven’t had many instances of needing to adjust for white space in html over the last almost 30 years of web development haha
- peter-m80 2y agoBroken = works as expected
- lexicality 2y agoit works as specified, but in many cases that's not what someone who hasn't read the spec would expect
- seba_dos1 2y agoI dunno, given all the constraints it actually seems to be specified in a pretty reasonable way to work in an approachable manner even (or especially) if you had never read a spec in your life.
- ximm 2y agoThe one thing I thought was IMHO missing from this article was JavaScript. In HTML, it is pretty natural to add white space (i.e. text nodes containing white space) between all elements. You basically only have to worry if you want to avoid that. In JavaScript, the opposite is true. If you want to create a text node, you have to do so explicitly. If you just create elements and append them to the same parent, they will be added without whitespace. I am not sure how JSX behaves in this regard. Last time I checked it was more like JavaScript than HTML, which was of curse very confusing for people.
- CSSer 2y agoiirc, in JSX whitespace between elements/components is ignored unless it’s part of a string inside a JSX expression e.g. {“ “}.
- austin-cheney 2y ago* All white space in HTML and XML is preserved verbatim. * HTML has a default presentation scheme that varies by interpreter. For everything else use CSS. * The default presentation of white space in HTML and XML is what is called tokenized space, which is that all consecutive white space characters are displayed as a single space character. Again, you can control this with CSS. * White space does not determine the behavior or display of other HTML tags. * White space is a text node in the DOM. If it is adjacent to other text that text and white space are one text node, otherwise the white space is its own text node. That should be all there is to it. JavaScript has absolutely no bearing on this subject.
- lmm 2y ago> All white space in HTML and XML is preserved verbatim. Do you mean "any change to whitespace in HTML or XML results in a semantically inequivalent document"? That's a perspective you can take, but it has pretty undesirable results: it means you can't ever reformat HTML or XML source. And it very clearly contradicts how most people understand and expect to work with HTML. > The default presentation of white space in HTML and XML is what is called tokenized space, which is that all consecutive white space characters are displayed as a single space character. Again, you can control this with CSS. Where is the CSS option to display multiple consecutive spaces, but line break as normal? That's something very much wanted in a lot of cases (and what the author's &ncsp; idea is getting at). Also, this doesn't make it clear what happens (or should happen) with consecutive white space characters that have different markup. > White space is a text node in the DOM. If it is adjacent to other text that text and white space are one text node, otherwise the white space is its own text node. What does "adjacent" mean here? And what happens if the white space is adjacent to text on both sides?
- Rygian 2y ago> > All white space in HTML and XML is preserved verbatim. > Do you mean "any change to whitespace in HTML or XML results in a semantically inequivalent document"? That's a perspective you can take, but it has pretty undesirable results: it means you can't ever reformat HTML or XML source. And it very clearly contradicts how most people understand and expect to work with HTML. I don't think that's what grandparent meant. I read that HTML and XML do not impose any coalescing of whitespace. Whatever whitespace is read by a parser is accepted as such. Whether the whitespace has semantic value or not is not a concern for HTML or XML as data formats. On the other hand, coalescing whitespace is a feature of HTML and XML renderers. And you are correct: a tool that reformats whitespace inside a <verbatim> tag will output semantically wrong results (e.g. if the contents are Python code). Which supports the point: the semantics of whitespace are not determined by the HTML or XML data formats, but by the tools generating and consuming the data.
- LLcolD 2y agoThe issue probably comes from the fact that web browsers try to render HTML even if it’s not perfect. HTML isn’t super strict, so browsers will still display pages with small mistakes. There was a push to make HTML stricter with XHTML, which enforced rules like case-sensitive elements and closing tags, kind of like XML. But it didn’t really stick. Browsers had a hard time with those stricter rules, so HTML’s more relaxed approach stuck around. For some time I really tried to use XHTML when createing weh pages, but then I asked my self why all of the trouble when browsers don't follow the standards.
- nayuki 2y agoHalf of what you said is correct, but: > There was a push to make HTML stricter with XHTML / But it didn’t really stick. Yup! And XHTML still works in practice: https://www.nayuki.io/page/practical-guide-to-xhtml https://www.nayuki.io/page/practical-guide-to-xhtml > which enforced rules like case-sensitive elements That's a good thing. I don't miss the old days (~2000) of <HTML><BODY><P> etc. It's ugly to my eyes. Moreover, even today, it's legal to write <dIv></DIv>. > Browsers had a hard time with those stricter rules Nonsense; it's developers and amateur web designers who couldn't cope with XHTML. Browsers parse XHTML perfectly these days, because it's just an application of XML. Also, existing tools like Macromedia Dreamweaver didn't add XHTML export support; it only outputted HTML. > I really tried to use XHTML when createing weh pages, but then I asked my self why all of the trouble when browsers don't follow the standards Browsers do follow the standards in XHTML mode! My page documents the behaviors and the yellow screen of death. For me, it's worth the trouble because it helps me detect errors like invalid syntax and unclosed tags.
- eqvinox 2y agoThe author seems entirely unaware that HTML (SGML/XML) entities are essentially text replacement. is the same as a literal space, and breaking this (or adding a new &lf; that isn't a literal line break) would create an even worse mess than these purported whitespace problems. (Also ​ should probably have been discussed in this article.)
- nayuki 2y agoBe careful with what you mean when you say "essentially text replacement" and "same as a literal space". In HTML, ampersand entities can only be used outside of tags or inside attribute values, for example: <tag key="&value;">&abc;</tag>. Ampersand entities cannot be used as a substitute for tags; for example, <tag> is literal renderable text and not a tag. This distinction is important because of odd languages like Java, where \uXXXX processing happens before tokenization. So this is a legal program: class Foo \u007B }. (U+7B is left brace.) One consequence is that to put a literal quotation mark inside a string, you can't use \u0022, but you must use \".
- eqvinox 2y agoYes, this is why I added the "essentially". HTML does it after tokenization, but before whitespace processing (which implies before a lot of other things that by necessity happen between tokenization and whitespace processing, these steps are nowhere close to each other). But the author seems to vaguely believe/suggest to either process entities at a much later stage, or carry down some "shadow effect" in addition to expanding the entity to its text content. Both of these are complete non-starters IMHO. (btw, you/anyone have other examples for that Java-style ordering of escapes vs. tokenization? I can think of C preprocessor trigraphs [which are deprecated since C23] but nothing else…)
- nayuki 2y agoC trigraphs is a great example that I forgot, because no one uses it and everyone hates it; glad to hear that C23 is finally removing that wart. I'm not aware of other languages with Java-style escapes before tokenization. I only learned the Java example due to the book Java Puzzlers; it has little impact on real-world code because it's considered obfuscation. I don't know the nitty-gritty details of other programming languages that I come in contact with; I just know Java especially well.
- bloak 2y agoU+0020 is perhaps the weirdest character in Unicode. Most of the time it's used to separate words, which is arguably a kind of mark-up. But sometimes it's used for other kinds of formatting. Also, if you were to use explicit mark-up for words I have no idea how you'd handle punctuation. Perhaps writing should be redesigned from the ground up? But meanwhile, though we'd all love to see the plan, let's stick with the mess we're used to.
- vintagedave 2y agoThis bothers me too: > Newlines and tabs are also treated identically and collapsed into spaces. This means that simply formatting your HTML -- as you might when hand-editing -- can add spaces. Possibly, something else is going on too: I'm not an expert here, I've just observed rendering differences when you have a newline between tags. Maybe it's inline vs block tags as the author also discusses? This has bitten me a few times and my hand-written sites or SSG-generated sites that I want to look nice have several ugly, long lines that should be broken up to be readable, but are not.
- jfk13 2y agoDoes the article's "Example 31" look correct to anyone? I see no "small space between the two boxes" (as claimed) in any of the browsers I tried.
- matt_kantor 2y agoIf you view the source it looks like they goofed and don't actually have any white space between the elements in the rendered example. It's just `<ul class="inline-block-list"><li></li><li></li></ul>`. When I try the code they show on the page myself the space is displayed.
- P-Nuts 2y agoIt has always slightly nagged me that web browsers don’t do as good a job as TeX at line breaking and sentence spacing.
- BoujidStack 2y agoWhitespace in HTML always seems to do its own thing, never quite what you expect!
- vintagedave 2y agoOn whitespace: what about sentences? HTML has paragraph-level, and word-level, spacing. (This article is about word-level.) There's no concept of sentences as a semantic element. I need to write a thoughtful rant on this sometime. You can read a mini-thesis here: https://daveon.design/about-dave-on-design.html#typography-&-layout:-spacing https://daveon.design/about-dave-on-design.html#typography-&...
- eviks 2y agoBy the way, for such a spacious and space-conscious blog no space between em dashes is out of place, they glue words together "paragraph—but"
- vintagedave 2y agoGood point! :)
- chrismorgan 2y agoThe bit about <pre> ignoring leading newlines is essentially a completely different thing from the rest of the article. It’s specifically HTML syntax parser behaviour <https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody https://html.spec.whatwg.org/multipage/parsing.html#parsing-...>: > If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move on to the next one. (Newlines at the start of pre blocks are ignored as an authoring convenience.) This is also applied to <textarea>. Personally, I think it was a mistake, because it complicates things and doesn’t do enough to justify itself. If it also did leading whitespace trimming across all lines, it’d be interesting enough to maybe justify itself as an authoring convenience (… though honestly I suspect that’d end up worse), but as it is it’s just an extra complication. I’ve needed to deal with the nuance of its special behaviour more than once or twice, and I’ve seen others stumble over it too. It’s also part of the fairly small pile of HTML features that make it not-round-trippable: it’s only done in parsing; the serialiser doesn’t insert an extra ␊ if it would emit `<pre>␊`. This is one of the many cases that tempts me in the direction of the XML syntax (which, to many people’s surprise, is absolutely still a thing—save a local file with extension .xhtml, or serve over HTTP with MIME type application/xhtml+xml). The fact that XML doesn’t have a parser that guesses what you meant is generally a nice feature. (XML also has whitespace collapsing, xml:space. Honestly it’s interesting in this context, conveying whitespace-handling intent, but I’ll ignore it. Because it’s never coming to HTML.) But we’re stuck with this behaviour, because it would break compatibility. And that’s where a lot of the rest of the article baffles me, because I get the general sense, from the way he presents information, that this guy doesn’t understand a lot of HTML’s history and philosophy, things I’d expect to be understood by a memory of the Angular team. The suggestions made are generally just obviously not suitable for HTML, not just because of compatibility, but also because of philosophy. You think should be different from SPACE? Sorry, I think we’re up to about forty years since that ship sailed; entities/character references are strictly shorthand, and numbered entities are strictly code points. And do you know how confusing it would be if it worked differently? It would be a one-off special case. You think you can add a new entity to handle this? In XML I think you might be able to do that (way too long since I’ve written a DTD to remember clearly), but in HTML they’re called character references, because that’s all they can be, and your non-collapsing space would need to be either something entirely new in the document model, or shorthand for something like <span style=white-space:pre-wrap> </span>. > You'd think the CMS should be able to solve this problem, but it really can't. Uh, yes it can, and they all do, where they accept plain text, by either chunking the text into HTML paragraphs (e.g. "<p>" + s/\n\n/<\/p><p>/ + "</p>"), or by turning your text line breaks into HTML line breaks (e.g. s/\n/<br>/). CMSes do a lot of dodgy stuff like this. If you want to have nightmares, look at WordPress’s wpautop function, and think through the implications of it all. It’s a radioactive wasteland of bad ideas. It’s also rather important to remember that two line breaks in HTML (e.g. <p>A<br><br>B</p>) is not the same as a paragraph break (e.g. <p>A</p><p>B</p>). Consider margins and text-indent, for a start. > How Could we Fix This? The offered solution, “quote your strings”, is what almost all programming languages tend to do. Document languages practically never quote their strings (I can’t immediately think of any even vaguely popular ones that do). Document languages consistently default to text mode, with only markup elements requiring special syntax. As is later noted, there is, of course, absolutely no chance of HTML ever doing anything even vaguely like this. And honestly, if such a breaking change were on the cards, you’d be making far more invasive changes to HTML’s syntax. > 3. HTML already breaks the rules of common text formatting. > • The idea that you can write HTML today by just typing the text you want is a lie. No it isn’t: no one ever suggested that was a feature; there was no dishonesty. HTML is a markup language. —⁂— The remark on template language whitespace control is incorrect: Say hello to {%- username -%} and welcome them to the team! You’ll actually get “Say hello toDeveland welcome them to the team!” which is clearly not what’s wanted. —⁂— For my own part, I have at times seriously considered producing HTML with only the whitespace I mean, and applying something along the lines of `:root { white-space: pre-wrap }`. But then I remember that there’s a lot more that’s dodgy around segmentation, both in the directions of extraneous and missing breaks. For example, this URL and its rendering: data:text/html,<body style=font-family:monospace;width:5ch>Look at C++!<br>X </a> Look at C+ +! X </ a> Viewing on my phone (which, due to narrower column width, is more likely to demonstrate such problems), I think I’ve come across three articles on HN in the last week or so exhibiting this sort of problem. If I were writing much that referred to C++, I would genuinely make something to change it to <nobr>C++</nobr>, and I do sometimes tweak breaking behaviour inside <code> elements to control where breaks can occur. (I’m also the kind of guy who types actual no-break spaces in Bible references where the book has an ordinal, e.g. “1 John 2:3” will have one NBSP and one SPACE.) And in the end… HTML collapsing whitespace has done a lot to quell the two-spaces-between-sentences convention some hold, so it’s not all bad. ;-)
- malaise 2y agoWhite space being broken was one of my first gripes with HTML, and that was about 25 years ago. It’s amazing to see a whole post about it finally, but also so obvious that I’m surprised to see one.
- worksonmine 2y agoThis is one of the reasons I need at least a minify step on the HTML of any site I build. Sometimes I'd prefer not to but it's the easiest solution to have both indented HTML in the source and consistent spacing in the result. I don't think it's broken though, imagine if every whitespace was rendered. And how do we know what should be collapsed? I don't see a better solution that satisfies every situation. Use <pre> to preserve the whitespace in code, for everything else use CSS.
- 65 2y agoOne thing I've always found incredibly annoying is the character is not the same width as a space. It's slightly thinner.
- calibas 2y agoThe part about <aside> is worded in a way that can be confusing. It implies that a <div> is always going to be displayed as a block, but an <aside> is some kind of special element that could be either a block or inline. Whether it's "inline", "block", or "inline-block" is determined by the CSS for every visual HTML element. A <div> is not a block, nor an <a> an inline, those are just the defaults and can be easily overridden.
- deleted 2y ago[deleted]
- thro1 2y agoWorking XMP and LISTING Tag Element Examples: http://www.the-pope.com/listin.html http://www.the-pope.com/listin.html