css in react
Post on 16-Apr-2017
1.059 Views
Preview:
TRANSCRIPT
CSSIN
React
THE BADTHE GOODAND THE UGLY
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)
Flat - nested rules not supportedNeeds vendor pre�xesNo variables, no functionsSome dynamic updates still require JavaScript
CSS3 (THE BAD)
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)
(like �ux for CSS)Object-Oriented CSS (OOCSS)Scalable and Modular Architecture for CSS (SMACSS)Block, Element, Modi�er (BEM)ATOMIC CSSSUIT CSS
METHODOLOGIES
(like babel for CSS)SASSLESSStylusPostCSSAutopre�xer / cssnext
PRE/POST PROCESSORS
a like buttonEXAMPLE:
HTML<button class="btn btn‐primary"> Like <span class="badge">9</span> </button>
OR
JSX & REACTconst LikeButton = ({ likes }) => { return ( <button className="btn btn‐primary"> Like <span className="badge">{likes}</span> </button> ) }
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.
AND
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;
}
}
RESULTLike 9
NOW LET'S TRY THE SAMEWITH INLINE STYLES
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>
)
}
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. },
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,
14. ...styles.btn__badge,
RESULT WITH JSONLike 9
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
Radiumreact-css-modulesstyled-componentsaphrodite, jss, cxs, csjs, glamor, so many more
FRAMEWORKS FOR
CSS in JS
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
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.
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={[
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
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)
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)
CSS MODULES
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
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
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. }
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
STYLED COMPONENTS
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
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;
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.
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
Web Components and Shadow DOMcssnextCSS4¿¡ !?
WHAT'S NEXT
top related