Slide 1

Slide 1 text

The Super Mario Bros. Principle

Slide 2

Slide 2 text

@ddprrt fettblog.eu

Slide 3

Slide 3 text

manning.com/ baumgartner

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Toshihiko Nakago Shigeru Miyamoto

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Toshihiko Nakago Shigeru Miyamoto

Slide 11

Slide 11 text

Toshihiko Nakago Shigeru Miyamoto

Slide 12

Slide 12 text

Toshihiko Nakago Shigeru Miyamoto

Slide 13

Slide 13 text

Provide something Robust Failsafe Flexible Easy to use

Slide 14

Slide 14 text

CSS is easy selector { property: value; }

Slide 15

Slide 15 text

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

Slide 16

Slide 16 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 17

Slide 17 text

Methodologies .l-fixed .sidebar { … } .logo { … }

Slide 18

Slide 18 text

Methodologies .search { … } .search__input--disabled { … } .search__input { … }

Slide 19

Slide 19 text

Methodologies

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

INLINE STYLES

Slide 22

Slide 22 text

CSS Methodologies OOCSS SMACSS BEM Atomic CSS

Slide 23

Slide 23 text

CSS Methodologies Tools Rules Opinions Edge Cases

Slide 24

Slide 24 text

All Methodologies Agree That it’s all about the specificity

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Sledgehammer methods?

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

CSS is easy by design Writing CSS is super hard

Slide 30

Slide 30 text

CSS is easy by design Writing good CSS is super hard

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Think back to miyamoto

Slide 33

Slide 33 text

Interfaces

Slide 34

Slide 34 text

Web components I’m Mario

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

Enter custom properties

Slide 38

Slide 38 text

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

Slide 39

Slide 39 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 40

Slide 40 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 41

Slide 41 text

… are inheritable
The whole page

Slide 42

Slide 42 text

… are inheritable
The whole page Just one element

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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!

Slide 49

Slide 49 text

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

Slide 50

Slide 50 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 51

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

That looks like an interface

Slide 59

Slide 59 text

Compatibility And a damn good polyfill in Polymer

Slide 60

Slide 60 text

Edge!

Slide 61

Slide 61 text

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

Slide 62

Slide 62 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 63

Slide 63 text

Well…

Slide 64

Slide 64 text

Enter level 2

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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: …; … }

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

Think mixins, inheritable, cascading mixins!

Slide 70

Slide 70 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 71

Slide 71 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 72

Slide 72 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 73

Slide 73 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 74

Slide 74 text

No content

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

The upsides

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

You design using the same interface regardless of the technology underneath

Slide 79

Slide 79 text

Styling of components becomes even more declarative

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

The downsides

Slide 84

Slide 84 text

This approach needs some documentation

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

This is also not the one solution for your css problems

Slide 88

Slide 88 text

Toshihiko Nakago Shigeru Miyamoto

Slide 89

Slide 89 text

Toshihiko Nakago Shigeru Miyamoto

Slide 90

Slide 90 text

@ddprrt