Future of the web

Web Components and semantic Linked Data

By Nazar Mokrynskyi

Hi from Apple

<section class="section section-display" data-analytics-section-engagement="name:display">
  <div class="section-content">
    <div class="row">
      <div class="column large-5 xsmall-12 column-copy">
        <div class="section-copy" data-analytics-region="learn more">
          <a href="/iphone-6/display/" class="block">
            <h2>Not just a bigger display. A better display.</h2>
            <p>It’s one thing to make a bigger display. It’s something else entirely to make a bigger Multi‑Touch display with brilliant colors and higher contrast at even wider viewing angles. But that’s exactly what we did with the new Retina HD display.</p>
            <p><span class="more block-link">Learn more about the Retina HD display</span></p>
          </a>
        </div>
        <div class="callout-list row">
          <aside class="callout column large-6 xsmall-6 callout-resolution-iphone-6 callout-from-right">
            <h6 class="callout-headline">1334<span class="callout-unit">×</span><br />750</h6>
            <p class="callout-copy"><span class="callout-copy-names">iPhone 6</span><br />RESOLUTION</p>
          </aside>

          <aside class="callout column large-6 xsmall-6 callout-resolution-iphone-6-plus callout-from-right">
            <h6 class="callout-headline">1920<span class="callout-unit">×</span><br />1080</h6>
            <p class="callout-copy"><span class="callout-copy-names">iPhone 6 Plus</span> RESOLUTION</p>
          </aside>

          <figure class="image-delay image-display-hero"></figure>
        </div>

      </div>
    </div>
  </div>
</section>

This is how iPhone 6 page was built

Good or bad?

Not as bad as some BEM-ish markup looks like, but still far from perfect

We need do better

<select multiple>
	<option>One</option>
	<option>Two</option>
</select>
<video controls autoplay>
  <source src="movie.mp4" type="video/mp4">
</video>

In fact browser already does, why can't we?

Indeed we can

<article is="cs-indiegogo-benefits" id="benefits">
  <h1>Our benefits</h1>
  <picture>
    <source srcset="benefits-1-mobile.jpg" media="(max-width: 1100px)">
    <img src="benefits-1.jpg" alt="Benefits">
  </picture>
  <picture>
    <source srcset="benefits-2-mobile.jpg" media="(max-width: 1100px)">
    <img src="/benefits-2.jpg" alt="Benefits">
  </picture>
  <picture>
    <source srcset="benefits-3-mobile.jpg" media="(max-width: 1100px)">
    <img src="benefits-3.jpg" alt="Benefits">
  </picture>

  <dl>
    <dt>Appliance Detection</dt>
    <dd>Ecoisme detects all devices in your home and shows you statistics of their usage</dd>
    <dt>Personalized Tips</dt>
    <dd>Get clear and specific tips, based on usage of your home appliances</dd>
    <dt>Integration with smart devices</dt>
    <dd>Having smart devices like NEST or WeMo, make them smarter with Ecoisme</dd>
  </dl>
</article>

Benefits

  • Simple to read and maintain
  • Semantically meaningful
  • Responsive

Web Components here to save you

  • Custom elements
  • HTML Imports
  • Templates
  • Shadow DOM

Custom elements

<script>
  document.registerElement('my-element', {
    prototype: Object.create(HTMLElement.prototype)
  });
</script>
<my-element>
  Hello, world!
</my-element>

HTML Imports

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

Templates

<template id="picture-inside">
  <img src="nice-picture.png">
</template>

Shadow DOM


Polymer

<dom-module id="contact-card">
  <link rel="import" type="css" href="contact-card.css">
  <template>
    <content></content>
    <iron-icon icon="star" hidden$="{{!starred}}"></iron-icon>
  </template>
  <script>
    Polymer({
      is: 'contact-card',
      properties: {
        starred: Boolean
      }
    });
  </script>
</dom-module>
<contact-card starred>
  <img src="profile.jpg" alt="Eric's photo">
  <span>Eric Bidelman</span>
</contact-card>
<google-map lat="37.790" long="-122.390"></google-map>

Data

How they appear on web-page:

<div class="buystrip-product-block">
  <h4 class="buystrip-product-title">iPhone 6</h4>
  <p class="buystrip-product-copy">From $199</p>
  <p class="buystrip-product-copy block-link more">Compare iPhone models</p>
</div>

Good or bad?

Doesn't look as bad as it might if we use semantically correct microdata or RDFa, but still far from perfect

We need do better

Why not just use JSON we all know and use everyday?

Seems to be a good idea, please welcome, JSON-LD:

{
  "@context" : "https://schema.org",
  "@id"      : "https://github.com/nazar-pc",
  "@type"    : "Person",
  "name"     : "Nazar Mokrynskyi",
  "image"    : "https://www.gravatar.com/avatar/3d67cc976284fd62356e2edd8a8dfc49"
}

Benefits

  • Simple to read and maintain
  • Semantically meaningful and very specific, anyone can understand it
  • Usually came without significant changes directly from API

But we still have a problem

Data are duplicated in JSON-LD structure and in page body

Wait, they are the same, aren't they?

Web Components + JSON-LD

<dom-module id="my-profile">
  <template>
    <a href="{{jsonld.@id}}">
      <img src="{{jsonld.image}}" alt="{{jsonld.name}}">
    </a>
  </template>
  <script>
    Polymer({
      is         : 'my-profile',
      properties : {
        jsonld : Object
      },
      ready      : function () {
        var jsonld = Polymer.dom(this).querySelector('script').innerHTML;
        this.set('jsonld', JSON.parse(jsonld));
      }
    });
  </script>
</dom-module>
<my-profile>
  <script type="application/ld+json">
    {
      "@context" : "https://schema.org",
      "@id"      : "https://github.com/nazar-pc",
      "@type"    : "Person",
      "name"     : "Nazar Mokrynskyi",
      "image"    : "https://www.gravatar.com/avatar/3d67cc976284fd62356e2edd8a8dfc49"
    }
  </script>
</my-profile>

Benefits

Everything mentioned before in one place)

Links

WebComponents.org

Polymer

Creating semantic sites with Web Components and JSON-LD

Создание семантических сайтов с помощью веб-компонентов и JSON-LD

Questions?

Nazar Mokrynskyi

https://github.com/nazar-pc

@nazarpc

Skype: nazar-pc

Diaspora: nazarpc@diaspora.mokrynskyi.com

Tox: A9D95C9AA5F7A3ED75D83D0292E22ACE84BA40E912185939414475AF28FD2B2A5C8EF5261249