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

The Road to Styled Components & the Road Ahead

Glen Maddern
September 14, 2017

The Road to Styled Components & the Road Ahead

Presented at React Foo, Bangalore, 14/9/17

Glen Maddern

September 14, 2017
Tweet

More Decks by Glen Maddern

Other Decks in Technology

Transcript

  1. "

  2. • Scoped styles • Critical CSS • Smarter optimisations •

    Package management • Non-browser styling BENEFITS OF CSS-IN-JS https://medium.com/seek-blog/a-unified-styling-language-d0c208de2660 @markdalgleish
  3. https://speakerdeck.com/didoo/let-there-be-peace-on-css @areaweb Separation of Concerns Separation of Concerns (only, from

    a different point of view) JS CSS HTML BUTTON DATE PICKER MODAL LIST LIST-ITEM MEDIA
  4. @glenmaddern /* styles.css */ .Headline { padding: 4em; background: papayawhip;

    } .Headline_Text { font-size: 1.5em; text-align: center; color: palevioletred; } <!-- my_page.html --> <!-- ... --> <header class="Headline"> <h1 class="Headline_Text"> My Page Title </h1> </header> <!-- ... --> /* src/components/Headline.css */ .Headline { padding: 4em; background: papayawhip; } .Headline_Text { font-size: 1.5em; text-align: center; color: palevioletred; } /* src/components/Headline.js */ import './Headline.css' export default ({ text }) => ( <header className="Headline"> <h1 className="Headline_Text"> { text } </h1> </header> ) REACT & WEBPACK
  5. @glenmaddern /* src/components/Headline.css */ .Headline { padding: 4em; background: papayawhip;

    } .Headline_Text { font-size: 1.5em; text-align: center; color: palevioletred; } /* src/components/Headline.js */ import './Headline.css' export default ({ text }) => ( <header className="Headline"> <h1 className="Headline_Text"> { text } </h1> </header> ) /* src/components/Headline.js */ import styles from './Headline.css' export default ({ text }) => ( <header className={ styles.wrapper }> <h1 className={ styles.text }> { text } </h1> </header> ) /* src/components/Headline.module.css */ .wrapper { padding: 4em; background: papayawhip; } .text { font-size: 1.5em; text-align: center; color: palevioletred; } CSS MODULES
  6. @glenmaddern /* src/components/Headline.js */ import styled from 'styled-components' const Wrapper

    = styled.header` padding: 4em; background: papayawhip; `; const Text = styled.h1` font-size: 1.5em; text-align: center; color: palevioletred; `; export default ({ text }) => ( <Wrapper> <Text>{ text }</Text> </Wrapper> ) /* src/components/Headline.js */ import styles from './Headline.css' export default ({ text }) => ( <header className={ styles.wrapper }> <h1 className={ styles.text }> { text } </h1> </header> ) /* src/components/Headline.module.css */ .wrapper { padding: 4em; background: papayawhip; } .text { font-size: 1.5em; text-align: center; color: palevioletred; } STYLED COMPONENTS
  7. @glenmaddern /* EqualDivider.scss */ .EqualDivider { display: flex; margin: 0.5rem;

    padding: 1rem; background: papayawhip; > * { flex: 1; &:not(:first-child) { margin-left: 1rem; } } } .Box { padding: 0.25rem 0.5rem; background: palevioletred; } /* EqualDivider.sass */ .EqualDivider display: flex margin: 0.5rem padding: 1rem background: papayawhip > * flex: 1 &:not(:first-child) margin-left: 1rem .Box padding: 0.25rem 0.5rem background: palevioletred
  8. @glenmaddern /* EqualDivider.css.js */ const equalDivider = { display: 'flex',

    margin: '0.5rem', padding: '1rem', background: 'papayawhip', '> *': { flex: 1, '&:not(:first-child)': { marginLeft: '1rem' } } } const box = { padding: '0.25rem 0.5rem', background: 'palevioletred' } /* EqualDivider.js */ const EqualDivider = styled.div` display: flex; margin: 0.5rem; padding: 1rem; background: papayawhip; > * { flex: 1; &:not(:first-child) { margin-left: 1rem; } } ` const Box = styled.div` padding: 0.25rem 0.5rem; background: palevioletred; `
  9. @glenmaddern DESIGN GOALS #2 BRING PEOPLE ALONG INCREASE THE NUMBER

    OF PEOPLE WHO CAN GET VALUE FROM YOUR IDEA STRAIGHT AWAY
  10. @glenmaddern <Button>Option A</Button> <Button className="primary">Option B</Button> const Button = styled.button`

    font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; background: palevioletred; color: white; ${props => props.primary && css` background: white; color: palevioletred; `} ` <Button>Option A</Button> <Button primary>Option B</Button> const Button = styled.button` font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; background: palevioletred; color: white; &.primary { background: white; color: palevioletred; } `
  11. @glenmaddern const Button = styled.button` font-size: 1em; margin: 1em; padding:

    0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; background: palevioletred; color: white; ${props => props.primary && css` background: white; color: palevioletred; `} ` <Button>Option A</Button> <Button primary>Option B</Button> const vars = { primary: 'palevioletred', secondary: 'white' } const Button = styled.button` font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; background: ${ vars.primary }; color: ${ vars.secondary }; ${props => props.primary && css` background: ${ vars.secondary }; color: ${ vars.primary }; `} `
  12. @glenmaddern import styled from 'styled-components/native' const Wrapper = styled.View` background-color:

    papayawhip; flex: 1; justify-content: center; align-items: center; ` const Title = styled.Text` font-size: 20px; text-align: center; margin: 10px; color: palevioletred; font-weight: bold; `
  13. @glenmaddern class StyledComponentsNative extends React.Component { render() { return (

    <Wrapper> <Title> Hello World, this is my first native styled component! </Title> </Wrapper> ) } }
  14. @glenmaddern STYLED COMPONENTS • 100% JavaScript • No Webpack/Babel changes

    needed • babel-plugin-styled-components • Improves dev tooling • Makes server-rendering deterministic • Better performance (v3 onwards)
  15. @glenmaddern ✅ CODIFY BEST PRACTICES ✅ BRING PEOPLE ALONG ✅

    FOLLOW THE PLATFORM ✅ ZERO CONFIGURATION
  16. STYLED COMPONENTS • CSS-in-JS for React (and Preact) • ~400K

    downloads/month • ~10K stars on GitHub • 142 contributors but core team: @_philpl @mxstbr @glenmaddern
  17. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,

    user-scalable=yes, initial-scale=1.0"> <title>pithy.af · Kurt Vonnegut Jr. · Slaughterhouse-Five (1969)</title> <link rel="shortcut icon" href="favicon.ico"> <meta property="og:title" content="[pithy.af] A quote by Kurt Vonnegut Jr. from Slaughterhouse-Five (1969)"> <meta property="og:description" content="And I asked myself about the present..."> <meta property="og:image" content="http://pithy.af/authors/kurt-vonnegut-jr-5.png"> <link rel="stylesheet" href="reset.css"> <link rel="stylesheet" href="styles.css"> <script async src="https://use.typekit.net/oqw6kuv.js"></script> </head> <body class="sans-serif"> <nav class="Nav mb3"> <img src="logo.svg" alt="pithy.af logo" class="Logo"> <a href="#">About</a> <a href="#">Submit a quote</a> </nav> <main> <div class="Quote -main"> <div class="Quote_Inner"> <div class="Quote_Short"> <em>And I asked myself</em> about the present: how wide it was, how deep it was, how much was mine to keep. </div> <div class="Quote_Attribution">Kurt Vonnegut Jr.</div> <div class="Quote_Work">Slaughterhouse-Five (1969)</div> </div> </div> </main> </body> </html> CONTENT BROWSER METADATA RESOURCE REFERENCES SHARING METADATA
  18. @glenmaddern User Local machine SNAPSHOT RENDERING File Storage GET index.html

    *renders React code* GET bundle.js, logo.svg, etc. *boots up App* *renders static page* PUT index.html GET index.html BUILD & DEPLOY PRODUCTION
  19. @glenmaddern WEB PAGE WEB APP • Static HTML & CSS

    • Unobtrusive or no JavaScript • Meta tags designed for SEO and social sharing • Simple build step if any • Performance-sensitive • Fully client-rendered • Built using a JS framework • No extraneous metadata • Complex, all-inclusive build & optimisation process • Development-speed- sensitive VS Sharing assets/knowledge difficult or impossible
  20. WEB PAGE WEB APP • Built with the same JS

    framework • Interactive components built the same way as static ones • Shared build process & optimisations • Real HTML & CSS served to all users • Components, assets, knowledge & workflow now shareable &
  21. @glenmaddern THE ROAD AHEAD: A UNIFIED UI LANGUAGE • It

    codifies best practices • It brings people along • It's expressive & powerful • It's universally usable