Styled Components
Quoting from the Styled Components Docs:
styled-components is the result of wondering how we could enhance CSS for styling React component systems. By focusing on a single use case we managed to optimize the experience for developers as well as the output for end users
Styled Components Docs
We begin…
# Spin the docker project down
docker-compose -f docker-compose.yml -f docker-compose-dev.yml down
# or
make dev-down
# Install npm dependencies
cd frontend
npm install gatsby-plugin-styled-components styled-components babel-plugin-styled-components
Add the following to the gatsby-config.js file:
// frontend/gatsby-config.js
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.com/docs/gatsby-config/
*/
module.exports = {
siteMetadata: {
title: `Gatsby Todo App`,
description: `A fabulous description of our Todo app here...`,
author: `Ron Leeson`,
},
plugins: [
{
resolve: `gatsby-plugin-typography`,
options: {
pathToConfigModule: `src/utils/typography`,
},
},
`gatsby-plugin-styled-components`,
],
}
Rebuild frontend:
# cd to root of project
docker-compose build frontend
# reboot app
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -d
# or
make dev
The whole point of styled-components is to isolate a single css class from other components eliminating the problem of selector name collisions but it would useful to be able to define styles that can be applied globally. For that we use createGlobalStyle.
Setup Global Styles
We are going to us createGlobalStyle in our layout.js component which will allows us to share our styles globally throughout the site.
Start by editing our layout.js file:
// frontend/src/components/layout.js
import React from "react"
import Header from "./header"
import styled from "styled-components"
import { createGlobalStyle } from "styled-components"
const GlobalStyle = createGlobalStyle`
div {
font-size: 1.8rem;
}
a {
color: teal;
}
`
const BodyWrapper = styled.div`
padding: 2.0rem;
`
export default function Layout({ children }) {
return (
<React.Fragment>
<GlobalStyle />
<Header />
<BodyWrapper>{children}</BodyWrapper>
</React.Fragment>
)
}
What did we do?
- We imported styled-components and createGlobalStyle from styled-components
- Using createGlobalStyle, define a base font size and the anchor color for the entire site and assign these style definitions to the GlobalStyle component.
- Define a BodyWrapper component adding padding to the entire site.
- Add our GlobalStyle component.
- Wrap {children} with our BodyWrapper component adding site wide padding.
Add Styles to Header
// frontend/src/components/header.js
import { Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import styled from "styled-components"
const HeaderWrapper = styled.div`
padding: 2.0rem;
display: flex;
flex-direction: row;
align-items = center;
justify-content: space-between;
background-color: rebeccapurple;
a {
color: white;
text-decoration: none;
}
`
const SiteTitle = styled.div`
font-family: Arial, Helvetica, sans-serif;
`
const HeaderH1 = styled.h1`
font-size: 2.6rem;
`
const MainMenuWrapper = styled.div`
padding: 1.0rem 0;
a {
padding: 0 1.0rem 0 1.0rem;
}
`
const StyledLink = styled(Link)`
color: white;
`
export const PureHeader = ({ data }) => (
<HeaderWrapper>
<SiteTitle>
<HeaderH1>
<Link
to="/"
>
{data.site.siteMetadata.title}
</Link>
</HeaderH1>
</SiteTitle>
<MainMenuWrapper>
<Link
to="#"
>
Link 1
</Link>
<Link
to="#"
>
Link 2
</Link>
<Link
to="#"
>
Link 3
</Link>
</MainMenuWrapper>
</HeaderWrapper>
)
export const Header = props => {
const data = useStaticQuery(graphql`
query {
site {
siteMetadata {
title
}
}
}
`)
return <PureHeader {...props} data={data}></PureHeader>
}
Header.propTypes = {
siteTitle: PropTypes.string,
}
Header.defaultProps = {
siteTitle: ``,
}
export default Header
If you hit http://localhost:8000 you should see something like this:

Next up in chapter 13: implement authentication for Gatsby.