Overview

6 Markup managed

This chapter focuses on making the inside of Web Components as clean and maintainable as their public APIs. It replaces hard-to-read, concatenated or escaped multiline strings with ES2015 template literals, allowing HTML and CSS to be written naturally inside JavaScript. Through an end-to-end example, it shows how to separate concerns by moving markup and style out of the component class and into a dedicated module, so components remain small, organized, and easier to iterate on.

Building a business card component demonstrates importing a template module that exposes render, html, and css functions, then feeding it data to populate placeholders. The chapter adds template logic to generate UI from arrays (like select menus for backgrounds and logos), and introduces a simple pattern for element caching (mapDOM) so the component can reference key nodes without repeated querySelector calls. Event wiring and small controller methods then update styles in response to user choices while keeping markup and logic clearly separated.

Finally, the chapter explores “smart templating” with lit-html and, by extension, LitElement: tagged templates for treating strings as real DOM, the repeat directive for data-driven markup, and inline event bindings that reduce setup code while enabling efficient, granular DOM updates. It weighs the trade-offs of adding a dependency against gains in performance and developer ergonomics. The techniques culminate in refactoring the earlier slider into a shareable module-plus-template design, with external sizing and background styles for flexibility, and a preview of further encapsulation with Shadow DOM in a future update.

End result of the next demo: a business card that allows us to customize values like name, job, title, and so on
Initial business card layout without style yet
A business card made with HTML and CSS prior to Web Component integration
Keeping your Web Component class small by using another module
Example Node.js-based tool for automating JS module population with an existing HTML file
Results of integrated template so far
Allowing customization with the business card logo and background
Two option lists we will be adding to our component in order to customize the business card
Calling out from an HTML template to a JS function to generate menu options from an array
Mapping and caching elements from querySelector lookups to a JS object for easy reference
Using an array of items to repeat a snippet of HTML, populating a menu of options
The parts of a tagged function and how it works with a template literal
Shows our template module using lit-html, with nested html tagged functions for various content
Inline event listener to listen for menu changes and calling a function in our Web Component
The three files for the slider component

    Summary

In this chapter, you learned

  • An introduction to a new string syntax using the backtick (`) character for creating template literals. A new ES2015 feature, these template literals allow not only multiline strings with no awkward syntax, but also insertion of variables into the templated string—perfect for inserting HTML and CSS right into our JS with no tweaking required.
  • Using element caching as well as separation of code and markup for better component readability and maintainability.
  • Exploring logic-generated templates using custom JS as well as the Polymer Project's lit-html library for repeating markup from data, while additionally using lit-html to add event listeners in your HTML.
  • An example Web Component project featuring a business card customizer, focusing on visual layout and style, which enables us to examine workflows with more complex HTML and CSS.

FAQ

Why are ES2015 template literals useful for Web Component markup?They allow clean, multiline strings with indentation and embedded expressions (for example, ${name}), so your HTML and CSS read like real markup without string concatenation or escaping hassles.
How can I keep my Web Component class free of bulky HTML and CSS?Move all markup into a separate template module (for example, template.js) that exports methods like render(props), html(props), and css(props). The component then sets innerHTML (or a renderer) from Template.render(props).
Why import a JS module for templates instead of raw HTML/CSS files?Today, browsers standardize on JavaScript modules; native HTML/CSS modules are still emerging. A JS template module works everywhere now and lets you add logic alongside your markup.
What’s a good pattern for rendering HTML and CSS from a template module?Expose a render(props) function that returns the combined output of html(props) and css(props). Keep HTML and CSS in separate helpers so you can reuse or swap them independently.
How can I populate a select menu from an array of options?Create a small helper, like options(list), that loops through data and returns option tags as a string. If you use lit-html, use its repeat directive to render options directly from the array.
What is element caching (mapDOM) and why should I use it?After rendering, query elements once and store them in a plain object (for example, this.dom = Template.mapDOM(this)). This avoids repeated querySelector calls, improves readability, and isolates selector changes to one place.
Where should I attach event listeners: in the component or in the template?Both work. Traditional approach: add listeners in connectedCallback using cached refs. With lit-html, you can bind events inline in the template (for example, @change="${e => controller.updateGraphics()}") and keep setup code minimal.
What are tagged templates and how do they relate to lit-html?Tagged templates let a function process a template literal. lit-html provides an html tag that parses your template and updates only the DOM parts that change, enabling efficient re-renders.
When is lit-html preferable to setting innerHTML?Use lit-html for partial DOM updates, data-driven repetition, and inline event bindings. For small, static content that rarely changes, plain template literals plus innerHTML may be simpler.
How do I refactor an existing component (like the slider) to this approach?Split it into three files: a demo HTML, a component class module, and a template module for HTML/CSS. Cache elements via mapDOM, keep size/background styles customizable from the outside, and render via Template.render() (or lit-html) for cleaner, reusable code.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Web Components in Action ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Web Components in Action ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Web Components in Action ebook for free