What do you want to learn?
Leverged
jhuang@tampa.cgsinc.com
Skip to main content
Pluralsight uses cookies.Learn more about your privacy
HTML5 Web Component Fundamentals
by Cory House
Learn how to use the Shadow DOM, Custom Elements, Templates, and Imports to create reusable web components.
Resume CourseBookmarkAdd to Channel
Table of contents
Description
Transcript
Exercise files
Discussion
Learning Check
Recommended
Five Problems, One Solution
Intro
Hi, and welcome to HTML5 Web Component Fundamentals. I'm Cory House with Pluralsight. You can reach me on my blog at bitnative.com or catch me on Twitter: @housecor. Today's web developers have some big problems, and that's why I'm really excited to bring you this course on HTML5 Web Components. I believe web components are going to radically improve the way that we write applications today. So what sorts of problems am I talking about? Let's walk through five specific problems that web developers face today.
Problem 1: Undescriptive Markup
The first problem is most of our markup isn't descriptive, it's highly generic. Just look at the source of Gmail. Note the divs nested more than a dozen layers deep. Using the developer tools it's really obvious when you look at the layers of nesting, html, body, then div div, div, div, div, div. I could go on, but div soup is the problem. Divs mean nothing, all they say is this element is a block. And Gmail isn't alone with having a sea of divs in its markup. Twitter is the same story. As you can see, there are least nine layers of divs in the markup for Twitter. Wouldn't it be nice if this markup were more descriptive and less generic? One last example, check out StackOverflow, again, div soup, but do note that StackOverflow has done a great job of at least providing useful IDs and class names on different elements. This certainly helps the maintenance programmer navigate the markup, but it's still composed of deeply nested divs at least nine layers deep. You've likely heard about the importance of the semantic web over the years. Semantics is the study of meaning in language, and the semantic web is important because it helps convey the meaning of your content. The generic div tag conveys no meaning about what lies inside.
Problem 2: Style Conflicts
Have you ever had a plan to take family pictures, and you have this vision of well-behaved children and proper coordinating outfits, and as developers, we have the same dreams of creating clean, professional-looking components with a polished style. We want things to look crisp and for things to flow. And then you go pull in the giant centralized application style sheet, and ah, what happened, that's not at all what I envisioned. When everyone is free to do their own thing, style clashes are a real risk. So problem #2 is styling conflicts. Today's HTML5 components struggle with avoiding CSS conflicts. We envision cohesive styles like this, but if we're not really careful, we may end up with this. Other people's styles end up ruining our vision, and because there's no way to encapsulate styles for a given component, there's no way to ensure that other styles on the page won't accidentally break the styling of any components that we use or write ourselves. So, we're forced to bloat our CSS and markup with very specific selectors or even resort to the use of hacks like !important to ensure our styles are applied as expected. The bottom line is, we have no guarantee that other styles won't accidentally conflict with ours, so we have to be extremely specific when writing styles and markup for useable components. This adds unfortunate bloat to our markup and our style sheets.
Problem 3: No Native Templates
Problem #3 is that we have no native templates. Today's HTML template solutions are clunky. There's no native way for us to import inert HTML that we can use for templates. We understand that it's easy to import JavaScript with a script tag, styles with a link or style tag, and images with image tag, but what if we want to import HTML on the page? There's no native mechanism designed to offer the support by design, so we tend to resort to various hacks, and people try to solve their problems in their own way. So we slap HTML in script tags with a different type like "text/html" or you'll see third party libraries invent their own script type. This approach doesn't utilize native DOM and it risks Cross-Site Scripting issues. We also store HTML and hidden DOM elements and manually extract the markup as necessary. But this leads to styling struggles and various ad hoc methods for hiding and storing the markup out of view. We also iframe sometimes to try to get separate scope and styling, but these iframes go far beyond mere encapsulation, making frequent interactions between the iframe and the hosting page awkward.
Problem 4: No Bundling
Problem #4 is, we have no bundling. There's no native way to bundle our dependencies together into a single call. What if you want to bundle some CSS, JavaScript, and HTML together? For example, today if you want to use a framework that has a variety of dependencies, you have to add a reference to each dependency line-by-line in the proper logical order. Think about Bootstrap. If you build something with Bootstrap, you need five references, three for Bootstrap and two for separate JavaScript and CSS files that contain your implementation. What we need is a simple way to request all of these items as a named reusable bundle on a single line.
Problem 5: No Standard
Problem #5 is, there is no standard. This problem really sums up all the other problems. The bottom line is we have no standard for creating components with HTML5, JavaScript, and CSS today. Each of these libraries offer their own approach for creating HTML-based components. And the differences are obvious, because if you want to use more than one of these at the same time, you'll find it's a struggle because they solve problems in such different ways. Each offers its own API and utilizes a proprietary approach to publishing and configuring components. So when we change vendors, we must learn each new libraries convention. There's a wide variety of abstraction levels above as well, ranging from the simplicity of jQuery plugins, all the way up to the heavy and opinionated components of ExtJS. Many of these libraries utilize large complex style sheets as well, with highly specific selectors to avoid conflicting with other markup on your page. See, other industries have solved this problem of reusable components. Car manufacturers don't buy raw diodes, capacitors, etc. They buy radios, they buy navigation systems, much larger and more powerful components. Think of BMW. Like all manufacturers, it reuses components between cars, the blinker stock, the push-button start, door handles, the stereo, steering wheel buttons, seat belt assemblies, and airbag systems. What if all vehicles started with a clean slate and simply used raw plastic and metal. Cars would cost far more money, because it would take much more work for the manufacturers truly having to design and build each model completely from scratch. This interior is made up of components, and as the automotive industry grows, they'll continue to use larger components. In fact, many of today's vehicles even utilize the same engines, transmissions, and platforms. This phenomenon isn't even unique to the automotive industry. Component size and complexity tends to grow as industries mature, and industries grow by utilizing ever more powerful abstractions. In the same way we used to build our apps from the ground up using plain HTML, JavaScript, and CSS. Then people started using jQuery plugins and components like jQuery UI, Kendo UI, and ExtJS. However, the current state of components in web development lacks a strong formal standard. Reuse across manufacturers requires standards, and this is why it feels awkward and wasteful when we want to utilize components from multiple companies. We have to learn the ad hoc way that each manufacturer has designed their components. consider a brief history of web development and the increasing levels of abstraction are pretty clear. We're certainly headed down the right path, albeit very slowly. In 1995, Brendan Eich created JavaScript. For years it was a real struggle because browsers were so inconsistent and JavaScript was largely misunderstood or ignored in these early phases. Fast forward a decade and John Resig created jQuery. jQuery finally made working with the DOM much less painful by providing abstractions over the native APIs that were consistently cross browser. This single library radically changed the trajectory of JavaScript's future by providing people higher level components. In this case, in the form of simple terse functions that interact with the DOM, among other rich features. And it was upon this foundation of success, that jQUery UI was created, offering a library of higher level reusable components, including tabs, accordions, dialogs, and many other components that we were previously often building ourselves. The jQuery plugin community began to thrive, offering many developers the chance to simply add an extra JavaScript file to their page to enjoy richer components. Competitors like ExtJS also arrived on the scene about this time, offering developers richer and higher-level controls than we'd seen previously. By 2011, there were many mature component options like Kendo UI and Bootstrap. Bootstrap helped popularize the idea of componentized CSS, and Kendo UI began offering powerful grids for paginating, sorting, and filtering data, and even schedulers for easily creating interactive calendars. Around this same time, Angular was released, offering a proprietary way to define components that it calls directives. More recently, other proprietary component options have popped up, like Ember Components, and Knockout Components. And today we can finally begin enjoying the power of native HTML5 Web Components. HTML5 Web Components are a powerful standards-based solution that should help radically improve the power and reusability of these existing solutions, and also empower us to build our own. As you can see, the theme is that over time the components that we use to get started just keep growing in power, and they keep moving higher up the abstraction layer. We started out using plain JavaScript. We moved to jQuery, which was basically a friendly abstraction over much of the JavaScript that we were struggling to write. Then we moved on to ever higher levels of components to solve problems, However, despite the greatness of all these technologies, these current component solutions all struggle with the aforementioned fundamental problems.
The Solution: Web Components
So in summary, today's components have 5 core problems. They lack descriptive markup, so they're typically composed of mostly divs and spans, there's no standard, so each time you decide to choose a component library you have to learn how the authors have chosen to structure their vision of reusable components. And since there's no way to encapsulate the styling for a given component, they suffer from style conflicts that require complex and verbose style sheets and class structures to avoid accidentally manipulating styles on pages. There's no native standard for defining client-side templates either, so each library defines their own approach, and we as developers resort to various proprietary approaches as well. Finally, there's no native way to bundle the HTML, JavaScript and CSS that's necessary to build a component together into a single unit that we can include on the page with a single line of markup. You see the punch line coming. The great news is there is a solution, and the solution is HTML5 Web Components. Web Components are built using a combination of these four new technologies, Templates, Custom Elements, the Shadow DOM, and HTML5 Imports. These are the four technologies that we'll explore throughout this course. Templates allow us to define inert, reusable markup using web standards. We'll discuss templates in module 2. Custom Elements give us the power to extend HTML by defining our own elements. We'll explore Custom Elements in module 3. The Shadow DOM provides encapsulation of our markup and our styling. The Shadow DOM is a huge topic, so I've split it up into three separate modules. Module 4 covers Shadow DOM Fundamentals, module 5 covers Shadow DOM insertion points and events, and module 6 discusses the new CSS styling techniques that are related to the Shadow DOM. And finally, HTML5 Imports support bundling HTML, JavaScript, and CSS files together into a single, simple, reusable package so we can easily deliver web components that we create. We'll cover Imports in module 7. These four technologies work together to create HTML5 Web Components, and will be the focus of this course.
Browser Support
I'll warn you, these technologies aren't yet supported in all major browsers at the time of this recording, so throughout this course I suggest using Google Chrome to test out the components that we create. Google took a leading role in the Web Component spec, so Chrome was the first browser to boast full native support for Web Components. While other browsers may have caught up with Chrome by the time you're viewing this course, I suggest using the latest version of Chrome throughout this course to assure that the demos we're walking through work for you. To keep track of the latest status of Web Components support, check out Jon Rimmer's website at this URL. As you can see, at the time of this recording all of the four core pillars of Web Components are fully specified and supported natively in both Chrome and Opera, and they can be polyfilled for use in all modern browsers using the webcomponents.js polyfill library. We'll discuss this polyfill library briefly in module 7. As you can see on this chart, the webcomponents.js polyfill adds support for all four of the core Web Component technologies to today's modern browsers. In addition, there are interesting libraries that make it easier and faster to create web components like Polymer and X-Tag. But before you learn these libraries, it's important to learn the native specification that we're exploring throughout this course first. I'll use an analogy to help explain why.
Why Learn Web Components First?
So why learn native Web Components first? Well, remember a few years ago when jQuery had become so popular that new developers were learning jQuery instead of learning JavaScript first. It became more common for people to ask if you knew jQuery than to hear if you knew JavaScript. That was a problem, and it's a problem because just like in school, it's important to learn the foundation before learning the abstraction. Not understanding the abstraction means that you're stuck when the abstraction leaks. What do I mean by leaks? Well an abstraction leaks when it expects the user to understand the underlying technology which is being abstracted. So, for example, jQuery would sometimes leak and require someone to understand the underlying quirks in JavaScript or cross-browser issues. When these issues occur, it's important to understand the foundation so that you can address the issue and move on. JavaScript is the foundation, jQuery is an abstraction over that foundation, so it's important to learn the foundation first. In the same way, Web Components are the foundation. They're the native technology that we'll be using for many years to come, so it's critical to learn the foundation of the Web Component specification before you try to learn abstractions like Polymer. Polymer is a project from Google. It's in developer preview at the time of this recording. Polymer offers a variety of handy features for working with Web Components, and similar to the relationship between JavaScript and jQuery, Polymer is an abstraction over the Web Components specification. So the foundation that you'll receive on Web Components throughout this course will help make you successful in any technologies that rely upon the Web Components standard in the future. In fact, in the future you're likely to find that popular JavaScript frameworks slowly become a layer over the Web Components standard.
Selecting a Level of Abstraction
So before we dive in, let's consider what level of abstraction makes sense when creating Web Components. My short answer, any level, low level to entire app, yes, you can encapsulate an entire application into a web component, and that component could of course be composed of many smaller components. So imagine you created a billing system application. You could create a component that encapsulates the entire application if you like. Since it's a billing application, perhaps you'd decide to prefix all your custom element names with the word bill. So you could call the component that delivers the application, bill-app, and that component could compose together more granular components that handle smaller pieces of the app, maybe bill-header and bill-body, and that header might be composed of a navigation bar and an avatar of the currently logged in user, you get the idea. Now you certainly aren't obligated to make your entire app into a single component. You might simply find Web Components useful for creating very small reusable components, like search inputs, tab navigation, or other small reusable pieces of interface. There's no right answer here, but think carefully about the level of abstraction that is useful for your project. When you start thinking about the web as a nested set of components, it starts to really change the way you write your markup and compose your pages. Here's an Author page, oh, it just happens to be mine, nice, okay. So what components do we see here? Well, there's a header across the top, and that header is really helping integrate two separate sites, Pluralsight and Digital Tutors, so this could be an integration-header element. Jumping down here to the list of courses, each of these could be a Pluralsight course-listing component, and that component might have attributes like Course Level, Date, and Rating. Of course, some of these components are complicated and would warrant their own component. You can imagine the Pluralsight star-rating component could be composed within a Pluralsight course-listing component, and this entire page could be wrapped up as an author-page component. You could just set an author attribute on the author-page component, and it would make the call to retrieve the information that you need. It's, of course, not required, but this is just an example of how high-level you could go if desired. And since you can compose components within components, deep nesting is a practical option to consider.
The Dawn of the Democratic Web
In summary, I believe Web Components will democratically grow the web from the bottom up. We're moving control over the future of the web from a small group of people who work within standards bodies like the W3C and the Web Hypertext Application Technology Working Group, and instead empowering every developer to create ever more powerful components for building the web. Web Components get around the bottleneck of waiting for standards organizations by giving web developers the power to introduce new declarative elements. We're going to see communities rally around components, and major existing component vendors like Telerik and ComponentOne are likely to release Web Component based versions of their existing components. In this new world, GitStars and downloads will measure interest in specific components, and will likely be considered by standards bodies for determining which components should be considered for becoming native HTML elements in future versions of the HTML specification. And since standards bodies will consider the interest in existing web components when deciding which elements should be added, future web browsers are likely to provide native alternatives to components that become very popular. Web Components will create a rich feedback loop, where standards bodies regularly consider which of the most popular web components should become native element. This should produce a bright future where web application developers enjoy ever more powerful solutions with less boiler-plate configuration and complexity.
Summary: Why Web Components?
So bottom line, why Web Components? Well, Web Components will make our markup easier to read, navigate, and understand. It will help replace generic tags like divs and spans with higher level and more descriptive markup that's easier to navigate and maintain. We'll no longer have to start from the beginning on each new project. We can easily leverage components created during previous projects, and reach out to the community to leverage existing components as well. Web Components honor the Unix philosophy. They emphasize building simple, clear, modular, and extendable code that can be easily maintained and re-purposed by developers that aren't the initial creators. When bugs are found in our components, it'll be easier to replace and upgrade the code, since it'll be properly bundled, encapsulated, and centralized. And since we're more likely to share and reuse each other's components in the future, more developers will use each line of code, which should help reduce the number of bugs that are in our components. And since HTML Imports make it so easy to import a bundle of dependencies, we're less likely to struggle with integration problems on our projects. We'll simply add a single line to the top of our file, and get everything we need to run the component on our page. Finally, the API for interacting with the components that we create will be much clearer than today's compromised solutions. The components will feel native, which should greatly reduce the learning curve when picking up new components that you haven't seen before. As we're about to see, HTML5 Web Components usher in a new exciting era in web development. They're going to dramatically change the way that we build web apps, and I believe Web Components mark the biggest change in a web developer's fundamental toolset since around 2005 when the term AJAX was coined. And yes, I know that's an audacious statement. The componentized web is going to radically increase the speed of innovation and web development by empowering us to create and share ever more robust components to build rich web applications. Web Components removes standards organizations as a bottleneck to innovation, by empowering individuals to create the tags that they need today. It's a bright future, so let's get rolling.
Templates
Intro
Hi, I'm Cory House with BitNative Consulting and in this module on HTML5 Web Components, we'll discuss the first of four core new technologies for building web components, and that's Templates. Templates aren't a new concept. You're almost certainly already using a templating solution today to build web applications, and in this module we'll quickly discuss the existing templating strategies on both the client and the server. Then we'll explore the new HTML5 Template tag and see how it finally provides a formal, inert, and standards-based approach to storing reusable snippets of markup on the client. We'll review examples of activating templates, injecting data into templates, and also learn how to handle nested templates. So, there you go, that's the Template for this module. I'd like to apologize, that was an awful pun, I should probably cut that. Okay, let's get rolling. I'm sure you already understand what templates are. They're a way to define a preset format for reuse, and all sorts of server-side technologies offer a template-like solution. HAML is popular if you're in Ruby or PHP. If you're in ASP.NET MVC, then the Razor View Engine is a popular templating option. Python developers are likely familiar with Django, and Node developers often use Jade. The point is, there's a huge number of server-side solutions for templating. These days it's becoming increasingly common to render the UI on the client, but up until now the web has offered no standardized support for defining templates that are parsed on the browser. As we discussed in the introduction, today we have simple and elegant ways to reference assets that help us build web apps. We use the