Slide 1

Slide 1 text

The Super Mario Bros. Principle

Slide 2

Slide 2 text

http://goo.gl/h7PnfE The long shadow of Super Mario Bros.

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Toshihiko Nakago Shigeru Miyamoto

Slide 5

Slide 5 text

I could insert anything into a level, Nakago’s System would at least do something with it

Slide 6

Slide 6 text

Toshihiko Nakago Shigeru Miyamoto

Slide 7

Slide 7 text

Toshihiko Nakago Shigeru Miyamoto

Slide 8

Slide 8 text

Provide something Robust Failsafe Flexible Easy to use

Slide 9

Slide 9 text

CSS is easy selector { property: value; }

Slide 10

Slide 10 text

CSS is easy from-that-thing { make-this: look-like-this; and-this: look-something-like-this; }

Slide 11

Slide 11 text

CSS is easy from-that-thing { make-this: look-like-this; and-this: look-something-like-this; } This rarely gets complex This is always centre of debates and problems

Slide 12

Slide 12 text

This can be overwhelming Even with all the tools and tooling

Slide 13

Slide 13 text

Why can’t it be as easy as a { color: red; }

Slide 14

Slide 14 text

Interfaces

Slide 15

Slide 15 text

Web components I’m Mario
!
"
#

Slide 16

Slide 16 text

Web components document .querySelector( ‘player-character’) .addEventListener( ‘jump’, () => { // do something }) handleClick: function(e) { this.fire(‘jump’); }

Slide 17

Slide 17 text

Web components .player { ... } header { ... } footer { ... } .body { ... }

Slide 18

Slide 18 text

CSS custom properties :root { --main-color: #00b4ff; } .box { background-color: var(--main-color, blue); } .headline { color: var(--main-color, red); border-color: var(--main-color); }

Slide 19

Slide 19 text

… follow the cascade :root { --main-color: #00b4ff; } .box { background-color: var(--main-color, blue); } .headline { color: var(--main-color, red); border-color: var(--main-color); } .theme-red { --main-color: #ff5205; }

Slide 20

Slide 20 text

… are inheritable
The whole page Just one element A special area of the site

Slide 21

Slide 21 text

The possibilities! http://codepen.io/ddprrt/pen/KzboRG

Slide 22

Slide 22 text

The possibilities! http://codepen.io/ddprrt/pen/NNeYOz @keyframes turn-wheel { from { transform: rotate(0deg); } to { transform: rotate( calc(15 * 360deg + var(--wheel-deg)) ) } } [class*=number-] { animation: turn-wheel 10s ease-out forwards; } .number-20 { --wheel-deg: 290deg; }

Slide 23

Slide 23 text

Controllable via JavaScript const wheel = document.querySelector(‘roulette-wheel’); wheel.style.setProperty('--wheel-deg', ‘100deg’); wheel.classList.add(‘number-custom');

Slide 24

Slide 24 text

Compatibility And a damn good polyfill in Polymer

Slide 25

Slide 25 text

Cascade and inheritance allow us to use custom properties as a styling interface

Slide 26

Slide 26 text

But it can be tough .player { display: block } header { color: var(--player-header-color); width: var(--player-header-width); height: var(--player-header-height); ... } footer { color: var(--player-footer-color); width: var(--player-footer-width); height: var(--player-footer-height); ... } .body { ... } player-character { --player-header-color: …; --player-header-width: …; --player-header-height: …; --player-footer-color: …; --player-footer-width: …; --player-footer-height: …; … }

Slide 27

Slide 27 text

Enter the apply rule .player { display: block } header { @apply --player-header; } footer { @apply --player-footer; } .body { ... } player-character { --player-header: { width: ..; height: ..; color: ..; }; --player-footer: { width: ..; height: ..; color: ..; }; }

Slide 28

Slide 28 text

Think mixins, inheritable, cascading mixins!

Slide 29

Slide 29 text

Custom Properteception .player { display: block } header { @apply --player-header; background-color: var(--hat-color); } footer { @apply --player-footer; color: var(--pants-color); } .body { ... } player-character { --player-header: { width: ..; height: ..; --hat-color: ..; }; --player-footer: { width: ..; height: ..; --pants-color: ..; }; }

Slide 30

Slide 30 text

transparent, resilient interface .mybemmed__header { @apply --player-header; background-color: var(--hat-color); } .mybemmed__footer { @apply --player-footer; color: var(--pants-color); } player-character { --player-header: { width: ..; height: ..; --hat-color: ..; }; --player-footer: { width: ..; height: ..; --pants-color: ..; }; }

Slide 31

Slide 31 text

transparent, resilient interface div:nth-of-type(1) { @apply --player-header; background-color: var(--hat-color); } div:not(:nth-of-type(1)) { @apply --player-footer; color: var(--pants-color); } player-character { --player-header: { width: ..; height: ..; --hat-color: ..; }; --player-footer: { width: ..; height: ..; --pants-color: ..; }; }

Slide 32

Slide 32 text

transparent, resilient interface //Access the properties via JavaScript! var styles = window.getComputedStyle(this); styles.getPropertyValue(‘--hat-color'); player-character { --player-header: { width: ..; height: ..; --hat-color: ..; }; --player-footer: { width: ..; height: ..; --pants-color: ..; }; }

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Don’t avoid the cascade, use it to your advantage in a tamed way

Slide 35

Slide 35 text

Custom properties and the @apply rule transfer selector complexity to the property level

Slide 36

Slide 36 text

This approach needs some documentation

Slide 37

Slide 37 text

The apply rule needs some time to land (but it’s pretty good polyfilled in Polymer)

Slide 38

Slide 38 text

Toshihiko Nakago Shigeru Miyamoto

Slide 39

Slide 39 text

@ddprrt See you at JSConf!