SlideShare a Scribd company logo
1 of 164
Download to read offline
Polymer-Powered Design Systems
DevFest Florida - November 11, 2017
John Riviello
@JohnRiv
© Comcast
© Comcast
© Comcast
© Comcast
© Comcast
© Comcast
"Notebook beside the iPhone on Table" by PicJumbo is licensed under CC0 1.0
WHY?!?
1. Communication
2. Deviations
"Alone" by Pixabay is licensed under CC0 1.0
“Designers should build
products that solve needs
instead of spending time on
reinventions”
- Jack Zankowski
Creative Director, Comcast XD
"Mask, Ancient Artifact" by Pedro_Teixeira is licensed under CC0 1.0
"Abstract Business Code" by Pixabay is licensed under CC0 1.0
“And You Thought
Buttons Were Easy?”
- Nathan Curtis
Source: https://medium.com/eightshapes-llc/and-you-thought-buttons-were-easy-26eb5b5c1871
Source: https://medium.com/eightshapes-llc/and-you-thought-buttons-were-easy-26eb5b5c1871
$100/hour x 200 hours =
$20,000
Source: https://medium.com/eightshapes-llc/and-you-thought-buttons-were-easy-26eb5b5c1871
$20,000 x 50 teams =
$1,000,000
Source: https://medium.com/eightshapes-llc/and-you-thought-buttons-were-easy-26eb5b5c1871
$20,000 x 50 teams =
$1,000,000
"Books on Shelf in Library" by Pixabay is licensed under CC0 1.0
76 contributors
200 contributors
542 contributors
“A design system’s value is
realized when products ship
features using parts from
the system.”
- Nathan Curtis
Source: https://medium.com/eightshapes-llc/a-design-system-isn-t-a-project-it-s-a-product-serving-products-74dcfffef935
Design
System
Design &
Development
Source: http://atomicdesign.bradfrost.com/chapter-5/
Website
Pattern
Library
Make changes to a pattern
Applications and pattern library
both update to reflect changes
Google Polymer Project
#UseThePlatform
- Polymer Motto
Existing Frameworks
Applications
Web Platform
Web Components built with Polymer (or not)
What Are
Web Components?
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv35
4 Specs
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv36
Custom Elements
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv37
Custom Elements
•Provides a way for authors to build their own
fully-featured DOM elements.
- <xc-tab>Your Wifi</xc-tab>
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv38
HTML Imports
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv39
HTML Imports
• Means to import custom elements
- <link rel="import" href="../xc-tab/xc-tab.html">
• Built-in deduplication
• Componetize the HTML, CSS & JavaScript
• Will be replaced by ES6 Modules
- import "../xc-tab/xc-tab.js"
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv40
Templates
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv41
• Used to declare fragments of HTML
- <template id="tab">
<div class="tab-content"></div>
</template>
• The element itself renders nothing
• Can be cloned and inserted in the document via
JavaScript, which will render the content
Templates
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv42
Shadow DOM
What Are Web Components?
Polymer-Powered Design Systems - @JohnRiv43
•Allows you to take a DOM subtree and
hide it from the document scope
•Hides CSS styles as well
•Common examples from HTML5 include:
<select>, <video>, & <input type="date">
Shadow DOM
Source: https://www.webcomponents.org/element/PolymerElements/paper-tabs
Source: https://ebidel.github.io/material-playground/
How do I build my
Design System
using Polymer?
“A style guide is an artifact of design
process. A design system is a living,
funded product with a roadmap &
backlog, serving an ecosystem.”
- Nathan Curtis
Source: https://twitter.com/nathanacurtis/status/656829204235972608
You Need a TeamYou Need a Team
“Establish a high-quality,
brand-aligned experience across
our product through human
guidance and internal tools.”
- Jina Anne
Source: https://medium.com/salesforce-ux/the-salesforce-team-model-for-scaling-a-design-system-d89c2a2d404b
Salesforce.com Design Systems Team Objective:
"Person Workshop" is licensed under CC0 1.0 / Adjusted from original
Building Your Design System with Polymer
CSS
IS
AWESOME
Polymer-Powered Design Systems54
Source: https://philipwalton.github.io/talks/2015-10-26/#7
• Managing global names
• Scoping/isolating styles
• Specificity conflicts
• Unpredictable matching
• Managing style
dependencies
• Removing unused code
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Import Polymer.Element
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Styles we’ll be modifying
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Template contains <p>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Polymer Boilerplate
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
index.html:
<!doctype html>
<html>
<head>
<title>Shadow DOM Demo</title>
<script
src="bower_components/webcomponentsjs/webcomponent
s-loader.js"></script>
<link rel="import" href="my-element.html">
<style>
/* Main Document Styles */
</style>
</head>
<body>
<my-element></my-element>
<p>Paragraph in the main document</p>
</body>
</html>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
index.html:
<!doctype html>
<html>
<head>
<title>Shadow DOM Demo</title>
<script
src="bower_components/webcomponentsjs/webcomponent
s-loader.js"></script>
<link rel="import" href="my-element.html">
<style>
/* Main Document Styles */
</style>
</head>
<body>
<my-element></my-element>
<p>Paragraph in the main document</p>
</body>
</html>
Load Polyfills (if needed)
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome/p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
index.html:
<!doctype html>
<html>
<head>
<title>Shadow DOM Demo</title>
<script
src="bower_components/webcomponentsjs/webcomponent
s-loader.js"></script>
<link rel="import" href="my-element.html">
<style>
/* Main Document Styles */
</style>
</head>
<body>
<my-element></my-element>
<p>Paragraph in the main document</p>
</body>
</html>
Import my-element.html
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
index.html:
<!doctype html>
<html>
<head>
<title>Shadow DOM Demo</title>
<script
src="bower_components/webcomponentsjs/webcomponent
s-loader.js"></script>
<link rel="import" href="my-element.html">
<style>
/* Main Document Styles */
</style>
</head>
<body>
<my-element></my-element>
<p>Paragraph in the main document</p>
</body>
</html>
Styles we’ll be modifying
index.html:
<!doctype html>
<html>
<head>
<title>Shadow DOM Demo</title>
<script
src="bower_components/webcomponentsjs/webcomponent
s-loader.js"></script>
<link rel="import" href="my-element.html">
<style>
/* Main Document Styles */
</style>
</head>
<body>
<my-element></my-element>
<p>Paragraph in the main document</p>
</body>
</html>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Body contains <my-element> & <p>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-element">
<template>
<style>
/* My Element Styles */
</style>
<p>Shadow DOM is awesome</p>
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
index.html:
<!doctype html>
<html>
<head>
<title>Shadow DOM Demo</title>
<script
src="bower_components/webcomponentsjs/webcomponent
s-loader.js"></script>
<link rel="import" href="my-element.html">
<style>
/* Main Document Styles */
</style>
</head>
<body>
<my-element></my-element>
<p>Paragraph in the main document</p>
</body>
</html>
Flattened DOM Tree:
<body>
<my-element>
#shadow-root (open)
<style>...</style>
<p>Shadow DOM is awesome</p>
</my-element>
<p>Paragraph in the main document</p>
</body>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
p {
border: 3px solid #f60;
}
</style>
index.html:
<style>
p {
background-color: #9cf;
}
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
}
p {
border: 3px solid #f60;
}
</style>
:host selector
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
}
p {
border: 3px solid #f60;
}
</style>
Flattened DOM Tree:
<body>
<my-element>
#shadow-root (open)
<style>...</style>
<p>Shadow DOM is awesome</p>
</my-element>
<p>Paragraph in the main document</p>
</body>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
}
p {
border: 3px solid #f60;
}
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
}
p {
border: 3px solid #f60;
}
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
}
</style>
See https://developers.google.com/web/updates/2016/06/css-containment for more information on contain
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
See https://developers.google.com/web/updates/2016/06/css-containment for more information on contain
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
:host([disabled]) {
outline-color: #ccc;
}
:host([disabled]) > p {
border-color: #ccc;
} ...
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
:host([disabled]) {
outline-color: #ccc;
}
:host([disabled]) > p {
border-color: #ccc;
} ...
</style>
index.html:
<my-element></my-element>
<p>Paragraph in the main
document</p>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
:host([disabled]) {
outline-color: #ccc;
}
:host([disabled]) > p {
border-color: #ccc;
} ...
</style>
index.html:
<my-element disabled></my-element>
<p>Paragraph in the main
document</p>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
:host([disabled]) {
outline-color: #ccc;
}
:host([disabled]) > p {
border-color: #ccc;
} ...
</style>
index.html:
<my-element></my-element>
<p>Paragraph in the main
document</p>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
index.html:
<my-element></my-element>
<p>Paragraph in the main
document</p>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
index.html:
<style>
p { background-color: #9cf; }
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
my-element { outline-color: red; }
</style>
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
my-element { outline-color: red; }
my-element p {
border-color: blue;
}
</style>
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
index.html:
<style>
p { background-color: #9cf; }
</style>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
index.html:
<my-element></my-element>
<p>Paragraph in the main
document</p>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
index.html:
<my-element>
<ul>
</ul>
</my-element>
<p>Paragraph in the main
document</p>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
</style>
index.html:
<my-element>
<ul>
<li>This is Light DOM</li>
<li>It needs a slot</li>
</ul>
</my-element>
<p>Paragraph in the main
my-element.html:
<template>
<style> ... </style>
<p>Shadow DOM is awesome</p>
</template>
Rendered Result:
Shadow DOM is awesome
Paragraph in the main document
index.html:
<my-element>
<ul>
<li>This is Light DOM</li>
<li>It needs a slot</li>
</ul>
</my-element>
<p>Paragraph in the main
my-element.html:
<template>
<style> ... </style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<template>
<style> ... </style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
Flattened DOM Tree:
<body>
<my-element>
#shadow-root (open)
<style>...</style>
<p>Shadow DOM is awesome</p>
<slot>
<ul>
<li>This is Light DOM</li>
<li>It needs a slot</li>
</ul>
</slot>
</my-element> ...
my-element.html:
<template>
<style> ... </style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
Flattened DOM Tree:
<body>
<my-element>
#shadow-root (open)
<style>...</style>
<p>Shadow DOM is awesome</p>
<slot>
<ul>
<li>This is Light DOM</li>
<li>It needs a slot</li>
</ul>
</slot>
</my-element> ...
my-element.html:
<template>
<style> ... </style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<template>
<style>
...
::slotted(ul) {
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
::slotted() selector
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
::slotted(ul > li) {
color: red;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
</style>
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
li { color: red; }
</style>
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
ul { color: red; }
</style>
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
color: blue;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
ul { color: red; }
</style>
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
color: blue;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
</style>
my-element.html:
<template>
<style>
...
::slotted(ul) {
margin: 0;
}
</style>
<p>Shadow DOM is awesome</p>
<slot></slot>
</template>
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
</style>
my-element.html:
<template>
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
::slotted(ul) { ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
</style>
my-element.html:
<template>
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
::slotted(ul) { ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
body { color: green;
font-family: Calibri; }
p { background-color: #9cf; }
my-element.html:
<template>
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
color: initial;
}
p {
border: 3px solid #f60;
margin: 0;
}
::slotted(ul) { ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
body { color: green;
font-family: Calibri; }
p { background-color: #9cf; }
my-element.html:
<template>
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
all: initial;
}
p {
border: 3px solid #f60;
margin: 0;
}
::slotted(ul) { ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
body { color: green;
font-family: Calibri; }
p { background-color: #9cf; }
CSS
Custom Properties"Chameleon" by George is licensed under CC0 1.0
CSS Custom Properties
Basic usage:
<style>
html {
/* Define a Custom Property */
--body-text-color: gray;
}
Polymer-Powered Design Systems106
CSS Custom Properties
Basic usage:
<style>
html {
/* Define a Custom Property */
--body-text-color: gray;
}
p {
/* Use a Custom Property */
color: var(--body-text-color);
}
</style>
Polymer-Powered Design Systems107
CSS Custom Properties
Basic usage:
<style>
html {
/* Define a Custom Property */
--body-text-color: gray;
}
p {
/* Use a Custom Property with a fallback value */
color: var(--body-text-color, navy);
}
</style>
Polymer-Powered Design Systems108
CSS Custom Properties
Basic usage:
<style>
html {
/* Define a Custom Property */
--body-text-color: gray;
}
p {
/* Use a Custom Property with multiple fallback values */
color: var(--body-text-color, var(--p-text-color, navy));
}
</style>
Polymer-Powered Design Systems109
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid #f60;
margin: 0;
}
::slotted(ul) {
margin: 0; ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
</style>
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
}
::slotted(ul) {
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
p { background-color: #9cf; }
</style>
my-element.html:
<style>
:host {
outline: 3px dashed blue;
display: block;
contain: content;
}
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
}
::slotted(ul) {
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
html { --my-element-border-color:
purple; }
p { background-color: #9cf; }
• Name colors: --xc-blue-sky: #0272B6;
• Set variables for usage: --xc-link-color: var(--xc-blue-sky);
• Useful to name Custom Property hooks in the format of
--element-property: var(--my-element-border-color, #f60);
• Besides colors, gaps and/or padding factors are useful:
--xc-main-gap: 16px; --xc-large-gap: 24px;
padding: var(--xc-main-gap); padding: calc(1.5*var(--xc-main-gap));
CSS Custom Properties Tips
Polymer-Powered Design Systems113
CSS Mixins"Mix Colorful Color" is licensed under CC0 1.0
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
Import polymer.html or add
shadycss/apply-shim.html
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
Use `@apply` to add the mixin hook
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
Polymer CSS Mixin Format:
<custom-style>
<style>
selector {
--mixin-name: {
/* rules */
};
}
</style>
</custom-style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
html {
--my-element-border-color: purple; }
}
p { background-color: #9cf; }
...
</style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<style>
html {
--my-element-p {
background: red;
font-style: italic;
}; ...
} ... </style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
Style in my-element.html after shim is applied:
<style>
p {
border: 3px solid var(--my-element-border-color, #f60);
margin: 0;
background: var(--my-element-p_-_background);
font-style: var(--my-element-p_-_font-style);
}
</style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
Style in my-element.html after shim is applied:
<style>
p {
border: 3px solid var(--my-element-border-color, #f60);
margin: 0;
background: var(--my-element-p_-_background);
font-style: var(--my-element-p_-_font-style);
}
</style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
Style in my-element.html after shim is applied:
<style>
p {
border: 3px solid var(--my-element-border-color, #f60);
margin: 0;
background: var(--my-element-p_-_background);
font-style: var(--my-element-p_-_font-style);
}
</style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
Style in my-element.html after shim is applied:
<style>
p {
border: 3px solid var(--my-element-border-color, #f60);
margin: 0;
background: var(--my-element-p_-_background);
font-style: var(--my-element-p_-_font-style);
}
</style>
Style in index.html after shim is applied:
<custom-style> <style>
html {
--my-element-border-color: purple;
--my-element-p_-_background: red;
--my-element-p_-_font-style: italic;
}
</style> </custom-style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
Style in my-element.html after shim is applied:
<style>
p {
border: 3px solid var(--my-element-border-color, #f60);
margin: 0;
background: var(--my-element-p_-_background);
font-style: var(--my-element-p_-_font-style);
}
</style>
Style in index.html after shim is applied:
<custom-style> <style>
html {
--my-element-border-color: purple;
--my-element-p_-_background: red;
--my-element-p_-_font-style: italic;
}
</style> </custom-style>
my-element.html:
<link rel="import"
href="bower_components/polymer/
polymer.html">
...
<style> ...
p {
border: 3px solid
var(--my-element-border-color,
#f60);
margin: 0;
@apply --my-element-p;
} ...
Rendered Result:
Shadow DOM is awesome
• This is Light DOM
• It needs a slot
Paragraph in the main document
index.html:
<custom-style> <style>
html {
--my-element-p: {
background: red;
font-style: italic;
}; ...
} ... </style> </custom-style>
Style in my-element.html after shim is applied:
<style>
p {
border: 3px solid var(--my-element-border-color, #f60);
margin: 0;
background: var(--my-element-p_-_background);
font-style: var(--my-element-p_-_font-style);
}
</style>
Style in index.html after shim is applied:
<custom-style> <style>
html {
--my-element-border-color: purple;
--my-element-p_-_background: red;
--my-element-p_-_font-style: italic;
}
</style> </custom-style>
• Used for setting styles in the main document, either:
- Declared directly in the main document, or
- Hoisted to the main document from an import
• When would you want to include them in an import?
- @font-face rules
- Theming (declaring common variables & mixins)
• <custom-style> & @apply can be loaded on their own via
ShadyCSS (see https://github.com/webcomponents/shadycss)
More <custom-style> notes
Polymer-Powered Design Systems129
• This warning is unavoidable when using <custom-style>:
• If you’re using at least Polymer 1.10.1 or 2.1.1, you’re good
More <custom-style> notes
Polymer-Powered Design Systems130
• Style Modules are Polymer’s way of sharing styles among
Polymer Components
• The styles are actually copied into the Shadow Root of the
component they are included in
- So only include what you actually need
• Great way of sharing form element styles like buttons
Another way to share styles: Style Modules
Polymer-Powered Design Systems131
my-button-styles.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-button-styles">
<template>
<style>
button {
background: #fff;
border: 3px solid rebeccapurple;
color: rebeccapurple;
text-decoration: none;
}
button:hover {
background: rebeccapurple; color: #fff;
}
button:focus {
color: navy; background: powderblue;
}
</style>
</template>
</dom-module>
my-button-styles.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-button-styles">
<template>
<style>
button {
background: #fff;
border: 3px solid rebeccapurple;
color: rebeccapurple;
text-decoration: none;
}
button:hover {
background: rebeccapurple; color: #fff;
}
button:focus {
color: navy; background: powderblue;
}
</style>
</template>
</dom-module>
Declare styles in a dom-module with an `id` attribute
my-button-styles.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-button-styles">
<template>
<style>
button {
background: #fff;
border: 3px solid rebeccapurple;
color: rebeccapurple;
text-decoration: none;
}
button:hover {
background: rebeccapurple; color: #fff;
}
button:focus {
color: navy; background: powderblue;
}
</style>
</template>
</dom-module>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<link rel="import" href="my-button-styles.html">
<dom-module id="my-element">
<template>
<style include="my-button-styles">
/* Element-specific CSS goes here */
</style>
...
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
my-button-styles.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-button-styles">
<template>
<style>
button {
background: #fff;
border: 3px solid rebeccapurple;
color: rebeccapurple;
text-decoration: none;
}
button:hover {
background: rebeccapurple; color: #fff;
}
button:focus {
color: navy; background: powderblue;
}
</style>
</template>
</dom-module>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<link rel="import" href="my-button-styles.html">
<dom-module id="my-element">
<template>
<style include="my-button-styles">
/* Element-specific CSS goes here */
</style>
...
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Import the styles
my-button-styles.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-button-styles">
<template>
<style>
button {
background: #fff;
border: 3px solid rebeccapurple;
color: rebeccapurple;
text-decoration: none;
}
button:hover {
background: rebeccapurple; color: #fff;
}
button:focus {
color: navy; background: powderblue;
}
</style>
</template>
</dom-module>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<link rel="import" href="my-button-styles.html">
<dom-module id="my-element">
<template>
<style include="my-button-styles">
/* Element-specific CSS goes here */
</style>
...
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Include the styles
my-button-styles.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<dom-module id="my-button-styles">
<template>
<style>
button {
background: #fff;
border: 3px solid rebeccapurple;
color: rebeccapurple;
text-decoration: none;
}
button:hover {
background: rebeccapurple; color: #fff;
}
button:focus {
color: navy; background: powderblue;
}
</style>
</template>
</dom-module>
my-element.html:
<link rel="import"
href="bower_components/polymer/polymer-element.html">
<link rel="import" href="my-button-styles.html">
<dom-module id="my-element">
<template>
<style include="my-button-styles">
/* Element-specific CSS goes here */
</style>
...
</template>
<script>
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
}
window.customElements.define(MyElement.is,
MyElement);
</script>
</dom-module>
Add additional CSS here
ShadyCSS Shim Limitations
• ::slotted needs a selector before it (such as :host)
• External stylesheets within a shadow root cannot be shimmed
- So no <link rel="stylesheet"> or @import
• Avoid dynamic changes, including:
- Changing a custom property value
- Adding styles after the scoping shim is executed
Polymer-Powered Design Systems139
Additional Details: https://github.com/webcomponents/shadycss#limitations
"scroll-1410168" is licensed under CC0 1.0
Documenting Your Polymer Code
• Document with JSDoc syntax - usejsdoc.org
• Create a page that imports & includes iron-component-page
• Generate the docs and load your page:
$ npm i -g polymer-cli bower
$ polymer analyze > analysis.json
$ polymer serve --open
Polymer-Powered Design Systems141
Additional Details: https://github.com/PolymerElements/iron-component-page
<!--
Material design:
[Tabs](https://www.google.com/design/s
pec/components/tabs.html)
`paper-tabs` makes it easy to explore
and switch between different views or
functional aspects of
an app, or to browse categorized data
sets.
Use `selected` property to get or set
the selected tab.
Example:
<paper-tabs selected="0">
<paper-tab>TAB 1</paper-tab>
<paper-tab>TAB 2</paper-tab>
<paper-tab>TAB 3</paper-tab>
</paper-tabs>
<!--
### Styling
The following custom properties and
mixins are available for styling:
Custom property | Description |
Default
----------------|-------------|-------
---
`--paper-tabs-selection-bar-color` |
Color for the selection bar | `--
paper-yellow-a100`
`--paper-tabs-selection-bar` | Mixin
applied to the selection bar | `{}`
`--paper-tabs` | Mixin applied to the
tabs | `{}`
`--paper-tabs-content` | Mixin applied
to the content container of tabs |
`{}`
`--paper-tabs-container` | Mixin
applied to the layout container of
/**
* If true, the tabs are aligned
to bottom (the selection bar
appears at the top).
*/
alignBottom: {
type: Boolean,
value: false
},
/**
* If true, tabs are
automatically selected when
focused using the
* keyboard.
*/
autoselect: {
type: Boolean,
value: false
},
D
D
D
Demo
Driven
Development
© Comcast
Source: https://github.com/webcomponents/gold-standard/wiki
MONO
REPO
MANY
REPOS
MONO
REPO
MANY
REPOS
vs.
"Peñón de Ifach - Calpe - Spain" by Wyemji is licensed under CC BY-SA 3.0 "Mohegan Bluffs" by John Riviello is licensed under CC BY-SA 2.0
How do teams use my
Polymer-Powered
Design System?
{
"name": "my-app",
"flat": true,
...
http://yarnpkg.com
Why Yarn & not NPM? See https://github.com/package-community/discussions/issues/2
Using Web Components
• Import the component
- <link rel="import" href="https://your-web-component-
cdn.com/iron-pages/iron-pages.html">
• Use your custom element as a normal HTML tag
- <iron-pages>
<div>Page 1 content</div>
<div>Page 2 content</div>
</iron-pages>
Polymer-Powered Design Systems - @JohnRiv158
© Comcast
© Comcast
<script href="https://polaris.xfinity.com/polaris.js"></script>
<xc-header
tab="myaccount"
is-authed="[[isAuthed]]"
login-url="/login"
sign-out-url="/logout"
first-name="[[openidData.given_name]]"
user-name="[[openidData.preferred_username]]">
</xc-header>
<xc-footer></xc-footer>
View the Open Source code at https://github.com/Comcast/polaris
Polymer-Powered Design Systems - @JohnRiv161
Polymer-Powered Design Systems
• Have a team of designers & developers
responsible for your design system
• Polymer & Web Components are a great way to
build reusable components that work across
multiple frameworks
• Don’t forget your colons & semicolons when
defining Polymer CSS Mixins
• Embrace Demo Driven Development
Polymer-Powered Design Systems - @JohnRiv162
Useful Links
•WebComponents.org - webcomponents.org
•Polymer Website - polymer-project.org
•Polymer Slack - polymer-slack.herokuapp.com
•Polymer 2.x Cheat Sheet - https://meowni.ca/posts/polymer-2-cheatsheet/
•How to use Polymer with Webpack - http://robdodson.me/how-to-use-polymer-with-webpack/
•Hands-on with the Polymer 3.0 preview - https://www.polymer-project.org/blog/2017-08-23-hands-
on-30-preview
•Custom Elements Everywhere - https://custom-elements-everywhere.com/
•Polycasts on YouTube -
https://www.youtube.com/playlist?list=PLOU2XLYxmsII5c3Mgw6fNYCzaWrsM3sMN
•2017 Polymer Summit videos on YouTube -
https://www.youtube.com/playlist?list=PLNYkxOF6rcIDP0PqVaJxqNWwIgvoEPzJi
•End-to-End Polymer Apps - 2017 Chrome Dev Summit video - https://youtu.be/Wu2GCRkDecI
•2017 Google I/O Polymer videos on YouTube -
https://www.youtube.com/playlist?list=PL_c6rbXV248du6m1VJABo32mP7sXWVb4m
Polymer-Powered Design Systems - @JohnRiv163
Thank you!
John Riviello
@JohnRiv

More Related Content

What's hot

HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?Chris Mills
 
Taiwan Web Standards Talk 2011
Taiwan Web Standards Talk 2011Taiwan Web Standards Talk 2011
Taiwan Web Standards Talk 2011Zi Bin Cheah
 
Responsive Web Design: Tips and Tricks
Responsive Web Design: Tips and TricksResponsive Web Design: Tips and Tricks
Responsive Web Design: Tips and TricksGautam Krishnan
 
Improving the Responsive Web Design Process in 2016
Improving the Responsive Web Design Process in 2016Improving the Responsive Web Design Process in 2016
Improving the Responsive Web Design Process in 2016Cristina Chumillas
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web DesignDebra Shapiro
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do MoreRemy Sharp
 
Html5 & CSS overview
Html5 & CSS overviewHtml5 & CSS overview
Html5 & CSS overviewIvan Frantar
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentspsstoev
 
HTML5 - Introduction
HTML5 - IntroductionHTML5 - Introduction
HTML5 - IntroductionDavy De Pauw
 
jQuery Comes to XPages
jQuery Comes to XPagesjQuery Comes to XPages
jQuery Comes to XPagesTeamstudio
 
jQuery: The World's Most Popular JavaScript Library Comes to XPages
jQuery: The World's Most Popular JavaScript Library Comes to XPagesjQuery: The World's Most Popular JavaScript Library Comes to XPages
jQuery: The World's Most Popular JavaScript Library Comes to XPagesTeamstudio
 
State of jQuery June 2013 - Portland
State of jQuery June 2013 - PortlandState of jQuery June 2013 - Portland
State of jQuery June 2013 - Portlanddmethvin
 
Take Your Markup to Eleven
Take Your Markup to ElevenTake Your Markup to Eleven
Take Your Markup to ElevenEmily Lewis
 

What's hot (20)

HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?HTML5 and CSS3: does now really mean now?
HTML5 and CSS3: does now really mean now?
 
Taiwan Web Standards Talk 2011
Taiwan Web Standards Talk 2011Taiwan Web Standards Talk 2011
Taiwan Web Standards Talk 2011
 
Responsive Web Design: Tips and Tricks
Responsive Web Design: Tips and TricksResponsive Web Design: Tips and Tricks
Responsive Web Design: Tips and Tricks
 
Improving the Responsive Web Design Process in 2016
Improving the Responsive Web Design Process in 2016Improving the Responsive Web Design Process in 2016
Improving the Responsive Web Design Process in 2016
 
Chapter14
Chapter14Chapter14
Chapter14
 
HTML5 JS APIs
HTML5 JS APIsHTML5 JS APIs
HTML5 JS APIs
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web Design
 
Bilder usw...
Bilder usw...Bilder usw...
Bilder usw...
 
Fundamental JQuery
Fundamental JQueryFundamental JQuery
Fundamental JQuery
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
 
Html5 & CSS overview
Html5 & CSS overviewHtml5 & CSS overview
Html5 & CSS overview
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
 
What is jQuery?
What is jQuery?What is jQuery?
What is jQuery?
 
HTML5 - Introduction
HTML5 - IntroductionHTML5 - Introduction
HTML5 - Introduction
 
jQuery Comes to XPages
jQuery Comes to XPagesjQuery Comes to XPages
jQuery Comes to XPages
 
jQuery: The World's Most Popular JavaScript Library Comes to XPages
jQuery: The World's Most Popular JavaScript Library Comes to XPagesjQuery: The World's Most Popular JavaScript Library Comes to XPages
jQuery: The World's Most Popular JavaScript Library Comes to XPages
 
Html5
Html5Html5
Html5
 
State of jQuery June 2013 - Portland
State of jQuery June 2013 - PortlandState of jQuery June 2013 - Portland
State of jQuery June 2013 - Portland
 
Take Your Markup to Eleven
Take Your Markup to ElevenTake Your Markup to Eleven
Take Your Markup to Eleven
 
HTML5 Design
HTML5 DesignHTML5 Design
HTML5 Design
 

Similar to Polymer-Powered Design Systems - DevFest Florida

Polymer - Lego for the web!
Polymer - Lego for the web!Polymer - Lego for the web!
Polymer - Lego for the web!Codemotion
 
BreizhBeans - Web components
BreizhBeans - Web componentsBreizhBeans - Web components
BreizhBeans - Web componentsHoracio Gonzalez
 
Polymer - Una bella historia de amor
Polymer - Una bella historia de amorPolymer - Una bella historia de amor
Polymer - Una bella historia de amorIsrael Blancas
 
Reaching for the Future with Web Components and Polymer
Reaching for the Future with Web Components and PolymerReaching for the Future with Web Components and Polymer
Reaching for the Future with Web Components and PolymerFITC
 
Web Components: back to the future
Web Components: back to the futureWeb Components: back to the future
Web Components: back to the futureDA-14
 
Web Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xWeb Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xPatrickHillert
 
Web Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xWeb Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xinovex GmbH
 
Web Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereWeb Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereJohn Riviello
 
Polytechnic 1.0 Granada
Polytechnic 1.0 GranadaPolytechnic 1.0 Granada
Polytechnic 1.0 GranadaIsrael Blancas
 
Introduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebConIntroduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebConJohn Riviello
 
Web Components
Web ComponentsWeb Components
Web ComponentsFITC
 
Web components: A simpler and faster react
Web components:  A simpler and faster reactWeb components:  A simpler and faster react
Web components: A simpler and faster reactChris Lorenzo
 
Web Components
Web ComponentsWeb Components
Web ComponentsFITC
 
Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16John Riviello
 
Iasi code camp 12 october 2013 shadow dom - mihai bîrsan
Iasi code camp 12 october 2013   shadow dom - mihai bîrsanIasi code camp 12 october 2013   shadow dom - mihai bîrsan
Iasi code camp 12 october 2013 shadow dom - mihai bîrsanCodecamp Romania
 
The Structure of Web Code: A Case For Polymer, November 1, 2014
The Structure of Web Code: A Case For Polymer, November 1, 2014The Structure of Web Code: A Case For Polymer, November 1, 2014
The Structure of Web Code: A Case For Polymer, November 1, 2014Tommie Gannert
 
HTML5 Essential Training
HTML5 Essential TrainingHTML5 Essential Training
HTML5 Essential TrainingKaloyan Kosev
 
Introduction to web components
Introduction to web componentsIntroduction to web components
Introduction to web componentsMarc Bächinger
 
The Time for Vanilla Web Components has Arrived
The Time for Vanilla Web Components has ArrivedThe Time for Vanilla Web Components has Arrived
The Time for Vanilla Web Components has ArrivedGil Fink
 

Similar to Polymer-Powered Design Systems - DevFest Florida (20)

Polymer - Lego for the web!
Polymer - Lego for the web!Polymer - Lego for the web!
Polymer - Lego for the web!
 
BreizhBeans - Web components
BreizhBeans - Web componentsBreizhBeans - Web components
BreizhBeans - Web components
 
Polymer - Una bella historia de amor
Polymer - Una bella historia de amorPolymer - Una bella historia de amor
Polymer - Una bella historia de amor
 
Reaching for the Future with Web Components and Polymer
Reaching for the Future with Web Components and PolymerReaching for the Future with Web Components and Polymer
Reaching for the Future with Web Components and Polymer
 
Web Components: back to the future
Web Components: back to the futureWeb Components: back to the future
Web Components: back to the future
 
Web Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xWeb Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.x
 
Web Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xWeb Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.x
 
Web Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereWeb Components: The Future of Web Development is Here
Web Components: The Future of Web Development is Here
 
Polytechnic 1.0 Granada
Polytechnic 1.0 GranadaPolytechnic 1.0 Granada
Polytechnic 1.0 Granada
 
Introduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebConIntroduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebCon
 
Web Components
Web ComponentsWeb Components
Web Components
 
Web components: A simpler and faster react
Web components:  A simpler and faster reactWeb components:  A simpler and faster react
Web components: A simpler and faster react
 
Web Components
Web ComponentsWeb Components
Web Components
 
Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16
 
Iasi code camp 12 october 2013 shadow dom - mihai bîrsan
Iasi code camp 12 october 2013   shadow dom - mihai bîrsanIasi code camp 12 october 2013   shadow dom - mihai bîrsan
Iasi code camp 12 october 2013 shadow dom - mihai bîrsan
 
The Structure of Web Code: A Case For Polymer, November 1, 2014
The Structure of Web Code: A Case For Polymer, November 1, 2014The Structure of Web Code: A Case For Polymer, November 1, 2014
The Structure of Web Code: A Case For Polymer, November 1, 2014
 
HTML5 Essential Training
HTML5 Essential TrainingHTML5 Essential Training
HTML5 Essential Training
 
Polymer
PolymerPolymer
Polymer
 
Introduction to web components
Introduction to web componentsIntroduction to web components
Introduction to web components
 
The Time for Vanilla Web Components has Arrived
The Time for Vanilla Web Components has ArrivedThe Time for Vanilla Web Components has Arrived
The Time for Vanilla Web Components has Arrived
 

More from John Riviello

The Decision Buy-In Algorithm
The Decision Buy-In AlgorithmThe Decision Buy-In Algorithm
The Decision Buy-In AlgorithmJohn Riviello
 
Future-Proofing Your JavaScript Framework Decision
Future-Proofing Your JavaScript Framework DecisionFuture-Proofing Your JavaScript Framework Decision
Future-Proofing Your JavaScript Framework DecisionJohn Riviello
 
Introduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS InteractiveIntroduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS InteractiveJohn Riviello
 
The Critical Career Path Conversation
The Critical Career Path ConversationThe Critical Career Path Conversation
The Critical Career Path ConversationJohn Riviello
 
Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer John Riviello
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceJohn Riviello
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceJohn Riviello
 

More from John Riviello (7)

The Decision Buy-In Algorithm
The Decision Buy-In AlgorithmThe Decision Buy-In Algorithm
The Decision Buy-In Algorithm
 
Future-Proofing Your JavaScript Framework Decision
Future-Proofing Your JavaScript Framework DecisionFuture-Proofing Your JavaScript Framework Decision
Future-Proofing Your JavaScript Framework Decision
 
Introduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS InteractiveIntroduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS Interactive
 
The Critical Career Path Conversation
The Critical Career Path ConversationThe Critical Career Path Conversation
The Critical Career Path Conversation
 
Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's Performance
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's Performance
 

Polymer-Powered Design Systems - DevFest Florida

  • 1. Polymer-Powered Design Systems DevFest Florida - November 11, 2017 John Riviello @JohnRiv
  • 8. "Notebook beside the iPhone on Table" by PicJumbo is licensed under CC0 1.0
  • 9.
  • 10. WHY?!? 1. Communication 2. Deviations "Alone" by Pixabay is licensed under CC0 1.0
  • 11. “Designers should build products that solve needs instead of spending time on reinventions” - Jack Zankowski Creative Director, Comcast XD
  • 12.
  • 13.
  • 14.
  • 15. "Mask, Ancient Artifact" by Pedro_Teixeira is licensed under CC0 1.0
  • 16. "Abstract Business Code" by Pixabay is licensed under CC0 1.0
  • 17.
  • 18.
  • 19. “And You Thought Buttons Were Easy?” - Nathan Curtis Source: https://medium.com/eightshapes-llc/and-you-thought-buttons-were-easy-26eb5b5c1871
  • 23. "Books on Shelf in Library" by Pixabay is licensed under CC0 1.0
  • 24.
  • 25.
  • 26.
  • 27.
  • 29. “A design system’s value is realized when products ship features using parts from the system.” - Nathan Curtis Source: https://medium.com/eightshapes-llc/a-design-system-isn-t-a-project-it-s-a-product-serving-products-74dcfffef935
  • 30. Design System Design & Development Source: http://atomicdesign.bradfrost.com/chapter-5/ Website Pattern Library Make changes to a pattern Applications and pattern library both update to reflect changes
  • 33. Existing Frameworks Applications Web Platform Web Components built with Polymer (or not)
  • 35. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv35 4 Specs
  • 36. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv36 Custom Elements
  • 37. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv37 Custom Elements •Provides a way for authors to build their own fully-featured DOM elements. - <xc-tab>Your Wifi</xc-tab>
  • 38. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv38 HTML Imports
  • 39. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv39 HTML Imports • Means to import custom elements - <link rel="import" href="../xc-tab/xc-tab.html"> • Built-in deduplication • Componetize the HTML, CSS & JavaScript • Will be replaced by ES6 Modules - import "../xc-tab/xc-tab.js"
  • 40. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv40 Templates
  • 41. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv41 • Used to declare fragments of HTML - <template id="tab"> <div class="tab-content"></div> </template> • The element itself renders nothing • Can be cloned and inserted in the document via JavaScript, which will render the content Templates
  • 42. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv42 Shadow DOM
  • 43. What Are Web Components? Polymer-Powered Design Systems - @JohnRiv43 •Allows you to take a DOM subtree and hide it from the document scope •Hides CSS styles as well •Common examples from HTML5 include: <select>, <video>, & <input type="date"> Shadow DOM
  • 46. How do I build my Design System using Polymer?
  • 47. “A style guide is an artifact of design process. A design system is a living, funded product with a roadmap & backlog, serving an ecosystem.” - Nathan Curtis Source: https://twitter.com/nathanacurtis/status/656829204235972608
  • 48. You Need a TeamYou Need a Team
  • 49. “Establish a high-quality, brand-aligned experience across our product through human guidance and internal tools.” - Jina Anne Source: https://medium.com/salesforce-ux/the-salesforce-team-model-for-scaling-a-design-system-d89c2a2d404b Salesforce.com Design Systems Team Objective:
  • 50. "Person Workshop" is licensed under CC0 1.0 / Adjusted from original
  • 51.
  • 52.
  • 53.
  • 54. Building Your Design System with Polymer CSS IS AWESOME Polymer-Powered Design Systems54 Source: https://philipwalton.github.io/talks/2015-10-26/#7 • Managing global names • Scoping/isolating styles • Specificity conflicts • Unpredictable matching • Managing style dependencies • Removing unused code
  • 55.
  • 56. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module>
  • 57. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Import Polymer.Element
  • 58. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Styles we’ll be modifying
  • 59. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Template contains <p>
  • 60. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Polymer Boilerplate
  • 61. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> index.html: <!doctype html> <html> <head> <title>Shadow DOM Demo</title> <script src="bower_components/webcomponentsjs/webcomponent s-loader.js"></script> <link rel="import" href="my-element.html"> <style> /* Main Document Styles */ </style> </head> <body> <my-element></my-element> <p>Paragraph in the main document</p> </body> </html>
  • 62. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> index.html: <!doctype html> <html> <head> <title>Shadow DOM Demo</title> <script src="bower_components/webcomponentsjs/webcomponent s-loader.js"></script> <link rel="import" href="my-element.html"> <style> /* Main Document Styles */ </style> </head> <body> <my-element></my-element> <p>Paragraph in the main document</p> </body> </html> Load Polyfills (if needed)
  • 63. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome/p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> index.html: <!doctype html> <html> <head> <title>Shadow DOM Demo</title> <script src="bower_components/webcomponentsjs/webcomponent s-loader.js"></script> <link rel="import" href="my-element.html"> <style> /* Main Document Styles */ </style> </head> <body> <my-element></my-element> <p>Paragraph in the main document</p> </body> </html> Import my-element.html
  • 64. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> index.html: <!doctype html> <html> <head> <title>Shadow DOM Demo</title> <script src="bower_components/webcomponentsjs/webcomponent s-loader.js"></script> <link rel="import" href="my-element.html"> <style> /* Main Document Styles */ </style> </head> <body> <my-element></my-element> <p>Paragraph in the main document</p> </body> </html> Styles we’ll be modifying
  • 65. index.html: <!doctype html> <html> <head> <title>Shadow DOM Demo</title> <script src="bower_components/webcomponentsjs/webcomponent s-loader.js"></script> <link rel="import" href="my-element.html"> <style> /* Main Document Styles */ </style> </head> <body> <my-element></my-element> <p>Paragraph in the main document</p> </body> </html> my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Body contains <my-element> & <p>
  • 66. my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-element"> <template> <style> /* My Element Styles */ </style> <p>Shadow DOM is awesome</p> </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> index.html: <!doctype html> <html> <head> <title>Shadow DOM Demo</title> <script src="bower_components/webcomponentsjs/webcomponent s-loader.js"></script> <link rel="import" href="my-element.html"> <style> /* Main Document Styles */ </style> </head> <body> <my-element></my-element> <p>Paragraph in the main document</p> </body> </html> Flattened DOM Tree: <body> <my-element> #shadow-root (open) <style>...</style> <p>Shadow DOM is awesome</p> </my-element> <p>Paragraph in the main document</p> </body>
  • 67. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> p { border: 3px solid #f60; } </style> index.html: <style> p { background-color: #9cf; } </style>
  • 68. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { } p { border: 3px solid #f60; } </style> :host selector
  • 69. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { } p { border: 3px solid #f60; } </style> Flattened DOM Tree: <body> <my-element> #shadow-root (open) <style>...</style> <p>Shadow DOM is awesome</p> </my-element> <p>Paragraph in the main document</p> </body>
  • 70. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; } p { border: 3px solid #f60; } </style>
  • 71. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; } p { border: 3px solid #f60; } </style>
  • 72. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; } </style> See https://developers.google.com/web/updates/2016/06/css-containment for more information on contain
  • 73. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> See https://developers.google.com/web/updates/2016/06/css-containment for more information on contain
  • 74. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } :host([disabled]) { outline-color: #ccc; } :host([disabled]) > p { border-color: #ccc; } ... </style>
  • 75. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } :host([disabled]) { outline-color: #ccc; } :host([disabled]) > p { border-color: #ccc; } ... </style> index.html: <my-element></my-element> <p>Paragraph in the main document</p>
  • 76. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } :host([disabled]) { outline-color: #ccc; } :host([disabled]) > p { border-color: #ccc; } ... </style> index.html: <my-element disabled></my-element> <p>Paragraph in the main document</p>
  • 77. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } :host([disabled]) { outline-color: #ccc; } :host([disabled]) > p { border-color: #ccc; } ... </style> index.html: <my-element></my-element> <p>Paragraph in the main document</p>
  • 78. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> index.html: <my-element></my-element> <p>Paragraph in the main document</p>
  • 79. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> index.html: <style> p { background-color: #9cf; } </style>
  • 80. Rendered Result: Shadow DOM is awesome Paragraph in the main document index.html: <style> p { background-color: #9cf; } my-element { outline-color: red; } </style> my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style>
  • 81. Rendered Result: Shadow DOM is awesome Paragraph in the main document index.html: <style> p { background-color: #9cf; } my-element { outline-color: red; } my-element p { border-color: blue; } </style> my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style>
  • 82. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> index.html: <style> p { background-color: #9cf; } </style>
  • 83. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> index.html: <my-element></my-element> <p>Paragraph in the main document</p>
  • 84. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> index.html: <my-element> <ul> </ul> </my-element> <p>Paragraph in the main document</p>
  • 85. Rendered Result: Shadow DOM is awesome Paragraph in the main document my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } </style> index.html: <my-element> <ul> <li>This is Light DOM</li> <li>It needs a slot</li> </ul> </my-element> <p>Paragraph in the main
  • 86. my-element.html: <template> <style> ... </style> <p>Shadow DOM is awesome</p> </template> Rendered Result: Shadow DOM is awesome Paragraph in the main document index.html: <my-element> <ul> <li>This is Light DOM</li> <li>It needs a slot</li> </ul> </my-element> <p>Paragraph in the main
  • 87. my-element.html: <template> <style> ... </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 88. my-element.html: <template> <style> ... </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document Flattened DOM Tree: <body> <my-element> #shadow-root (open) <style>...</style> <p>Shadow DOM is awesome</p> <slot> <ul> <li>This is Light DOM</li> <li>It needs a slot</li> </ul> </slot> </my-element> ...
  • 89. my-element.html: <template> <style> ... </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document Flattened DOM Tree: <body> <my-element> #shadow-root (open) <style>...</style> <p>Shadow DOM is awesome</p> <slot> <ul> <li>This is Light DOM</li> <li>It needs a slot</li> </ul> </slot> </my-element> ...
  • 90. my-element.html: <template> <style> ... </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 91. my-element.html: <template> <style> ... ::slotted(ul) { } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document ::slotted() selector
  • 92. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 93. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } ::slotted(ul > li) { color: red; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 94. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 95. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } </style>
  • 96. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } li { color: red; } </style>
  • 97. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } ul { color: red; } </style>
  • 98. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; color: blue; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } ul { color: red; } </style>
  • 99. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; color: blue; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } </style>
  • 100. my-element.html: <template> <style> ... ::slotted(ul) { margin: 0; } </style> <p>Shadow DOM is awesome</p> <slot></slot> </template> Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } </style>
  • 101. my-element.html: <template> <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } ::slotted(ul) { ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } </style>
  • 102. my-element.html: <template> <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } ::slotted(ul) { ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> body { color: green; font-family: Calibri; } p { background-color: #9cf; }
  • 103. my-element.html: <template> <style> :host { outline: 3px dashed blue; display: block; contain: content; color: initial; } p { border: 3px solid #f60; margin: 0; } ::slotted(ul) { ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> body { color: green; font-family: Calibri; } p { background-color: #9cf; }
  • 104. my-element.html: <template> <style> :host { outline: 3px dashed blue; display: block; contain: content; all: initial; } p { border: 3px solid #f60; margin: 0; } ::slotted(ul) { ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> body { color: green; font-family: Calibri; } p { background-color: #9cf; }
  • 105. CSS Custom Properties"Chameleon" by George is licensed under CC0 1.0
  • 106. CSS Custom Properties Basic usage: <style> html { /* Define a Custom Property */ --body-text-color: gray; } Polymer-Powered Design Systems106
  • 107. CSS Custom Properties Basic usage: <style> html { /* Define a Custom Property */ --body-text-color: gray; } p { /* Use a Custom Property */ color: var(--body-text-color); } </style> Polymer-Powered Design Systems107
  • 108. CSS Custom Properties Basic usage: <style> html { /* Define a Custom Property */ --body-text-color: gray; } p { /* Use a Custom Property with a fallback value */ color: var(--body-text-color, navy); } </style> Polymer-Powered Design Systems108
  • 109. CSS Custom Properties Basic usage: <style> html { /* Define a Custom Property */ --body-text-color: gray; } p { /* Use a Custom Property with multiple fallback values */ color: var(--body-text-color, var(--p-text-color, navy)); } </style> Polymer-Powered Design Systems109
  • 110. my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid #f60; margin: 0; } ::slotted(ul) { margin: 0; ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } </style>
  • 111. my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; } ::slotted(ul) { Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> p { background-color: #9cf; } </style>
  • 112. my-element.html: <style> :host { outline: 3px dashed blue; display: block; contain: content; } p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; } ::slotted(ul) { Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> html { --my-element-border-color: purple; } p { background-color: #9cf; }
  • 113. • Name colors: --xc-blue-sky: #0272B6; • Set variables for usage: --xc-link-color: var(--xc-blue-sky); • Useful to name Custom Property hooks in the format of --element-property: var(--my-element-border-color, #f60); • Besides colors, gaps and/or padding factors are useful: --xc-main-gap: 16px; --xc-large-gap: 24px; padding: var(--xc-main-gap); padding: calc(1.5*var(--xc-main-gap)); CSS Custom Properties Tips Polymer-Powered Design Systems113
  • 114. CSS Mixins"Mix Colorful Color" is licensed under CC0 1.0
  • 115. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 116. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document Import polymer.html or add shadycss/apply-shim.html
  • 117. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document Use `@apply` to add the mixin hook
  • 118. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document Polymer CSS Mixin Format: <custom-style> <style> selector { --mixin-name: { /* rules */ }; } </style> </custom-style>
  • 119. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document
  • 120. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> html { --my-element-border-color: purple; } } p { background-color: #9cf; } ... </style>
  • 121. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <style> html { --my-element-p { background: red; font-style: italic; }; ... } ... </style>
  • 122. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style>
  • 123. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style> Style in my-element.html after shim is applied: <style> p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; background: var(--my-element-p_-_background); font-style: var(--my-element-p_-_font-style); } </style>
  • 124. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style> Style in my-element.html after shim is applied: <style> p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; background: var(--my-element-p_-_background); font-style: var(--my-element-p_-_font-style); } </style>
  • 125. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style> Style in my-element.html after shim is applied: <style> p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; background: var(--my-element-p_-_background); font-style: var(--my-element-p_-_font-style); } </style>
  • 126. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style> Style in my-element.html after shim is applied: <style> p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; background: var(--my-element-p_-_background); font-style: var(--my-element-p_-_font-style); } </style> Style in index.html after shim is applied: <custom-style> <style> html { --my-element-border-color: purple; --my-element-p_-_background: red; --my-element-p_-_font-style: italic; } </style> </custom-style>
  • 127. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style> Style in my-element.html after shim is applied: <style> p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; background: var(--my-element-p_-_background); font-style: var(--my-element-p_-_font-style); } </style> Style in index.html after shim is applied: <custom-style> <style> html { --my-element-border-color: purple; --my-element-p_-_background: red; --my-element-p_-_font-style: italic; } </style> </custom-style>
  • 128. my-element.html: <link rel="import" href="bower_components/polymer/ polymer.html"> ... <style> ... p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; @apply --my-element-p; } ... Rendered Result: Shadow DOM is awesome • This is Light DOM • It needs a slot Paragraph in the main document index.html: <custom-style> <style> html { --my-element-p: { background: red; font-style: italic; }; ... } ... </style> </custom-style> Style in my-element.html after shim is applied: <style> p { border: 3px solid var(--my-element-border-color, #f60); margin: 0; background: var(--my-element-p_-_background); font-style: var(--my-element-p_-_font-style); } </style> Style in index.html after shim is applied: <custom-style> <style> html { --my-element-border-color: purple; --my-element-p_-_background: red; --my-element-p_-_font-style: italic; } </style> </custom-style>
  • 129. • Used for setting styles in the main document, either: - Declared directly in the main document, or - Hoisted to the main document from an import • When would you want to include them in an import? - @font-face rules - Theming (declaring common variables & mixins) • <custom-style> & @apply can be loaded on their own via ShadyCSS (see https://github.com/webcomponents/shadycss) More <custom-style> notes Polymer-Powered Design Systems129
  • 130. • This warning is unavoidable when using <custom-style>: • If you’re using at least Polymer 1.10.1 or 2.1.1, you’re good More <custom-style> notes Polymer-Powered Design Systems130
  • 131. • Style Modules are Polymer’s way of sharing styles among Polymer Components • The styles are actually copied into the Shadow Root of the component they are included in - So only include what you actually need • Great way of sharing form element styles like buttons Another way to share styles: Style Modules Polymer-Powered Design Systems131
  • 132. my-button-styles.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-button-styles"> <template> <style> button { background: #fff; border: 3px solid rebeccapurple; color: rebeccapurple; text-decoration: none; } button:hover { background: rebeccapurple; color: #fff; } button:focus { color: navy; background: powderblue; } </style> </template> </dom-module>
  • 133. my-button-styles.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-button-styles"> <template> <style> button { background: #fff; border: 3px solid rebeccapurple; color: rebeccapurple; text-decoration: none; } button:hover { background: rebeccapurple; color: #fff; } button:focus { color: navy; background: powderblue; } </style> </template> </dom-module> Declare styles in a dom-module with an `id` attribute
  • 134. my-button-styles.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-button-styles"> <template> <style> button { background: #fff; border: 3px solid rebeccapurple; color: rebeccapurple; text-decoration: none; } button:hover { background: rebeccapurple; color: #fff; } button:focus { color: navy; background: powderblue; } </style> </template> </dom-module> my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <link rel="import" href="my-button-styles.html"> <dom-module id="my-element"> <template> <style include="my-button-styles"> /* Element-specific CSS goes here */ </style> ... </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module>
  • 135. my-button-styles.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-button-styles"> <template> <style> button { background: #fff; border: 3px solid rebeccapurple; color: rebeccapurple; text-decoration: none; } button:hover { background: rebeccapurple; color: #fff; } button:focus { color: navy; background: powderblue; } </style> </template> </dom-module> my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <link rel="import" href="my-button-styles.html"> <dom-module id="my-element"> <template> <style include="my-button-styles"> /* Element-specific CSS goes here */ </style> ... </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Import the styles
  • 136. my-button-styles.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-button-styles"> <template> <style> button { background: #fff; border: 3px solid rebeccapurple; color: rebeccapurple; text-decoration: none; } button:hover { background: rebeccapurple; color: #fff; } button:focus { color: navy; background: powderblue; } </style> </template> </dom-module> my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <link rel="import" href="my-button-styles.html"> <dom-module id="my-element"> <template> <style include="my-button-styles"> /* Element-specific CSS goes here */ </style> ... </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Include the styles
  • 137. my-button-styles.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <dom-module id="my-button-styles"> <template> <style> button { background: #fff; border: 3px solid rebeccapurple; color: rebeccapurple; text-decoration: none; } button:hover { background: rebeccapurple; color: #fff; } button:focus { color: navy; background: powderblue; } </style> </template> </dom-module> my-element.html: <link rel="import" href="bower_components/polymer/polymer-element.html"> <link rel="import" href="my-button-styles.html"> <dom-module id="my-element"> <template> <style include="my-button-styles"> /* Element-specific CSS goes here */ </style> ... </template> <script> class MyElement extends Polymer.Element { static get is() { return 'my-element'; } } window.customElements.define(MyElement.is, MyElement); </script> </dom-module> Add additional CSS here
  • 138.
  • 139. ShadyCSS Shim Limitations • ::slotted needs a selector before it (such as :host) • External stylesheets within a shadow root cannot be shimmed - So no <link rel="stylesheet"> or @import • Avoid dynamic changes, including: - Changing a custom property value - Adding styles after the scoping shim is executed Polymer-Powered Design Systems139 Additional Details: https://github.com/webcomponents/shadycss#limitations
  • 141. Documenting Your Polymer Code • Document with JSDoc syntax - usejsdoc.org • Create a page that imports & includes iron-component-page • Generate the docs and load your page: $ npm i -g polymer-cli bower $ polymer analyze > analysis.json $ polymer serve --open Polymer-Powered Design Systems141 Additional Details: https://github.com/PolymerElements/iron-component-page
  • 142.
  • 143. <!-- Material design: [Tabs](https://www.google.com/design/s pec/components/tabs.html) `paper-tabs` makes it easy to explore and switch between different views or functional aspects of an app, or to browse categorized data sets. Use `selected` property to get or set the selected tab. Example: <paper-tabs selected="0"> <paper-tab>TAB 1</paper-tab> <paper-tab>TAB 2</paper-tab> <paper-tab>TAB 3</paper-tab> </paper-tabs>
  • 144.
  • 145. <!-- ### Styling The following custom properties and mixins are available for styling: Custom property | Description | Default ----------------|-------------|------- --- `--paper-tabs-selection-bar-color` | Color for the selection bar | `-- paper-yellow-a100` `--paper-tabs-selection-bar` | Mixin applied to the selection bar | `{}` `--paper-tabs` | Mixin applied to the tabs | `{}` `--paper-tabs-content` | Mixin applied to the content container of tabs | `{}` `--paper-tabs-container` | Mixin applied to the layout container of
  • 146.
  • 147. /** * If true, the tabs are aligned to bottom (the selection bar appears at the top). */ alignBottom: { type: Boolean, value: false }, /** * If true, tabs are automatically selected when focused using the * keyboard. */ autoselect: { type: Boolean, value: false },
  • 148.
  • 149.
  • 150. D D D
  • 153.
  • 155. MONO REPO MANY REPOS MONO REPO MANY REPOS vs. "Peñón de Ifach - Calpe - Spain" by Wyemji is licensed under CC BY-SA 3.0 "Mohegan Bluffs" by John Riviello is licensed under CC BY-SA 2.0
  • 156. How do teams use my Polymer-Powered Design System?
  • 157. { "name": "my-app", "flat": true, ... http://yarnpkg.com Why Yarn & not NPM? See https://github.com/package-community/discussions/issues/2
  • 158. Using Web Components • Import the component - <link rel="import" href="https://your-web-component- cdn.com/iron-pages/iron-pages.html"> • Use your custom element as a normal HTML tag - <iron-pages> <div>Page 1 content</div> <div>Page 2 content</div> </iron-pages> Polymer-Powered Design Systems - @JohnRiv158
  • 162. Polymer-Powered Design Systems • Have a team of designers & developers responsible for your design system • Polymer & Web Components are a great way to build reusable components that work across multiple frameworks • Don’t forget your colons & semicolons when defining Polymer CSS Mixins • Embrace Demo Driven Development Polymer-Powered Design Systems - @JohnRiv162
  • 163. Useful Links •WebComponents.org - webcomponents.org •Polymer Website - polymer-project.org •Polymer Slack - polymer-slack.herokuapp.com •Polymer 2.x Cheat Sheet - https://meowni.ca/posts/polymer-2-cheatsheet/ •How to use Polymer with Webpack - http://robdodson.me/how-to-use-polymer-with-webpack/ •Hands-on with the Polymer 3.0 preview - https://www.polymer-project.org/blog/2017-08-23-hands- on-30-preview •Custom Elements Everywhere - https://custom-elements-everywhere.com/ •Polycasts on YouTube - https://www.youtube.com/playlist?list=PLOU2XLYxmsII5c3Mgw6fNYCzaWrsM3sMN •2017 Polymer Summit videos on YouTube - https://www.youtube.com/playlist?list=PLNYkxOF6rcIDP0PqVaJxqNWwIgvoEPzJi •End-to-End Polymer Apps - 2017 Chrome Dev Summit video - https://youtu.be/Wu2GCRkDecI •2017 Google I/O Polymer videos on YouTube - https://www.youtube.com/playlist?list=PL_c6rbXV248du6m1VJABo32mP7sXWVb4m Polymer-Powered Design Systems - @JohnRiv163