Home Start Get started Build an element 1. Get set up 2. Add local DOM 3. Data binding & properties 4. React to input 5. Theming with custom properties Build an app 1. Get set up 2. Create a new page 3. Add some elements 4. Deploy Polymer Feature overview Quick tour Define elements Register an element Declare properties Instance methods Behaviors Local DOM & styling Local DOM Styling Events Handle and fire events Gesture events Data system Data system concepts Work with object and array data Observers and computed properties Data binding Helper elements Tools Tools overview Polymer CLI Document your elements Test your elements Optimize for production Publish an element Advanced tools Services What's new Release notes 1.0 Migration guide About Polymer 1.0 Resources Community Browser compatibility API Reference Polymer.Base array-selector custom-style dom-bind dom-if dom-repeat dom-template Polymer.Templatizer Global settings 2.0 Preview About Polymer 2.0 Upgrade guide App Toolbox What's in the box? Using the Toolbox App templates Responsive app layout Routing Localization App storage Service worker Serve your app Case study Shop Elements News Feature overview Quick tour
Define elements
Register an element Declare properties Instance methods Behaviors
Local DOM & styling
Local DOM Styling
Events
Handle and fire events Gesture events
Data system
Data system concepts Work with object and array data Observers and computed properties Data binding Helper elements
Tools
Tools overview Polymer CLI Document your elements Test your elements Optimize for production Publish an element Advanced tools Services
What's new
Release notes 1.0 Migration guide About Polymer 1.0
Resources
Community Browser compatibility
API Reference
Polymer.Base array-selector custom-style dom-bind dom-if dom-repeat dom-template Polymer.Templatizer Global settings

Polymer makes it simple to create web components, declaratively.

Custom elements can leverage Polymer's special features to reduce boilerplate and make it even easier to build complex, interactive elements:

  • Registering elements
  • Lifecycle callbacks
  • Property observation
  • Local DOM template
  • Data binding

In this section you can take a quick tour of the Polymer library, without installing anything. Click the Edit on Plunker button to open any of the samples in an interactive sandbox.

Tap the buttons following each feature to learn more.

To register a new element, call the Polymer function, which registers a new element with the browser. Registering an element associates a tag name with a prototype, so you can add properties and methods to your custom element. The custom element's name must contain a dash (-).

The Polymer function takes as an argument an object that defines your element's prototype.

<link rel="import"  href="https://polygit2.appspot.com/components/polymer/polymer.html">

<script>
  // register a new element called proto-element
  Polymer({
    is: "proto-element",

    // add a callback to the element's prototype
    ready: function() {
      this.textContent = "I'm a proto-element. Check out my prototype!"
    }
  });
</script>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="proto-element.html">
  </head>
  <body>
    <proto-element></proto-element>
  </body>
</html>

This sample uses a lifecycle callback to add contents to the <proto-element> when it's initialized. When a custom element finishes its initialization, the ready lifecycle callback is called. The ready callback is a great place to do constructor-like initialization work.

Learn more: element registration

Learn more: lifecycle callbacks

Many elements include some internal DOM nodes to implement the element's UI and behavior. Polymer calls this local DOM, and it provides an easy way to specify it:

<link rel="import"  href="https://polygit2.appspot.com/components/polymer/polymer.html">
<dom-module id="dom-element">

  <template>
    <p>I'm a DOM element. This is my local DOM!</p>
  </template>

  <script>
    Polymer({
      is: "dom-element"
    });
  </script>

</dom-module>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="dom-element.html">
  </head>
  <body>
    <dom-element></dom-element>
  </body>
</html>

Local DOM is encapsulated inside the element.

Learn more: local DOM

Local DOM lets you control composition. The element's children can be distributed so they render as if they were inserted into the local DOM tree.

This example creates a simple tag that decorates an image by wrapping it with a styled <div> tag.

