CSS in JS

Agenda

  • Why not Traditional CSS?
  • Starting with Styled Components
  • Codelab
    • lab-01 to lab-08

Problem with Traditional CSS

  1. Global Namespace
  2. Dead Code Elimination
  3. Minification
  4. Non deterministic resolution

 

Starting with styled components

import styled from 'styled-components'


const Wrapper = styled.div`
  background-color: rgb(218, 163, 87);
  font: normal 16px / normal Arial, sans-serif;
`

export default class App extends Component {
  render () {
    return (
      <Wrapper>
        <h1>CSS in JS</h1>
      </Wrapper>
    )
  }
}
npm install --save styled-components
import styled from 'styled-components'


const Wrapper = styled.div`
  background-color: rgb(218, 163, 87);
  font: normal 16px / normal Arial, sans-serif;
`

/* sc-component-id: sc-bdVaJa */

.gxkSFb{
    background-color:rgb(218,163,87);
    font:normal 16px / normal Arial,sans-serif;height:100vh;
}


<div class="sc-bdVaJa gxkSFb">
    <h1>CSS in JS</h1>
</div>
import styled from 'styled-components'


const Container = styled.div`
  align-items: center;
  display: flex;
  justify-content: center;
`
.gxkSFb{
    display:-webkit-box;
    display:-webkit-flex;
    display:-ms-flexbox;
    display:flex;
    -webkit-flex-direction:column;
    -ms-flex-direction:column;
    flex-direction:column;
    -webkit-align-items:center;
    -webkit-box-align:center;
    -ms-flex-align:center;
    align-items:center;
    -webkit-box-pack:center;
    -webkit-justify-content:center;
    -ms-flex-pack:center;
    justify-content:center;
}

pseudoelement, pseudoselector and nesting

const StyledButton = styled.button`
    background-color: blue;
    color: white;
    cursor: pointer;
    padding: 20px;
    font-size: 16px;

    & + & {
        background-color: gray;
    }

    &.otherButton{
        background-color: magenta;
    }

    &:hover {
        background-color: green;
        color: white;
    }

    &:active {
        background-color: red;
    }
`

Props in styles

const StyledButton = styled.button`
    background-color: ${ props => props.primary ? "blue" : props.secondary ? "green" : "red" };
    color: white;
    cursor: pointer;
    padding: 20px;
    font-size: 16px;
`


            <StyledButton> Normal </StyledButton>
            <StyledButton primary> Primary </StyledButton>
            <StyledButton secondary> Secondary </StyledButton>

Extend styles

const StyledCard = styled.div`
    background-color: #bbb;
    color: white;
    cursor: pointer;
    padding: 20px;
    font-size: 16px;
    margin: 20px;
`

const StyledCardLarge = styled(StyledCard)`
    padding: 30px;
    font-size: 22px;
`


            <StyledCard>Normal</StyledCard>
            <StyledCardLarge>Extended large card</StyledCardLarge>

Styling any component

import { Link } from "react-router-dom"



const StyledLink = styled(Link)`
  color: brown;
  padding: 15px;
  font-size: 18px;
  font-weight: bold;
  text-decoration: none;

  &:hover {
    color: red;
  }
`



            <StyledLink to="/button">Button</StyledLink>
            <StyledLink to="/card">Card</StyledLink>

Creating Helpers/Mixins

import { css } from "styled-components"

export const ELLIPSIS = (width=200) => 
    css`
        width: ${width}px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    `




const StyledDescription = styled.p`
    font-size: 14px;
    ${ELLIPSIS(200)}
`

    

<StyledDescription>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</StyledDescription>

Using with existing libraries, bootstrap

import 'bootstrap/dist/css/bootstrap.css'


const StyledAlert = styled.div.attrs({
    className: props => {
        console.log(props)
        const types = ['warning', 'info', 'danger', 'success']
        const type = types.find(item => props[item]) || 'info'
        return ` alert-${type}`
    }
})`
    border-radius: 10px;
    padding: 20px;
    & + & {
        margin-top: 15px;
    }
`


            <StyledAlert success>Success</StyledAlert>
            <StyledAlert danger>Danger</StyledAlert>
            <StyledAlert>Info</StyledAlert>
            <StyledAlert warning>Warning</StyledAlert>

Injecting Global Styles

import { createGlobalStyle } from 'styled-components'


const GlobalStyle = createGlobalStyle`
  body {
    background-color: rgb(218, 163, 87);
    margin: 0;
    padding: 0;
    font: normal 16px/normal Arial, sans-serif;
  }

  a {
    color: blue;
    text-decoration: none;

    &:hover {
      text-decoration: underline;
    } 
  }
`
         <BrowserRouter>
            <GlobalStyle />
            <Wrapper>
              {...}
            </Wrapper>
         </BrowserRouter>

Theming

import { createGlobalStyle, ThemeProvider } from 'styled-components'

const THEME = {
    dark: {
        bg: "black",
        color: "white"
    },
    light: {
        bg: "white",
        color: "black"
    }
}


const GlobalStyle = createGlobalStyle`
  body {
    background-color: ${props => props.theme.bg };
    color: ${props => props.theme.color };
  }
`

            <ThemeProvider theme={THEME.dark}>
                <React.Fragment>
                    <GlobalStyle />
                    <Wrapper>
                      {...}
                    </Wrapper>
                </React.Fragment>
            </ThemeProvider>
         

What Else!

  • Animation
  • Media Queries
  • Utilities
    • polished
    • grid-styled

CSS in JS

By Mukesh Yadav

CSS in JS

  • 544