css in react

41
CSS IN React

Upload: joe-seifi

Post on 16-Apr-2017

1.068 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: CSS in React

CSSIN

React

Page 2: CSS in React

Joe Sei�     @joesei�

Page 3: CSS in React

THE BADTHE GOODAND THE UGLY

Page 4: CSS in React

Familiarity - (CSS Level 1 released 19 years ago)Optimized Browser parsing and layoutJavaScript DOM APIInheritance structure - JSON likeMedia Queries - size and feature detectionPseudo Selectors - browser statesBasic math via calc()

CSS3 (THE GOOD)

Page 5: CSS in React

Flat - nested rules not supportedNeeds vendor pre�xesNo variables, no functionsSome dynamic updates still require JavaScript

CSS3 (THE BAD)

Page 6: CSS in React

Global namespace pollutionImportance, speci�city wars, & eventually !importantNondeterministic, depends on source orderEncapsulation - sharing code across components is scaryChanges & dead code elimination are manualMissing rules and syntax errors at runtime

CSS3 (THE UGLY)

Page 7: CSS in React

(like �ux for CSS)Object-Oriented CSS (OOCSS)Scalable and Modular Architecture for CSS (SMACSS)Block, Element, Modi�er (BEM)ATOMIC CSSSUIT CSS

METHODOLOGIES

Page 8: CSS in React

(like babel for CSS)SASSLESSStylusPostCSSAutopre�xer / cssnext

PRE/POST PROCESSORS

Page 9: CSS in React

a like buttonEXAMPLE:

Page 10: CSS in React

HTML<button class="btn btn‐primary">   Like <span class="badge">9</span> </button> 

Page 11: CSS in React

OR

Page 12: CSS in React

JSX & REACTconst LikeButton = ({ likes }) => {   return (     <button className="btn btn‐primary">       Like <span className="badge">{likes}</span>     </button>   ) } 

Page 13: CSS in React

DOM API

1. const LikeButton = ({ likes }) => { 2. return ( 3. <button className="btn btn-primary"> 4. Like <span className="badge">{likes}</span> 5. </button> 6. ) 7. } 8.

Page 14: CSS in React

AND

Page 15: CSS in React

