Skip to content

Table headers render at bottom due to HTML parser foster-parenting text markers #4

@melvincarvalho

Description

@melvincarvalho

Problem

When using html tagged templates with <table> elements, header rows render at the bottom of the table instead of the top.

render(container, html`
  <table>
    <tr><th>Name</th><th>Status</th></tr>
    ${items.map(item => html`<tr><td>${item.name}</td><td>${item.status}</td></tr>`)}
  </table>
`)

Cause

html.js uses zero-width text characters (\u200B\u200C\u200B) as placeholder markers. When parsed via innerHTML, the browser's HTML parser foster-parents text nodes out of <table>, displacing the markers and causing dynamic content to be inserted in the wrong position.

Ref: https://html.spec.whatwg.org/multipage/parsing.html#foster-parenting

Fix

Replace the text marker with an HTML comment. Comments survive inside <table>.

// Before
var HOLE = '\u200B\u200C\u200B'

// After
var HOLE = '<!--losos-->'

Update findParts to find comment nodes (nodeType === 8):

if (node.nodeType === 8 && node.textContent === 'losos') {
  var parent = node.parentNode
  var marker = document.createTextNode('')
  parent.insertBefore(marker, node)
  parent.removeChild(node)
  parts.push({ type: 'text', node: marker })
  return
}

Tested in Taskmill.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions