Hello Lisbon!

At the start of the web...

Things were simpler.

Our pages were simpler too.

Web - you've put on some weight.

JavaScript plugins

CSS libraries

float: none;

We can do better.

Let's go back in time...

Get A T-Shirt!

Elements are the building blocks of the web

Elements are encapsulated

<select>
  <option>Small</option>
  <option>Medium</option>
  <option>Large</option>
</select>

Elements are configurable

<select id="schwag">
  ...
  <option disabled>Medium</option>
  <option disabled>Large</option>
  <option selected>XX-large</option>
</select>

<select size="4" multiple>
  <option>Do</option>
  <option>Re</option>
  <option>Mi</option>
  ...
</select>

Elements are composable

<select>
  <optgroup label="German Cars">
    <option>Mercedes</option>
    <option>Audi</option>
  </optgroup>
  ...
</select>

Elements are programmable

var foo = mySelect.selectedIndex;

Good design doesn't date.

So what happened?

Tabs: a common component on the web

Building a tab component today

Pile on the JavaScript

Our HTML is terrible

Can we do better?

<x-tabs>
  <x-tab>Tab 1</x-tab>
  <x-tab>Tab 2</x-tab>
  <x-tab>Tab 3</x-tab>
</x-tabs>

It's easy to write code a browser understands. Good developers write code people can understand.

Web Components are a set of emerging standards that allow developers to extend HTML.

Templates

Custom Elements

Shadow DOM

HTML Imports

Web Components are an encapsulation mechanism, not a panacea.

Examples

Google Web Components

250+ APIS

Maps API 101

<style>
#map { height: 300px; }
</style>
<div id="map"></div>
<script src="http://maps.googleapis.com/maps/api/js">
</script>
<script>
document.addEventListener('load', function(){
  var container = document.querySelector('#map');
  var map = new google.maps.Map(container, { zoom: 14 });
});
</script>

Native Web Components

What we're used to using

<link rel="stylesheet" type="text/css" href="my-widget.css" />
<script src="my-widget.js"></script>
<div data-my-widget />
$(function() {
  $('[data-my-widget]').myWidget();
});
div.innerHTML = '<div data-my-widget />'
$(div).find('[data-my-widget]').myWidget();

Using a Custom Element

<link rel="import" href="my-widget.html" />

<my-widget></my-widget>

Creating a Custom Element

// JS
var MyElement = document.registerElement('my-element');
// or document.createElement(..)

// HTML
<my-element></my-element>
  

Extending a Custom Element

// JS
var MegaButton = document.registerElement('mega-button', {
  prototype: Object.create(HTMLButtonElement.prototype)
});

// HTML
<button is="mega-button">

Callbacks for Custom Elements

document.registerElement('my-element', {
  prototype: Object.create(HTMLElement.prototype, {

    // createdCallback, attachedCallback, detachedCallback
    attributeChangedCallback: {
      value: function(attr, oldVal, newVal) {
        this.innerHTML = 'ATTRIBUTE CHANGED!';
      }
    }

  })
});

Styling a Custom Element

<style>
  x-foo {
    display: block;
  }
  x-foo > [is="x-bar"] {
    opacity: 0;
  }
</style>

<x-foo>
    <div is="x-bar"></div>
</x-foo>

shadow = this.createShadowRoot();
shadow.innerHTML =
  "<style>span { color: green; }</style>" 
  + "<span>I'm green</span>";

Cross-browser support improving but not there yet

Polymer is a library that uses the latest web technologies to let you create custom HTML elements.

Layers of Polymer

Elements

Reusable custom elements (in progress)

Polymer

An opinionated way to work with Web Components

Platform

Web Components polyfills for all
modern browsers

Native

The current browser landscape

Using

polymer-project.org/docs/elements/

Everything is an element

HTML Elements

visual elements

non-visual elements

<script>

<title>

<link>

<style>

<template>

<datalist>

