Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

CSS in React - Will Change Transform

236 views

Published on

Talk on how CSS in JS is transforming the powers we have. Making our projects more automated, sharable, adaptable, scalable, and maintainable.

Published in: Technology
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

CSS in React - Will Change Transform

  1. 1. .css__in--react { will-change: transform; }
  2. 2. CSS IN React
  3. 3. Joe Seifi
  4. 4. Eventbrite
  5. 5. @BODY fo(fa=he,si=18) @P co(nu=3,wi=80) (BODY fontSize=normal BGColor=white FGColor=black (H1 fontSize=largest BGColor=red FGColor=white) ) h1.font.size = 24pt 100% h2.font.size = 20pt 40% *LI.prebreak: 0.5 *LI.postbreak: 0.5 *OL.LI.label: 1 *OL*OL.LI.label: A (element H1 (make paragraph font-size: 14pt font-weight: 'bold)) (style a (block #f) ; format as inline phrase (color blue) ; in blue if you’ve got it (click (follow (attval 'href))) ; and on click, follow url LI { VertPos: Top = LeftSib . Actual Bottom; } A { if (getAttribute(self, "href") != "") then fgColor = "blue"; underlineNumber = 1; endif } tags.H1.color = "blue"; tags.p.fontSize = "14pt"; with (tags.H3) { color = "green"; } classes.punk.all.color = "#00FF00" ids.z098y.letterSpacing = "0.3em"
  6. 6. RRP @BODY fo(fa=he,si=18) @P co(nu=3,wi=80) PWP (BODY fontSize=normal BGColor=white FGColor=black (H1 fontSize=largest BGColor=red FGColor=white) ) CHSS h1.font.size = 24pt 100% h2.font.size = 20pt 40% RRP *LI.prebreak: 0.5 *LI.postbreak: 0.5 *OL.LI.label: 1 *OL*OL.LI.label: A DSSSL (element H1 (make paragraph font-size: 14pt font-weight: 'bold)) RRP (style a (block #f) ; format as inline phrase (color blue) ; in blue if you’ve got it (click (follow (attval 'href))) ; and on click, follow url PSL LI { VertPos: Top = LeftSib . Actual Bottom; } A { if (getAttribute(self, "href") != "") then fgColor = "blue"; underlineNumber = 1; endif } JSSS tags.H1.color = "blue"; tags.p.fontSize = "14pt"; with (tags.H3) { color = "green"; } classes.punk.all.color = "#00FF00" ids.z098y.letterSpacing = "0.3em" Pre-CSS 1993-1996
  7. 7. My first website ~ 1997
  8. 8. JavaScript MVC Components 💄!11
  9. 9. CSS Modular CSS CSS in JS OOCSS SMACS SUIT BEM ATOMIC 💄
  10. 10. Super Powers of CSS in React - Automation - Sharable - Adaptable - Scalable - Maintainable
  11. 11. Giving up Control, actually gives you more control and new Super Powers
  12. 12. Automation
  13. 13. Managing CSS Classnames
  14. 14. There are only 2 hard problems in Computer Science: cache invalidation & naming things Phil Karlton from Netscape
  15. 15. B__E--M > 0__1--0
  16. 16. regular css imports .btn { color: #fff; background: pink;
 } button.css import './button.css'
  17. 17. css-modules import styles from './button.css' .btn { color: #fff; background: pink;
 } button.css
  18. 18. css-modules import styles from './button.css' console.log(styles) > { “btn": "button_btn_2Yt" } .btn { color: #fff; background: pink;
 } button.css
  19. 19. import React from 'react' import CSSModules from ‘react-css-modules' import styles from ‘./button.css’ @CSSModules(styles) const Button = ({ children }) => <button styleName=“btn”> {children} </button> React CSS Modules Buy .btn { color: #fff; background: pink;
 } button.css
  20. 20. React CSS Modules .btn { color: #fff; background: pink;
 } .button_btn_2Yt { color: #fff; background-color: pink; } <button class="button_btn_2Yt"> Buy </button> browser import React from 'react' import CSSModules from ‘react-css-modules' import styles from ‘./button.css’ @CSSModules(styles) const Button = ({ children }) => <button styleName=“btn”> {children} </button> // render <Button>Buy</Button> button.css Buy
  21. 21. DeCSS .Button { color: #fff; background: orange; } import React from 'react' import { Button } from './Button.css' Button.css
  22. 22. DeCSS .Button { color: #fff; background: orange; } import React from 'react' import { Button } from './Button.css' const MyButton = ({ children }) => ( <Button tag="button"> {children} </Button> ) // render <MyButton>Buy</MyButton> Button.css
  23. 23. DeCSS .Button { color: #fff; background: orange; } .button_Button_2V6 { color: #fff; background: orange; } <button class="button_Button_2V6"> Buy </button> browser import React from 'react' import { Button } from './Button.css' const MyButton = ({ children }) => ( <Button tag="button"> {children} </Button> ) // render <MyButton>Buy</MyButton> Button.css Buy
  24. 24. Sharable
  25. 25. Bootstrap Nation 122K 2nd largest project on Github
  26. 26. React classNames
  27. 27. <button id="btn">
 Buy
 </button> Buy HTML
  28. 28. <button id="btn">
 Buy
 </button> $("#btn").click(() => { // take money
 } Buy HTML JavaScript
  29. 29. <button id="btn">
 Buy
 </button> $("#btn").click(() => { // take money
 } Buy HTML JavaScript
  30. 30. <Button onClick="this.takeMoney">
 Buy
 </Button> HTML in JavaScript Buy
  31. 31. <Button onClick="this.takeMoney">
 Buy
 </Button> HTML in JavaScript Buy
  32. 32. <button className="btn">
 Buy
 </button> .btn { color: #fff; background-color: pink; } Buy HTML CSS
  33. 33. classNames > Components .glue_to_ui { /** **/ }
  34. 34. Styled Components Buy import React from 'react' import styled from 'styled-components'
  35. 35. Styled Components Buy import React from 'react' import styled from 'styled-components' const Button = styled.button` color: #fff; background-color: pink; `
  36. 36. Styled Components Buy import React from 'react' import styled from 'styled-components' const Button = styled.button` color: #fff; background-color: pink; ` .ctyFSz { color: #fff; background-color: pink; } .sc-bdVaJa { } <button class="sc-bdVaJa ctyFSz”> Buy </button> browser Buy // render <Button>Buy</Button>
  37. 37. Styled Components Buy 43 // shared-lib export const Shared = ({ className }) => ( <div className={ className }>Sharing is caring!</div> ) // our-app import styled from 'styled-components' import { Shared } from 'shared-lib'
  38. 38. Styled Components Buy 44 // shared-lib export const Shared = ({ className }) => ( <div className={ className }>Sharing is caring!</div> ) // our-app import styled from 'styled-components' import { Shared } from 'shared-lib' const Wrapped = styled(Shared)`color: pink;`
  39. 39. Styled Components Buy 45 // shared-lib export const Shared = ({ className }) => ( <div className={ className }>Sharing is caring!</div> ) // our-app import styled from 'styled-components' import { Shared } from 'shared-lib' const Wrapped = styled(Shared)`color: pink;` <Shared /> Sharing is caring! <Wrapped /> Sharing is caring!
  40. 40. JSON vs CSS
  41. 41. Glamorous Buy import React from ‘react' import glamorous from 'glamorous'
  42. 42. Glamorous Buy import React from ‘react' import glamorous from 'glamorous' const Button = glamorous.button({ color: '#fff', backgroundColor: 'pink' })
  43. 43. Glamorous Buy import React from ‘react' import glamorous from 'glamorous' const Button = glamorous.button({ color: '#fff', backgroundColor: 'pink' }) .css-glamorous-button--1yceljy, [data-css-glamorous-button--1yceljy] { color: #fff; background-color: pink; } <button class="css-glamorous-button--1yceljy"> Button </button> browser Buy // render <Button>Buy</Button>
  44. 44. Emotion Buy 50 import { css } from 'emotion' const base = css({ fontWeight: 600 }) const child = css` ${base}; color: pink; background-color: black; ` <p className={ child }> Inheriting base styles </p> Inheriting base styles
  45. 45. Adaptable
  46. 46. 53 Styled System
  47. 47. Buy 54 import styled from 'styled-components' import { width } from 'styled-system' const Box = styled.div`${width}` const responsiveWidths = [ 1, 1/2, 1/4 ] const App = () => ( <Box width={ responsiveWidths }> 100% below smallest breakpoint 50% from next breakpoint up 25% from next breakpoint up </Box> ) Styling Layout Styled System
  48. 48. 55 Adapt Styles to App State
  49. 49. Styling State Styled Components Buy 56 <Password /> Enter Password import styled from 'styled-components' const Input = styled.input`padding: 5px;` const Password = Input.extend.attrs({ placeholder: 'Enter Password’ }) ` border-color: black; ` <Input />
  50. 50. Styling State Styled Components Buy 57 <Password /> Enter Password import styled from 'styled-components' const Input = styled.input`padding: 5px;` const Password = Input.extend.attrs({ placeholder: 'Enter Password’ }) ` border-color: ${props => props.error ? 'red' : 'black'}; ` <Password error /> Enter Password <Input />
  51. 51. DeCSS .Button { color: #fff; background: orange; } .Button-danger { background: red; } import React from 'react' import { Button } from './Button.css' const MyButton = ({ children, danger }) => ( <Button tag=“button" danger={ danger }> {children} </Button> ) Button.css
  52. 52. DeCSS .Button { color: #fff; background: orange; } .Button-danger { background: red; } import React from 'react' import { Button } from './Button.css' const MyButton = ({ children, danger }) => ( <Button tag=“button" danger={ danger }> {children} </Button> ) Button.css module: { rules: [ { test: /.css$/, use: [ 'style-loader', 'decss-loader/react', 'css-loader?modules ] }, ] } webpack.config
  53. 53. DeCSS .Button { color: #fff; background: orange; } .Button-danger { background: red; } import React from 'react' import { Button } from './Button.css' const MyButton = ({ children, danger }) => ( <Button tag="button" danger={ danger }> {children} </Button> ) // render <MyButton danger>Buy</MyButton> Button.css .button_Button_2V6 { color: #fff; background: orange; } .button_Button-danger_2nt { background: red; } <button class="button_Button-danger_2nt button_Button_2V6"> Buy </button> browser Buy
  54. 54. Buy 61 Styling Elements Global Styling // Emotion // set color of nav globally const MyNav = styled(Nav)` :global(.nav) { color: pink; } ` // set box-sizing on all HTML elements import { injectGlobal } from 'emotion' injectGlobal` * { box-sizing: border-box; } ` /* CSS Modules */ // set color of nav globally :global .nav { color: pink; }
  55. 55. Maintainable
  56. 56. dealing with Dead & Unused CSS
  57. 57. Example Scenario Buy 65 import './input.css' const C1 = () => <input className="c1" /> const C2 = () => <input className="c2" /> input.css .c1 { padding: 1em; } .c2 { padding: 2em }
  58. 58. Buy 66 import './input.css' const C1 = () => <input className="c1" /> const C2 = () => <input className="c2" /> const App = () => <div><C1 /><C2 /></div> <style type="text/css"> .c1 { padding: 1em; } .c2 { padding: 2em } </style> input.css browser Example Scenario .c1 { padding: 1em; } .c2 { padding: 2em }
  59. 59. Stop Using <C2 /> Buy 67 import './input.css' const C1 = () => <input className="c1" /> const C2 = () => <input className="c2" /> const App = () => <div><C1 /></div> .c1 { padding: 1em; } .c2 { padding: 2em } input.css <style type="text/css"> .c1 { padding: 1em; } .c2 { padding: 2em } </style> browser
  60. 60. Unused CSS Buy 68 import './input.css' const C1 = () => <input className="c1" /> const C2 = () => <input className="c2" /> const App = () => <div><C1 /></div> input.css <style type="text/css"> .c1 { padding: 1em; } .c2 { padding: 2em } </style> browser .c1 { padding: 1em; } .c2 { padding: 2em }
  61. 61. Delete <C2 /> Buy 69 import './input.css' const C1 = () => <input className="c1" /> const App = () => <div><C1 /></div> input.css <style type="text/css"> .c1 { padding: 1em; } .c2 { padding: 2em } </style> browser .c1 { padding: 1em; } .c2 { padding: 2em }
  62. 62. Dead CSS Buy 70 import './input.css' const C1 = () => <input className="c1" /> const App = () => <div><C1 /></div> input.css <style type="text/css"> .c1 { padding: 1em; } .c2 { padding: 2em } </style> browser .c1 { padding: 1em; } .c2 { padding: 2em }
  63. 63. Buy 71 import styled from 'react-emotion' const C1 = styled.input`padding: 1em` const C2 = styled.input`padding: 2em` const App = () => <div><C1 /><C2 /></div> <style type="text/css" data-emotion=""> .css-1ylegpj-C1 { padding:1em; } .css-12zs2me-C2 { padding:2em; } </style> App.js browser using Styled Components
  64. 64. Buy 72 import styled from 'react-emotion' const C1 = styled.input`padding: 1em` const C2 = styled.input`padding: 2em` const App = () => <div><C1 /></div> <style type="text/css" data-emotion=""> .css-1ylegpj-C1 { padding:1em; } </style> browser there’s No Unused / Dead CSS
  65. 65. Buy 73 import styled from 'react-emotion' const C1 = styled.input`padding: 1em` const C2 = styled.input`padding: 2em` const App = () => <div><C1 /></div> <style type="text/css" data-emotion=""> .css-1ylegpj-C1 { padding:1em; } </style> browser automatic Critical CSS
  66. 66. 74 testing styles using Snapshots
  67. 67. Buy 75 import React from 'react' import styled from 'styled-components' import renderer from 'react-test-renderer' import 'jest-styled-components' const Button = styled.button`color: pink;` testing styles using Snapshots
  68. 68. Buy 76 import React from 'react' import styled from 'styled-components' import renderer from 'react-test-renderer' import 'jest-styled-components' const Button = styled.button`color: pink;` test('Button renders correctly', () => { const button = renderer.create(<Button />).toJSON() expect(button).toMatchSnapshot() expect(button).toHaveStyleRule('color', 'pink') }) testing styles using Snapshots
  69. 69. Buy 77 import React from 'react' import styled from 'styled-components' import renderer from 'react-test-renderer' import 'jest-styled-components' const Button = styled.button`color: pink;` test('Button renders correctly', () => { const button = renderer.create(<Button />).toJSON() expect(button).toMatchSnapshot() expect(button).toHaveStyleRule('color', 'pink') }) testing styles using Snapshots
  70. 70. Buy 78 import React from 'react' import styled from 'styled-components' import renderer from 'react-test-renderer' import 'jest-styled-components' const Button = styled.button`color: pink;` test('Button renders correctly', () => { const button = renderer.create(<Button />).toJSON() expect(button).toMatchSnapshot() expect(button).toHaveStyleRule('color', 'pink') }) testing styles using Snapshots exports[`Button renders correctly 1`] = ` .c0 { color: pink; } <button className="c0" /> `; Button.spec.js.snap
  71. 71. Buy 79 import React from 'react' import styled from 'styled-components' import renderer from 'react-test-renderer' import 'jest-styled-components' const Button = styled.button`color: pink;` test('Button renders correctly', () => { const button = renderer.create(<Button />).toJSON() expect(button).toMatchSnapshot() expect(button).toHaveStyleRule('color', 'pink') }) jest --watch testing styles using Snapshots
  72. 72. Scaleable
  73. 73. 82 Server Side Rendering CSS in JS
  74. 74. Buy 83 import React from 'react' import { renderStylesToString } from 'emotion-server' import { renderToString } from 'react-dom/server import App from './App' const html = renderStylesToString(renderToString(<App />)) Server Side Rendering
  75. 75. Buy 84 import React from 'react' import { renderStylesToString } from 'emotion-server' import { renderToString } from 'react-dom/server import App from './App' const html = renderStylesToString(renderToString(<App />)) <!DOCTYPE html> <html lang="en"> <body><div id="root"><main data-reactroot=""><div><style data-emotion- css="66u5jz">.css-66u5jz{padding:1em;}</style><input class="css-66u5jz e1c3ej80"/><style data-emotion-css="186egwm">.css-186egwm{padding:2em;}</style><input class="css-186egwm e1c3ej81"/></div></main></div> <script type="text/javascript" src="/runtime.js"></script><script type="text/javascript" src="/vendors~main.js"></script><script type="text/javascript" src="/main.js"></script></ body> </html> browser Server Side Rendering
  76. 76. Buy 85 import React from 'react' import { renderStylesToString } from 'emotion-server' import { renderToString } from 'react-dom/server import App from './App' const html = renderStylesToString(renderToString(<App />)) <!DOCTYPE html> <html lang="en"> <body><div id="root"><main data-reactroot=""><div><style data-emotion- css="66u5jz">.css-66u5jz{padding:1em;}</style><input class="css-66u5jz e1c3ej80"/><style data-emotion-css="186egwm">.css-186egwm{padding:2em;}</style><input class="css-186egwm e1c3ej81"/></div></main></div> <script type="text/javascript" src="/runtime.js"></script><script type="text/javascript" src="/vendors~main.js"></script><script type="text/javascript" src="/main.js"></script></ body> </html> browser Server Side Rendering
  77. 77. Buy 86 import React from 'react' import { renderStylesToString } from 'emotion-server' import { renderToString } from 'react-dom/server import App from './App' const html = renderStylesToString(renderToString(<App />)) <!DOCTYPE html> <html lang="en"> <body><div id="root"><main data-reactroot=""><div><style data-emotion- css="66u5jz">.css-66u5jz{padding:1em;}</style><input class="css-66u5jz e1c3ej80"/><style data-emotion-css="186egwm">.css-186egwm{padding:2em;}</style><input class="css-186egwm e1c3ej81"/></div></main></div> <script type="text/javascript" src="/runtime.js"></script><script type="text/javascript" src="/vendors~main.js"></script><script type="text/javascript" src="/main.js"></script></ body> </html> browser Server Side Rendering
  78. 78. 87 Right To Left Support CSS in JS
  79. 79. CSS & i18n Right to Left 88 import rtlCSSJS from 'rtl-css-js' const styles = { marginLeft: '50px', borderLeft: '10px solid black', background: 'linear-gradient(to left, pink, orange)' } const rtl = rtlCSSJS(styles) console.log(JSON.stringify(rtl, null, ' ')) > { "marginRight": "2em", "borderRight": "10px solid black", "background": "linear-gradient(to right, pink, orange)" }
  80. 80. CSS & i18n Right to Left 89 import rtlCSSJS from 'rtl-css-js' const styles = { marginLeft: '50px', borderLeft: '10px solid black', background: 'linear-gradient(to left, pink, orange)' } const rtl = rtlCSSJS(styles) console.log(JSON.stringify(rtl, null, ' ')) > { "marginRight": "2em", "borderRight": "10px solid black", "background": "linear-gradient(to right, pink, orange)" }
  81. 81. Themes
  82. 82. creating Themes 91 import glamorous, { ThemeProvider } from 'glamorous' const dark = { color: ‘pink’, background: ‘black’ } const light = { color: ‘black’, background: ‘gray’ } const Box = glamorous.div(({ theme }) => ({ color: theme.color, background: theme.background; }))
  83. 83. creating Themes 92 import glamorous, { ThemeProvider } from 'glamorous' const dark = { color: ‘pink’, background: ‘black’ } const light = { color: ‘black’, background: ‘gray’ } const Box = glamorous.div(({ theme }) => ({ color: theme.color, background: theme.background; })) export default class App extends Component { render () { return( <ThemeProvider theme={ dark }> <Box>Theme color</Box> </ThemeProvider> ) } }
  84. 84. creating Themes 93 import glamorous, { ThemeProvider } from 'glamorous' const dark = { color: ‘pink’, background: ‘black’ } const light = { color: ‘black’, background: ‘gray’ } const Box = glamorous.div(({ theme }) => ({ color: theme.color, background: theme.background; })) export default class App extends Component { render () { return( <ThemeProvider theme={ dark }> <Box>Theme color</Box> </ThemeProvider> ) } } Theme color
  85. 85. creating Themes 94 import glamorous, { ThemeProvider } from 'glamorous' const dark = { color: ‘pink’, background: ‘black’ } const light = { color: ‘black’, background: ‘gray’ } const Box = glamorous.div(({ theme }) => ({ color: theme.color, background: theme.background; })) export default class App extends Component { render () { return( <ThemeProvider theme={ light }> <Box>Theme color</Box> </ThemeProvider> ) } } Theme color
  86. 86. React Native
  87. 87. Kent C. Dodds @kentcdodds Mark Dalgleish @markdalgleish Oleg Isonen @oleg008 Michele Bertoli @MicheleBertoli Tom Raviv @RavivTom Bruce Lawson @brucel Sunil Pai @threepointone Sultan Tarimo @thysultan Kye Hohenberger @tkh44 Patrick Arminio @patrick91 Phil Pluckthun @_philpl Max Stoiber @mxstbr Glen Maddern @glenmaddern Superpowers CSS in JS LeadersFrameworks Styled Components Emotion Glamorous Styled System Glamor React CSS Modules Automation Shareable Adaptable Scaleable Maintainable Joe Seifi @joeseifi http://seifi.org https://github.com/joeshub/css-in-react Christopher Chedeau @vjeux DeCSS

×