<link rel="import"  href="https://polygit2.appspot.com/components/polymer/polymer.html">
<dom-module id="picture-frame">

  <template>
    <!-- scoped CSS for this element -->
    <style>
      div {
        display: inline-block;
        background-color: #ccc;
        border-radius: 8px;
        padding: 4px;
      }
    </style>
    <div>
      <!-- any children are rendered here -->
      <content></content>
    </div>
  </template>

  <script>
    Polymer({
      is: "picture-frame",
    });
  </script>

</dom-module>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="picture-frame.html">
  </head>
  <body>
    <picture-frame>
      <img src="https://www.polymer-project.org/images/logos/p-logo-32.png">
    </picture-frame>
  </body>
</html>

Note: The CSS styles defined inside the <dom-module> are scoped to the element's local DOM. So the div rule here only affects <div> tags inside <picture-frame>.

Learn more: Composition & distribution

Of course, it's not enough to have static local DOM. You usually want to have your element update its local DOM dynamically.

Data binding is a great way to quickly propagate changes in your element and reduce boilerplate code. You can bind properties in your component using the "double-mustache" syntax ({{}}). The {{}} is replaced by the value of the property referenced between the brackets.

<link rel="import"  href="https://polygit2.appspot.com/components/polymer/polymer.html">
<!-- import the iron-input custom element -->
<link rel="import" href="https://polygit2.appspot.com/components/iron-input/iron-input.html">

<dom-module id="name-tag">

  <template>
    <!-- bind to the "owner" property -->
    This is <b>{{owner}}</b>'s name-tag element.
  </template>

  <script>
  Polymer({
    is: "name-tag",
    ready: function() {
      // set this element's owner property
      this.owner = "Daniel";
    }
  });
  </script>

</dom-module>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="name-tag.html">
  </head>
  <body>
    <name-tag></name-tag>
  </body>
</html>

Learn more: data binding

Properties are an important part of an element's public API. Polymer declared properties support a number of common patterns for properties—setting default values, configuring properties from markup, observing property changes, and more.

In the following example, we add a declared owner property with a default value, and configure it in index.html.

<link rel="import"  href="https://polygit2.appspot.com/components/polymer/polymer.html">

<dom-module id="configurable-name-tag">

  <template>
    <!-- bind to the "owner" property -->
    This is <b>{{owner}}</b>'s configurable-name-tag element.
  </template>

  <script>
    Polymer({
      is: "configurable-name-tag",
      properties: {
        // declare the owner property
        owner: {
          type: String,
          value: "Daniel"
        }
      }
    });
  </script>

</dom-module>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="configurable-name-tag.html">
  </head>
  <body>
    <!-- configure a property from markup by setting
         the corresponding attribute                 -->
    <configurable-name-tag owner="Scott"></configurable-name-tag>
  </body>
</html>

Learn more: declared properties

In addition to text content, you can bind to an element's properties (using property-name="{{binding}}"). Polymer properties can optionally support two-way binding.

This example uses two-way binding: binding the value of a custom input element (iron-input) to the element's owner property, so it's updated as the user types.

<link rel="import"  href="https://polygit2.appspot.com/components/polymer/polymer.html">
<!-- import the iron-input custom element -->
<link rel="import" href="https://polygit2.appspot.com/components/iron-input/iron-input.html">

<dom-module id="editable-name-tag">

  <template>
    <p>
    This is a <strong>{{owner}}</strong>'s editable-name-tag.
    </p>
    <!-- iron-input exposes a two-way bindable input value -->
    <input is="iron-input" bind-value="{{owner}}"
      placeholder="Your name here...">
  </template>

  <script>
    Polymer({
      is: "editable-name-tag",
      properties: {
        owner: {
          type: String,
          value: "Daniel"
        }
      }
    });
  </script>

</dom-module>
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://polygit2.appspot.com/components/webcomponentsjs/webcomponents-lite.js"></script>
    <link rel="import" href="editable-name-tag.html">
  </head>
  <body>
    <editable-name-tag></editable-name-tag>
  </body>
</html>

Note: The is="iron-input" attribute indicates the input is a type-extension custom element; the element name is iron-input, and it extends the native <input> element.

Now that you understand these fundamental Polymer concepts, you can build your first element or explore the remainder of the Developer guide.