<source>

...

...

Core elements

visual elements

<core-menu> Demo

<core-toolbar> Demo

<core-pages> Demo

<core-list> Demo

<core-collapse> Demo

<core-overlay> Demo

<core-scaffold> Demo

<core-icons> Demo

...

Reusability...the non-visual elements are used to implement these!

Core elements

non-visual utility elements

Layout

layout.html

<core-layout-grid>

View

<core-media-query>

<core-pages>

<core-style>

Services / libs

<core-shared-lib>

<polymer-google-jsapi>

Data

<core-localstorage>

<core-xhr>

<core-meta>

<polymer-jsonp>

<polymer-file>

Behavior / interaction

<core-selector>

<polymer-signals>

Composability

Good engineering is making a design work with as few new pieces as possible.

<core-selector>        

is a building block for..

<my-tabs>      
<core-pages>      
<core-menu>      

Layout like a boss

Declarative layout system

flexbox...using attributes

<script src="platform.js"></script>
<link rel="import" href="layout.html">
<div layout horizontal>      
  <div>Header</div>
  <div flex>Body</div>
  <div>Footer</div>
</div>
Header
Body
Footer

Vertically aligning anything in CSS.

Axis centering

Vertical centering

<div layout horizontal center>      
  <div>Header</div>
  <div>Body</div>
  <div>Footer</div>
</div>

 

Header
Body
Footer

The Holy Grail

Centered Vertical alignment!!!

<div layout horizontal center center-justified>        
  <div>Header</div>
  <div>Body</div>
  <div>Footer</div>
</div>

 

Header
Body
Footer

Responsive design

Everything is an element

responsive design...using DOM (Bonus)

<script src="platform.js"></script>
<link rel="import" href="core-media-query.html">
<!--Phone-->
<core-media-query query="max-width: 40em" queryMatches="{{phone}}">
</core-media-query>
<!--Tablet-->
<core-media-query query="(min-width: 40.063em) and (max-width: 64em)" 
queryMatches="{{tablet}}"></core-media-query>

<template if="{{phone}}">
  ..
</template> 

<template if="{{tablet}}">
  ..
</template> 

Creating

polymer-project.org/polymer.html

Declarative element registration

Declarative registration

<link rel="import" href="polymer.html">
<polymer-element name="my-element" noscript>
  <template>
    <style>h2 { color: orange; }</style>
    <h2>Hello from my-element!</h2>
  </template>
</polymer-element>
<my-element></my-element>

Declarative extension

Declarative extension

<link rel="import" href="polymer.html">
<polymer-element extends="core-selector" name="my-tabs" 
noscript>
  <template>
    <shadow><shadow>
  </template>
</polymer-element>
<my-tabs></my-tabs>
One Two Three Four Five

Binding expressions

Binding Expressions

<polymer-element name="owner-element">
  <template>
    <h2>{{owner}} built me with Polymer</h2>
  </template>
  <script>
  Polymer({
    owner: 'Addy'
  });
  </script>
</polymer-element>
<owner-element></owner-element>

Published properties

Published properties

<polymer-element name="owner-element" attributes="owner">
  <template>
    <h2>{{owner}} built me with Polymer</h2>
  </template>
  <script>
  Polymer({
    owner: 'Addy'
  });
  </script>
</polymer-element>
<owner-element owner="Alex"></owner-element>

Automatic node finding

Automatic Node Finding

<polymer-element name="focus-element">
  <template>
    <button on-click="{{setFocus}}">Set Focus</button>
    <input id="nameInput" type="text">
  </template>
  <script>
  Polymer({
    setFocus: function() { this.$.nameInput.focus(); }
  });
  </script>
</polymer-element>

Material design.

Meaningful motion

Delightful details

Polymer + Material

Demo

http://google.com/design

WebComponents.org

Hopefully you're excited.

GO COMPONENTIZE THE WEB!

<thank-you>