CSS3.btn { 

  display: inline‐block; 

  border: 0; 

  padding: 6px 12px; 

.btn.btn‐primary { 

  color: #fff; 

  background‐color: #f74A27; 

.btn.btn‐primary:hover { 

  background‐color: #ff7857; 

.btn.btn‐primary > .badge { 

  color: #f74A27; 

  background‐color: #fff; 

.btn > .badge { 

  display: inline‐block; 

  border‐radius: 10px; 

  padding: 3px 6px; 

  

SASS.btn { 

  display: inline‐block; 

  border: 0; 

  padding: 6px 12px; 

  &.btn‐primary { 

    color: $text‐color; 

    background‐color: $button‐color; 

    &:hover { 

      background‐color: $button‐color‐hover; 

    } 

    .badge { 

      color: $button‐color; 

      background‐color: $text‐color; 

    } 

  } 

   

  .badge { 

    display: inline‐block; 

    border‐radius: 10px; 

    padding: 3px 6px; 

  } 

Page 16: CSS in React

RESULTLike  9

Page 17: CSS in React

NOW LET'S TRY THE SAMEWITH INLINE STYLES

in React

Page 18: CSS in React

JSONconst styles = { 

  'btn': { 

    'display': 'inline‐block', 

    'border': '0', 

    'padding': '6px 12px' 

  }, 

  'btn_primary': { 

    'color': '#fff', 

    'backgroundColor': '#f74A27' 

  }, 

  'btn_primary_hover': { 

    'backgroundColor': '#ff7857' 

  }, 

  'btn_primary__badge': { 

    'color': '#f74A27', 

    'backgroundColor': '#fff' 

  } 

  'btn__badge': { 

    'display': 'inline‐block', 

    'borderRadius': '10px', 

    'padding': '3px 6px' 

  } 

REACTimport React, { Component } from 'react' 

import { styles } from './styles' 

export const LikeButton = ({ likes }) => { 

  return ( 

    <button style={{ 

      ...styles.btn, 

      ...styles.btn_primary 

      }}> 

      Like 

      <span 

        style={{ 

        ...styles.btn__badge, 

        ...styles.btn_primary__badge 

        }}> 

        {likes} 

      </span> 

    </button> 

  ) 

  

Page 19: CSS in React

CSS IN JAVASCRIPT

1. const styles = { 2. 'btn': { 3. 'display': 'inline-block', 4. 'border': '0', 5. 'padding': '6px 12px' 6. }, 7. 8. 'btn_primary': { 9. 'color': '#fff', 10. 'backgroundColor': '#f74A27' 11. }, 12. 'btn_primary_hover': { 13. 'backgroundColor': '#ff7857' 14. },

Page 20: CSS in React

14. },

IN YOUR COMPONENT

1. import React, { Component } from 'react' 2. 3. import { styles } from './styles' 4. 5. export const LikeButton = ({ likes }) => { 6. return ( 7. <button style={{ 8. ...styles.btn, 9. ...styles.btn_primary 10. }}> 11. Like 12. <span 13. style={{ 14. ...styles.btn__badge,

Page 21: CSS in React

14. ...styles.btn__badge,

RESULT WITH JSONLike  9

Page 22: CSS in React

No pseudo selectors :hover :before etc.No media queries @media viewport etc.No rule nestingNo auto pre�xingNo CSS extractionFOUC

ISSUES WITH USING THE PLAIN

JSON object

Page 23: CSS in React

Radiumreact-css-modulesstyled-componentsaphrodite, jss, cxs, csjs, glamor, so many more

FRAMEWORKS FOR

CSS in JS

Page 24: CSS in React

RADIUMexport const styles = { 

  btn: { 

    display: 'inline‐block', 

    border: '0', 

    padding: '6px 12px', 

    btn_primary: { 

      color: '#fff', 

      backgroundColor: '#f74A27', 

      ':hover': { 

        backgroundColor: '#ff7857' 

      }, 

      badge: { 

        color: '#f74A27', 

        backgroundColor: '#fff' 

      } 

    } 

    badge: { 

      display: 'inline‐block', 

      borderRadius: '10px', 

      padding: '3px 6px' 

    } 

  } 

REACTimport React, { Component } from 'react' 

import Radium from 'radium' 

import { styles } from './styles' 

@Radium 

class LikeButton extends Component { 

  render () { 

    const { likes } = this.props 

    return ( 

      <button style={[ 

        styles.btn, 

        styles.btn.btn_primary 

      ]}> 

        Like <span style={[ 

          styles.btn.badge, 

          styles.btn.btn_primary.badge 

        ]}>{likes}</span> 

      </button> 

    ) 

  } 

export default LikeButton 

  

Page 25: CSS in React

RADIUM STYLE SYNTAX

1. export const styles = { 2. btn: { 3. display: 'inline-block', 4. border: '0', 5. padding: '6px 12px', 6. 7. btn_primary: { 8. color: '#fff', 9. backgroundColor: '#f74A27', 10. 11. ':hover': { 12. backgroundColor: '#ff7857' 13. }, 14.

Page 26: CSS in React

14.

RADIUM REACT SYNTAX

1. import React, { Component } from 'react' 2. import Radium from 'radium' 3. import { styles } from './styles' 4. 5. @Radium 6. class LikeButton extends Component { 7. render () { 8. const { likes } = this.props 9. return ( 10. <button style={[ 11. styles.btn, 12. styles.btn.btn_primary 13. ]}> 14. Like <span style={[

Page 27: CSS in React

14. Like <span style={[

Wraps your function or component with @decoratorsCreates a class to manage state for :hover :active :focusRadium.getState(this.state, 'btnPrimary', ':hover')

Style similar child elements with .map()matchMedia for media queries - IE poly�ll, server-side?Styles are inline, extract into CSS for production?

RADIUM NOTES

Page 28: CSS in React

No globals (with caveats)Built in dead code elimination, only used componentsPresentation logic is in your view, �nd and editState, constantsComposition, loops, computationDistribute via import and exportDynamic styling, app & DOM state e.g. data attributesSome :pseudo selectors re-implemented in JavaScriptFor example :last-child becomes i === arr.length - 1

INLINE STYLES (THE GOOD)

Page 29: CSS in React

No ::after ::before ::selection

Media queries have to use window.matchMedia()

Autopre�xing display: -webkit-flex; display: flex;

Animations via @keyframes re-implemented in JSHighest priority before !important No Speci�city CascadingPerformanceDebugging in devtools is a painDuplicate markup for similar elements

INLINE STYLES (THE BAD)

Page 30: CSS in React

CSS MODULES

Page 31: CSS in React

Based on Interoperable CSS - loadable, linkable CSSWorks with SASS, PostCSS etc.Broken CSS = compile errorUsing an unde�ned CSS Module = no warning

REACT-CSS-MODULES

Page 32: CSS in React

SASS@import "variables.scss"; 

.btn { 

  display: inline‐block; 

  border: 0; 

  padding: 6px 12px; 

  &.btn‐primary { 

    color: $text‐color; 

    background‐color: $button‐color; 

    &:hover { 

      background‐color: $button‐color‐hover; 

    } 

    .badge { 

      color: $button‐color; 

      background‐color: $text‐color; 

    } 

  } 

  .badge { 

    display: inline‐block; 

    border‐radius: 10px; 

    padding: 3px 6px; 

  } 

REACTimport React, { Component } from 'react' 

import CSSModules from 'react‐css‐modules' 

import styles from '../styles/likebutton.scss' 

@CSSModules(styles, {allowMultiple: true}) 

class LikeButton extends Component { 

  render () { 

    const { likes } = this.props 

    return ( 

      <button styleName="btn btn‐primary"> 

        Like <span styleName="badge">{likes}</span> 

      </button> 

    ) 

  } 

export default LikeButton 

  

Page 33: CSS in React

REACT-CSS-MODULES SYNTAX

1. import React, { Component } from 'react' 2. import CSSModules from 'react-css-modules' 3. import styles from '../styles/likebutton.scss' 4. 5. @CSSModules(styles, {allowMultiple: true}) 6. class LikeButton extends Component { 7. render () { 8. const { likes } = this.props 9. return ( 10. <button styleName="btn btn-primary"> 11. Like <span styleName="badge">{likes}</span> 12. </button> 13. ) 14. }

Page 34: CSS in React

14. }

styles object or this.props.styles[yourClasslassName]Con�gure your component classnames via localIdentName

Webpack CSS loader [path]___[name]__[local]___[hash:base64:5]

Generated classname styles-___likebutton__btn-primary___HYx7V

No overruling, intentionally nor unintentionallyComposition composes: parentClass same as @extend in SassOthers from ICSS :global :export :import

Use extract text plugin in production

REACT-CSS-MODULES NOTES

Page 35: CSS in React

STYLED COMPONENTS

Page 36: CSS in React

STYLEDimport styled from 'styled‐components' 

const StyledLikeButton = styled.button` 

  display: inline‐block; 

  border: 0; 

  padding: 6px 12px, 

  &.btn‐primary { 

    color: #fff; 

    background‐color: #f74A27; 

    &:hover { 

      background‐color: #ff7857; 

    } 

    .badge { 

      color: #f74A27; 

      background‐color: ${THEME.bgColor}; 

    } 

  } 

  .badge { 

    display: inline‐block; 

    border‐radius: 10px; 

    padding: 3px 6px; 

  } 

export default StyledLikeButton 

REACTimport React, { Component } from 'react' 

import StyledLikeButton from './StyledLikeButton' 

class LikeButton extends Component { 

  render () { 

    const { likes } = this.props 

    return ( 

      <StyledLikeButton className="btn‐primary"> 

        Like <span className="badge">{likes}</span> 

      </StyledLikeButton> 

    ) 

  } 

export default LikeButton 

  

Page 37: CSS in React

STYLED COMPONENTS SYNTAX

1. import styled from 'styled-components' 2. 3. const StyledLikeButton = styled.button` 4. display: inline-block; 5. border: 0; 6. padding: 6px 12px, 7. &.btn-primary { 8. color: #fff; 9. background-color: #f74A27; 10. &:hover { 11. background-color: #ff7857; 12. } 13. .badge { 14. color: #f74A27;

Page 38: CSS in React

14. color: #f74A27;

STYLED COMPONENTS USAGE

1. import React, { Component } from 'react' 2. import StyledLikeButton from './StyledLikeButton' 3. 4. class LikeButton extends Component { 5. 6. render () { 7. const { likes } = this.props 8. return ( 9. <StyledLikeButton className="btn-primary"> 10. Like <span className="badge">{likes}</span> 11. </StyledLikeButton> 12. ) 13. } 14.

Page 39: CSS in React

14.

Autopre�xing included for freeWrite plain CSS, no weird poly�lls neededGenerated classnames are namespaced btn-primary gjkSC

Injects style tags into the document headSupports server-side rendering, but not extract text pluginkeyframes helper keeps your rules local to your componentTheming is built in

STYLED COMPONENTS NOTES

Page 40: CSS in React

Web Components and Shadow DOMcssnextCSS4¿¡ !?

WHAT'S NEXT

Page 41: CSS in React

View examples on Github

THANK YOU!