Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Super Mario Bros. Principle - Extended Edition

The Super Mario Bros. Principle - Extended Edition

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.

Stefan Baumgartner

September 23, 2016
Tweet

More Decks by Stefan Baumgartner

Other Decks in Technology

Transcript

  1. The Super Mario Bros.
    Principle

    View full-size slide

  2. @ddprrt
    fettblog.eu

    View full-size slide

  3. manning.com/
    baumgartner

    View full-size slide

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

    View full-size slide

  5. Super Mario Bros. was about
    40 KB in Size
    That’s the same size as today’s
    Minified Bootstrap JavaScript*
    * Bootstrap 4, non-gzipped

    View full-size slide

  6. Toshihiko Nakago Shigeru Miyamoto

    View full-size slide

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

    View full-size slide

  8. Toshihiko Nakago Shigeru Miyamoto

    View full-size slide

  9. Toshihiko Nakago Shigeru Miyamoto

    View full-size slide

  10. Toshihiko Nakago Shigeru Miyamoto

    View full-size slide

  11. Provide something
    Robust
    Failsafe
    Flexible
    Easy to use

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  14. 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

    View full-size slide

  15. Methodologies
    .l-fixed .sidebar {

    }
    .logo {

    }

    View full-size slide

  16. Methodologies
    .search {

    }
    .search__input--disabled {

    }
    .search__input {

    }

    View full-size slide

  17. Methodologies

    View full-size slide

  18. INLINE STYLES

    View full-size slide

  19. CSS Methodologies
    OOCSS
    SMACSS
    BEM
    Atomic CSS

    View full-size slide

  20. CSS Methodologies
    Tools
    Rules
    Opinions
    Edge Cases

    View full-size slide

  21. All Methodologies
    Agree
    That it’s all about
    the specificity

    View full-size slide

  22. Keeping
    it low
    Keeping
    it high
    BEM
    Atomic
    OOCSS
    SMACSS
    Inline
    Styles

    View full-size slide

  23. Consensus
    Avoid specificity chaos
    Don’t use the cascade
    Stop the inheritance

    View full-size slide

  24. Sledgehammer methods?

    View full-size slide

  25. Finding the right selectors
    can be overwhelming
    Even with all the
    tools and tooling

    View full-size slide

  26. CSS is easy
    by design
    Writing CSS is
    super hard

    View full-size slide

  27. CSS is easy
    by design
    Writing good CSS is
    super hard

    View full-size slide

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

    View full-size slide

  29. Think back to
    miyamoto

    View full-size slide

  30. Web components

    I’m Mario






    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. Enter custom properties

    View full-size slide

  34. Also known as CSS Variables
    a {
    --a-property: red;
    }

    View full-size slide

  35. 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);
    }

    View full-size slide

  36. … 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;
    }

    View full-size slide

  37. … are inheritable



    The whole page

    View full-size slide

  38. … are inheritable



    The whole page
    Just one element



    View full-size slide

  39. … are inheritable



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










    View full-size slide

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

    View full-size slide

  41. The possibilities!
    http://codepen.io/ddprrt/pen/NNeYOz

    View full-size slide

  42. The possibilities!
    http://codepen.io/ddprrt/pen/NNeYOz

    View full-size slide

  43. The possibilities!
    http://codepen.io/ddprrt/pen/NNeYOz
    @keyframes turn-wheel-to-20 {
    from { transform: rotate(0deg); }
    to {
    transform: rotate(5690deg)
    }
    }
    .number-20 {
    animation: turn-wheel 10s ease-out forwards;
    }

    View full-size slide

  44. The possibilities!
    http://codepen.io/ddprrt/pen/NNeYOz
    @keyframes turn-wheel-to-20 {
    from { transform: rotate(0deg); }
    to {
    transform: rotate(5690deg)
    }
    }
    .number-20 {
    animation: turn-wheel 10s ease-out forwards;
    }
    just for one!

    View full-size slide

  45. The possibilities!
    http://codepen.io/ddprrt/pen/NNeYOz

    View full-size slide

  46. 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;
    }

    View full-size slide

  47. 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;
    }
    turns 1 turn the actual position

    View full-size slide

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

    View full-size slide

  49. But it helps with simple stuff as well
    a {
    color: #f00;
    text-decoration: none;
    }
    a:active,
    a:focus,
    a:hover {
    color: #e00;
    }
    a:visited: {
    color: #f00;
    }

    View full-size slide

  50. But it helps with simple stuff as well
    a {
    color: #f00;
    text-decoration: none;
    }
    a:active,
    a:focus,
    a:hover {
    color: #e00;
    }
    a:visited: {
    color: #f00;
    }
    .btn {
    color: #fff;
    background-color: #0f0;
    }
    .btn:active,
    .btn:focus,
    .btn:hover {
    background-color: #0e0;
    }
    .btn:visited {
    background-color: #0f0;
    }

    View full-size slide

  51. But it helps with simple stuff as well
    a {
    color: #f00;
    text-decoration: none;
    }
    a:active,
    a:focus,
    a:hover {
    color: #e00;
    }
    a:visited: {
    color: #f00;
    }
    .btn {
    color: #fff;
    background-color: #0f0;
    }
    .btn:active,
    .btn:focus,
    .btn:hover {
    background-color: #0e0;
    }
    .btn:visited {
    background-color: #0f0;
    }

    View full-size slide

  52. But it helps with simple stuff as well
    a {
    color: var(--txt-color, #f00);
    text-decoration: none;
    }
    a:active,
    a:focus,
    a:hover {
    color: var(--foc-color, #e00);
    }
    a:visited: {
    color: var(--txt-color, #f00);
    }
    .btn {
    --txt-color: #fff;
    --foc-color: #fff;
    background-color: #0f0;
    }
    .btn:active,
    .btn:focus,
    .btn:hover, {
    background-color: #0e0;
    }

    View full-size slide

  53. But it helps with simple stuff as well
    a {
    color: var(--txt-color, #f00);
    background-color:
    var(--bg-color, transparent);
    text-decoration: none;
    }
    a:active,
    a:focus,
    a:hover {
    color: var(--foc-color, #e00);
    background-color:
    var(--bg-act-color, transparent);
    }
    .btn {
    --txt-color: #fff;
    --foc-color: #fff;
    --bg-color: #0f0;
    --bg-act-color: #0e0;
    }

    View full-size slide

  54. That looks like an
    interface

    View full-size slide

  55. Compatibility
    And a damn good polyfill in Polymer

    View full-size slide

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

    View full-size slide

  57. 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: …;

    }

    View full-size slide

  58. Enter level 2

    View full-size slide

  59. Custom property sets
    player-character {
    --player-head: {
    color: …;
    width: …;
    height: …;
    }
    }

    View full-size slide

  60. Custom property sets
    player-character {
    --player-head: {
    color: …;
    width: …;
    height: …;
    }
    }
    header {
    @apply(--player-head);
    }

    View full-size slide

  61. Without @apply
    .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: …;

    }

    View full-size slide

  62. With @apply
    .player {
    display: block
    }
    header {
    @apply --player-header;
    }
    footer {
    @apply --player-footer;
    }
    .body { ... }
    player-character {
    --player-header: {
    width: ..;
    height: ..;
    color: ..;
    };
    --player-footer: {
    width: ..;
    height: ..;
    color: ..;
    };
    }

    View full-size slide

  63. Think mixins,
    inheritable, cascading
    mixins!

    View full-size slide

  64. 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: ..;
    };
    }

    View full-size slide

  65. 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: ..;
    };
    }




    View full-size slide

  66. 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: ..;
    };
    }


    View full-size slide

  67. 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: ..;
    };
    }

    View full-size slide

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

    View full-size slide

  69. You design using
    the same interface
    regardless of
    the technology
    underneath

    View full-size slide

  70. Styling of components
    becomes even more
    declarative

    View full-size slide

  71. You don’t avoid the cascade,
    You use it to your advantage

    View full-size slide

  72. Keeping
    it low
    Keeping
    it high
    BEM
    Atomic
    OOCSS
    SMACSS
    Inline
    Styles

    View full-size slide

  73. Keeping
    it low
    Keeping
    it high
    BEM
    Atomic
    OOCSS
    SMACSS
    Inline
    Styles

    View full-size slide

  74. The downsides

    View full-size slide

  75. This approach needs some
    documentation

    View full-size slide

  76. You need JS polyfills
    for now if you want to go
    cross-browser

    View full-size slide

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

    View full-size slide

  78. This is also not
    the one solution for
    your css problems

    View full-size slide

  79. Toshihiko Nakago Shigeru Miyamoto

    View full-size slide

  80. Toshihiko Nakago Shigeru Miyamoto

    View full-size slide