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

You Got CSS in My JavaScript!

You Got CSS in My JavaScript!

Thanks to the popularity of React, mixing markup and behavior – once thought unfathomable – is now almost commonplace. So why not invite styling along to the party? Adding inline styles to your markup is a breeze.

“Inline styling?!” I hear you say?

I know, I was skeptical too. But for all the progress CSS has made over the past almost 20 years, it’s still broken and annoying enough we’ve invented whole ecosystems of tooling to... well, make it less broken and annoying.

As it turns out, putting your CSS in your JavaScript components makes a pretty big chunk of that badness just disappear. And the stuff we use our favorite pre- and postprocessors for, like variables, math, and loops? You get that for free.

Moving to a truly componentized front end not only saved our CSS sanity, it got our team shipping more features with fewer bugs faster – we just had to let go of some old habits and prejudices first.

This talk is from ATXSass on 26 May 2016.

Nick Piesco

May 26, 2016
Tweet

More Decks by Nick Piesco

Other Decks in Programming

Transcript

  1. • Global namespace • Dependencies • Eliminating dead code •

    Minification • Sharing constants • Non-deterministic resolution • Isolation Christopher Chedeau: Seven Problems with CSS at Scale https://speakerdeck.com/vjeux/react-css-in-js
  2. • Global namespace • Dependencies • Eliminating dead code •

    Minification • Sharing constants • Non-deterministic resolution • Isolation Christopher Chedeau: Seven Problems with CSS at Scale https://speakerdeck.com/vjeux/react-css-in-js
  3. You might forget to include a module on a page,

    and it might work by accident
  4. React • Uses JSX to render the ‘Virtual DOM’ •

    Virtual DOM gets diffed against Actual DOM, and only the changes get rendered https://facebook.github.io/react/
  5. export default class myAwesomeButton { render () { return (

    <button type='button' className='my-awesome-button'> <span className='my-awesome-button-text'> Click me! </span> <button> ); } } myAwesomeButton.js
  6. export default class myAwesomeButton { render () { return (

    <button type='button' className='my-awesome-button'> <span className='my-awesome-button-text'> Click me! </span> <button> ); } } import MyAwesomeButton from 'path/to/myAwesomeButton'; export default class someOtherComponent { render () { return ( <div> Whatever you do, don’t click this button. <MyAwesomeButton /> </div> ); } } myAwesomeButton.js someOtherComponent.js
  7. So we have behaviour and content in the same place...

    ...what about styles? ...what about inline styles?
  8. WAT

  9. export default class myAwesomeButton { render () { return (

    <button type='button' style={backgroundColor: 'rebeccapurple', border: 0, borderRadius: 3, padding: <span style={color: 'white', fontSize: 24, fontWeight: 'bold', textShadow: '1px 1px 0 rgba(0, 0, 0 Click me! </span> </button> ); } } myAwesomeButton.js
  10. export default class myAwesomeButton { render () { return (

    <button type='button' style={backgroundColor: 'rebeccapurple', border: 0, borderRadius: 3, padding: <span style={color: 'white', fontSize: 24, fontWeight: 'bold', textShadow: '1px 1px 0 rgba(0, 0, 0 Click me! </span> </button> ); } } myAwesomeButton.js
  11. let styles = { button: { backgroundColor: 'rebeccapurple', padding: 10

    }, buttonText: { fontSize: 24, fontWeight: 'bold' } }; myAwesomeButton.js
  12. let styles = { button: { backgroundColor: 'rebeccapurple', padding: 10

    }, buttonText: { fontSize: 24, fontWeight: 'bold' } }; export default class myAwesomeButton { render () { return ( <button type='button' style={styles.button}> <span style={styles.buttonText}> Click me! </span> </button> ); } } myAwesomeButton.js
  13. • Pseudoelements (:before, :after) • Pseudoclasses (:hover, :focus, :active, etc.)

    • Media queries Things we don’t get with inline styles
  14. Pseudoclasses and media queries • :hover, :focus, and :active support

    via onMouseEnter, etc. • Media query support via window.matchMedia http://stack.formidable.com/radium/
  15. let styles = { button: { backgroundColor: 'rebeccapurple', padding: 5,

    ':hover': { backgroundColor: 'purple' }, '@media screen and (min-width: 600px)': { padding: 10 } }, buttonText: { fontSize: 24, fontWeight: 'bold' } };
  16. I

  17. export default { textColor: '#333', backgroundColor: 'white', buttonColor: 'rebeccapurple' };

    import myAwesomeButton from 'path/to/myAwesomeButton'; import colors from 'path/to/colors'; let styles = { button: { backgroundColor: colors.buttonColor } }; colors.js someOtherComponent.js
  18. let styles = { button: { backgroundColor: 'rebeccapurple' } };

    @Radium export default MyAwesomeButton { render () { return ( <button style={[styles.button, this.props.style]}> Click me! </button> ); } } myAwesomeButton.js
  19. return ( <MyAwesomeButton style={margin: 10}> Click me! </MyAwesomeButton> ); let

    styles = { button: { backgroundColor: 'rebeccapurple' } }; @Radium export default MyAwesomeButton { render () { return ( <button style={[styles.button, this.props.style]}> Click me! </button> ); } } myAwesomeButton.js someOtherComponent.js
  20. Math Comes for free with JS Use a library to

    handle colour operations https://github.com/Qix-/color
  21. I

  22. Thanks! @nickpiesco Reese’s commercial: tracy80sgirl/YouTube Scott Hall: wcwarchive/YouTube Sad Mark

    Zuckerberg: kippreport.com Emoji: Firefox OS/Wikimedia Commons Other Reese’s commercial: bionicdisco.com