question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Warn on invalid HTML hierarchy

See original GitHub issue

Example

https://github.com/jennydaman/preact-p-problem/blob/707dc6fd35c5422e610202ee7d40a2c3706a6b3e/src/index.js#L10-L18

Elements inside a JavaScript list which are rendered as children of a <p> have their HTML attributes dropped and put onto other elements of the same tag found below.

This bug only affects <p>, does not happen to <div>, <span>, <b>, nor <section>.

Result

colors are in wrong place

Expected

preact-cli actually pre-renders it correctly. We can get the correct result by disabling JavaScript in the browser.

expected result with javascript disabled

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

6reactions
marvinhagemeistercommented, Mar 8, 2020

Alright, I got it 🎉 Initially I assumed that there must be a problem in preact-render-to-string but that’s not the case. It renders the correct result.

Instead the weird behaviour is actually written down in the HTML spec itself. It states:

Tag omission in text/html:

A p element’s end tag can be omitted if the p element is immediately followed by an address, article, aside, blockquote, details, div, dl, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, main, menu, nav, ol, p, pre, section, table, or ul element, or if there is no more content in the parent element and the parent element is an HTML element that is not an a, audio, del, ins, map, noscript, or video element, or an autonomous custom element.

So this means that this:

<p id="problem">
  <div style="color: red">a</div>
  <p style="color: blue">b</p>
  <div style="color: green">c</div>
</p>

will be turned into:

<p id="problem"></p>
<div style="color: red">a</div>
<p style="color: blue">b</p>
<div style="color: green">c</div>
<p></p>

At this point the DOM hierarchy has changed substantially and the <p>-tag doesn’t wrap the colored children anymore.

What’s worse is that the DOM hierarchy you’re trying to render is invalid and browsers immediately enter the “quirks”-mode, where the browser tries to guess what the developer tried to achieve with the html document. This differs from browser to browser and is somewhat undefined behaviour. It’s safe to say that the outcome is rarely what’s expected.

The reason the HTML is invalid is because a p-tag does only allow phrasing content as children, which is defined here: https://html.spec.whatwg.org/multipage/dom.html#phrasing-content-2 Putting a div tag as a child of p is therefore invalid. Same as nesting p tag. That’s invalid, too.

Following the guidelines of the spec we can use span elements as children:

export default class App extends Component {
  render() {
    return (
      <div>
        <p id="problem">
          {[
            <span style="color: red">a</span>,
            <span style="color: blue">b</span>,
            <span style="color: green">c</span>
           ]}
        </p>
        <i>Spring</i>
        <div>break</div>
        <div>is</div>
      </div>
    );
  }
}

Proof:

Screenshot from 2020-03-08 10-03-00

I’m wondering if there is a way for us to warn the user in preact/debug.

1reaction
developitcommented, Mar 12, 2020

Definitely can’t go the spec validation route here, so our options are basically limited to bailing out of non-corrective hydration when encountering tree mismatch. I have a WIP version of this locally I’ll try to extract from my progressive hydration stuff.

Read more comments on GitHub >

github_iconTop Results From Across the Web

8 Invalid HTML Elements You Should Stop Using Immediately »
1 Valid but Poorly Implemented. 1.1 DOCTYPE; 1.2 Identifying the Character Set · 2 HTML Elements to Stop Using Immediately · 3 Tasks...
Read more >
Visual Studio warns me about some invalid html attributes
I used the attributes idAffaire and idSuite for retrieving some infos later. I know the official identification attribute is "id" but in my...
Read more >
aria-invalid - Accessibility - MDN Web Docs
The aria-invalid attribute is used to indicate that the value entered into an input field is not in a format or a value...
Read more >
6 Reasons Why Google Says Valid HTML Matters
A recent tweet from Google's Gary Illyes called attention to problem of invalid HTML. Google is fine with invalid HTML.
Read more >
Validating your HTML - W3C Wiki
Validation is your early-warning system about introducing bugs into your ... When a browser encounters invalid HTML, it has to take an educated...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found