Pro Yearly is on sale from $80 to $50! »

The Super Mario Bros. Principle

The Super Mario Bros. Principle

The release of Super Mario Bros. brought us gameplay like we have never seen before. An experience that still holds up to this day. One of the reasons is the architecture of the game: It allows designers absolute freedom in creating levels without spending any thought on the implementation. Not caring about the technical details, but still design without limitations? Isn't that something we'd love for web development? See how we use CSS custom properties, web components and the power of the Cascade to transcend into creative Nirvana. Just like Miyamoto did 30 years ago.

187d92c9284160ad908885ab096f5209?s=128

Stefan Baumgartner

May 11, 2016
Tweet

Transcript

  1. The Super Mario Bros. Principle

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

  3. None
  4. Toshihiko Nakago Shigeru Miyamoto

  5. I could insert anything into a level, Nakago’s System would

    at least do something with it
  6. Toshihiko Nakago Shigeru Miyamoto

  7. Toshihiko Nakago Shigeru Miyamoto

  8. Provide something Robust Failsafe Flexible Easy to use

  9. CSS is easy selector { property: value; }

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

  11. 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
  12. This can be overwhelming Even with all the tools and

    tooling
  13. Why can’t it be as easy as a { color:

    red; }
  14. Interfaces

  15. Web components <player-character> I’m Mario </player-character> <div class=“player”> <header>!</header> <div

    class=“body”>"</div> <footer>#</footer> </div>
  16. Web components document .querySelector( ‘player-character’) .addEventListener( ‘jump’, () => {

    // do something }) handleClick: function(e) { this.fire(‘jump’); }
  17. Web components .player { ... } header { ... }

    footer { ... } .body { ... }
  18. 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); }
  19. … 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; }
  20. … are inheritable <body class=“theme-red”> <div class=“box”>…</div> </body> <body> <div

    class=“box theme-red”>…</div> </body> <body> <div class=“theme-red”> <div class=“box”>…</div> <div class=“box”>…</div> </div> <div class=“box”>…</div> </body> The whole page Just one element A special area of the site
  21. The possibilities! http://codepen.io/ddprrt/pen/KzboRG

  22. 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; }
  23. Controllable via JavaScript const wheel = document.querySelector(‘roulette-wheel’); wheel.style.setProperty('--wheel-deg', ‘100deg’); wheel.classList.add(‘number-custom');

  24. Compatibility And a damn good polyfill in Polymer

  25. Cascade and inheritance allow us to use custom properties as

    a styling interface
  26. 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: …; … }
  27. 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: ..; }; }
  28. Think mixins, inheritable, cascading mixins!

  29. 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: ..; }; }
  30. 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: ..; }; } <div class=“mybemmed”> <div class=“mybemmed__footer”></div> <div class=“mybemmed__header”></div> </div>
  31. 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: ..; }; } <div></div> <div></div>
  32. 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: ..; }; } <canvas></canvas>
  33. None
  34. Don’t avoid the cascade, use it to your advantage in

    a tamed way
  35. Custom properties and the @apply rule transfer selector complexity to

    the property level
  36. This approach needs some documentation

  37. The apply rule needs some time to land (but it’s

    pretty good polyfilled in Polymer)
  38. Toshihiko Nakago Shigeru Miyamoto

  39. @ddprrt See you at JSConf!