Oleg Slobodskoi, Chatgrape, Berlin — Javascript Style Sheets

Oleg Slobodskoi, Chatgrape, Berlin — Javascript Style Sheets

Oleg Slobodskoi, Chatgrape, Berlin — Javascript Style Sheets

About the good parts of writing styles in javascript using JSS. Comparison to other existing CSS solutions and points about negative aspects got so far.

5799a3c0434b91ef7e00e730629390f0?s=128

React Amsterdam

April 21, 2016
Tweet

Transcript

  1. 1 JavaScript Style JavaScript Style Sheets Sheets by Oleg Slobodskoi

    jss React Amsterdam 2016
  2. 2 Plan Plan 1. React and CSS. 2. What are

    inline styles. 3. Problems solved by inline styles. 4. Interesting CSS in JS libs. 5. What is JSS. 6. Problems solved by JSS. 7. Unsolved problems.
  3. 3 React and CSS React and CSS React is about

    React is about components components. . CSS is for CSS is for documents. documents.
  4. 4 First JSS release First JSS release

  5. 5

  6. 6 Inline styles Inline styles const style = {color: red}

    <div style={style}></div> <div style="color: red"></div> HTML React const element = document.createElement('div') element.style.color = 'red' DOM
  7. 7 Global Namespace Global Namespace Selectors are the evil. Try

    to write an application inside of one function.
  8. 8 Implicit Implicit Dependencies Dependencies <button class="default-button my-button">My Button</button> /*

    buttons.css */ .default-button { cursor: pointer; } /* my-component.css */ .my-button { color: red; }
  9. 9 Dead code Dead code A task for a compiler.

    function module() { var styles = { button: { color: 'green' }, myButton: { color: 'red' } } // Renders a button. button({style: styles.myButton}) } function module(){button({style:{color:"red"}})};
  10. 10 Minification Minification function test(a) { var obj = {a:

    a, b: 2}; return obj.a + obj.b; } window.a = test(1) window.a=3; No selectors to minify. JavaScript compressor for the rest.
  11. 11 Sharing Constants Sharing Constants Data driven styling Shared Breakpoints

    Javascript Layouts
  12. 12 Non-deterministic Non-deterministic Resolution Resolution CSS Specificity Concept. /* my-button-1.css

    */ .my-button.my-blue-button { color: blue; } /* my-button-2.css */ button.my-button { color: red; } <head> <link href="my-button-1.css" rel="stylesheet" /> <link href="my-button-2.css" rel="stylesheet" /> </head> <body> <button class="my-button">My Button</button> </body>
  13. 13 Isolation Isolation No access to external components. Very high

    specificity.
  14. 14 Complex Selectors Complex Selectors .article #comments ul > li

    > a.button
  15. 15 Redundancy Redundancy Smaller payload.

  16. 16 Can we do even Can we do even better?

    better? YES. YES.
  17. 17 Other alternatives? Other alternatives?

  18. 18 And more ... And more ...

  19. 19 And more ... And more ... Text https://github.com/MicheleBertoli/css-in-js

  20. 20 3 Categories 3 Categories 1. Pure Inline 2. Mixed

    Mode 3. Pure Style Sheets
  21. 21 Pure Pure Inline Inline Already built in React No

    support for @media, @keyframes etc. Performance Downsides
  22. 22 Mixed Mode Mixed Mode Radium is using: React Events

    for Pseudo Selectors. Style Sheets for @media and co. Inline for everything else.
  23. 23 Pure Pure Style Sheets Style Sheets Aphrodite JSS

  24. 24 What is JSS. What is JSS. Good parts of

    CSS only. Designed with components in mind. Declarative JavaScript. JavaScript to CSS compiler. Easy to reason about.
  25. 25 How does it work. How does it work. Virtual

    CSS Tree Process Render Run plugins on every VRule Output <style> with CSS. Abstraction for CSS Rules Manipulation
  26. 26 React-JSS React-JSS Lazy compilation Ref counting

  27. 27 Example with React Example with React import React from

    'react' import {useSheet} from 'react-jss' @useSheet({ button: { color: 'green' } }) export default function Button(props) { const {classes} = props.sheet return <button className={classes.button}>{props.text}</button> } No magic in code.
  28. 28

  29. 29 Boring CSS output. Boring CSS output.

  30. 30 Problems it solves. Problems it solves. 1. All issues

    solved by Inline Styles. 2. Issues introduced by Inline Styles. 3. More CSS Issues.
  31. 31 Plan Plan 1. Media Queries 2. Keyframes Animation 3.

    Font Face 4. Pseudo Selectors 5. Fallbacks 6. Rules Caching 7. Rules Sharing 8. Extensible Architecture 9. Tools Agnostic 10. Vendor Prefixer 11. Inheritance DSL Library
  32. 32 Media Queries Media Queries export default { '@media (min-width:

    1024px)': { button: { minWidth: 200 } } } const breakpoint = 1024 export default { [`@media (min-width: ${breakpoint}px)`]: { button: { minWidth: 200 } } } @media (min-width: 1024px) { .button-jss-0 { min-width: 200px; } } JSS in ES5 JSS in ES6 CSS Not possible Inline.
  33. 33 Keyframes Animation Keyframes Animation export default { '@keyframes my-animation':

    { from: {opacity: 0}, to: {opacity: 1} } } const identifier = random() export default { [`@keyframes ${identifier}`]: { from: {opacity: 0}, to {opacity: 1} } } @keyframes my-animation { from { opacity: 0; } to { opacity: 1; } } JSS in ES5 JSS in ES6 CSS Not possible Inline.
  34. 34 Font Face Font Face export default { '@font-face': {

    fontFamily: 'MyWebFont', src: [ 'url(webfont.eot)', 'url(webfont.eot?#iefix) format(embedded-opentype)', 'url(webfont.woff2) format(woff2)' ] } } @font-face { font-family: 'MyWebFont'; src: url('webfont.eot'); src: url('webfont.eot?#iefix') format('embedded-opentype'), url('webfont.woff2') format('woff2'); } JSS CSS Not possible Inline.
  35. 35 Pseudo Selectors Pseudo Selectors export default { button: {

    color: 'green' '&:hover': { color: 'red' }, '&:active': { color: blue }, '&:before': { content: '"icon"' }, '& span': { verticalAlign: 'middle' } } } .jss-0-1 { color: green; } .jss-0-1:hover { color: red; } .jss-0-1:active { color: blue; } .jss-0-1:before { content: "icon"; } .jss-0-1 span { vertical-align: middle; } JSS CSS Not possible Inline. Inspired by Sass.
  36. 36 Fallbacks Fallbacks export default { container: { display: ['box',

    'flexbox','flex'] } } .jss-0-1 { display: box; display: flexbox; display: flex; } JSS CSS Not possible Inline.
  37. 37 Rules Caching Rules Caching Not possible Inline. CSS Rules

    are created just once.
  38. 38 Rules Sharing Rules Sharing Not possible Inline. One rule

    applies to all list items
  39. 39 Class Names are fast. Class Names are fast. 1.

    Find modified props. 2. Find props to unset. 3. Ensure valid property name, value, default unit. 4. Apply each property to an element
  40. 40 Smaller Payload Smaller Payload Up to 50% smaller payload

    when rendered at runtime.
  41. 41 Tools Agnostic Tools Agnostic Library agnostic. Infrastructure agnostic.

  42. 42 Extensible Extensible Small Core Plugins API.

  43. 43 Vendor Prefixer Vendor Prefixer Plugin export default { container:

    { display: 'flex' } } .jss-0-1 { display: -webkit-flex; } JSS CSS
  44. 44 Inheritance Inheritance Styles inherit from parent. Still no TRUE

    Isolation.
  45. 45 JSS-ISOLATE JSS-ISOLATE Created a JSS plugin. and SOLVED INHERITANCE

    PROBLEM Maxim Koretskiy “ This plugin protects styles from inheritance. It automatically creates a reset rule and applies it to every user's rule.
  46. 46 Unsolved Problems Unsolved Problems :( :(

  47. 47 Overengineered Overengineered Solution Solution If you feel it -

    don't use it.
  48. 48 Wrong Language? Wrong Language? import color from 'color' import

    fonts from 'theme/fonts' import mixins from 'jss-mixins' import {gainsboroLight, grapeTypo, grey, blue, white} from 'theme/colors' const grapeTypoSemi = color(grapeTypo).alpha(0.5).rgbaString() export default { datalist: { background: white, border: `1px solid ${gainsboroLight}`, boxShadow: `0px 3px 4px 0 ${grapeTypoSemi}`, overflow: 'auto' }, item: { extend: [fonts.normal, mixins.ellipsis], padding: `5px 7px`, color: grey, cursor: `pointer` }, `@media (min-width: 1024px)`: { item: { color: blue } } }
  49. 49 Let's experiment! Let's experiment! export default css` datalist {

    background: ${white}; border: 1px solid ${gainsboroLight}; box-shadow: 0px 3px 4px 0 ${grapeTypoSemi}; overflow: auto } item { extend: ${[fonts.normal, mixins.ellipsis]}; padding: 5px 7px; color: ${grey}; cursor: ${pointer}; } @media (min-width: 1024px) { item { color: ${blue} } } ` Tagged template literals
  50. 50 No standard DSL No standard DSL Styles reuse only

    together with the lib.
  51. 51 Missing dev tools Missing dev tools There is no

    autocomplete tools like Emmet or IntelliSense. There is no CSS specific highlighting. No linters.
  52. 52 Blocks initial Blocks initial rendering. rendering. Use it where

    it doesn't matter. Use server-side rendering. Use a hybrid approach.
  53. 53 Takeaways Takeaways CSS in JS is not only for

    big projects, it's for any maintainable project. Use Inline Styles for: 1. State styles. For e.g. when a "width" of a component depends on its state. 2. Animations. Don't be religious. Keep an open mind. Use tools that solve your problems!
  54. 54 Thank You Thank You #reactamsterdam @oleg008 https://github.com/jsstyles/jss