Styling
Global Styles
Create a
global.css
stylesheet file to hold global styles and add the styles below.src\styles\global.css
You will need to create the styles directory.
body {
background-color: #f3f4f6;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
}We are using a sans serif system font stack in this example. For more information see CSS System Font Stack.
Import the stylesheet into your Layout component to apply the styles globally to the entire site.
src\components\layout.js
import React from "react"
import Footer from "./footer"
import Header from "./header"
+ import "../styles/global.css"
export default function Layout({ children }) {
return (
<div>
<Header />
{children}
<Footer />
</div>
)
}
Component Styles (Scoped)
Modularizing CSS to approach styling in a component-oriented way is rapidly becoming more popular. The benefits are that it is clear which CSS styles are applied to a given part of your site and those styles don't conflict with other styles in your site.
We are going to use CSS Modules
to modularize our CSS just as we have modularized our HTML
using React
components.
CSS Modules
(CSS-in-CSS)
CSS files in which all class names and animation names are scoped locally by default.
Create a CSS Module for the layout component.
src\components\layout.module.css
.container {
margin: 0 auto;
max-width: 1920px;
padding: 10px;
}Import your css module into the component and apply the container class.
src\components\layout.js
import React from "react"
import Footer from "./footer"
import Header from "./header"
+ import * as styles from "./layout.module.css"
export default function Layout({ children }) {
return (
- <div>
+ <div className={styles.container}>
<Header />
{children}
<Footer />
</div>
)
}Create a CSS Module for the Header component and add the following styles.
src\components\header.module.css
.header {
border-bottom: 1px solid #4b5563;
padding-top: 20px;
padding-bottom: 20px;
}
.link {
margin-left: 5px;
margin-right: 5px;
padding: 10px;
color: #4b5563;
text-decoration: none;
font-size: 1.25rem;
}
.link:hover {
color: #1f2937;
border: 1px solid #1f2937;
padding: 10px;
}
.first {
margin-left: 0px;
}Import the CSS Module and apply the styles.
src\components\header.js
import { Link } from 'gatsby';
import React from 'react';
import * as styles from './header.module.css';
export default function Header() {
return (
<header className={styles.header}>
<nav>
<Link className={`${styles.link} ${styles.first}`} to="/">
Home
</Link>
<Link className={styles.link} to="/about">
About
</Link>
</nav>
</header>
);
}Create a CSS Module for the Footer component and add the following styles.
src\components\footer.module.css
.nav {
margin-top: 30px;
}
.link {
margin-left: 5px;
margin-right: 5px;
color: #4b5563;
text-decoration: none;
}
.link:hover {
color: #f87171;
text-decoration: underline;
}
.first {
margin-left: 0px;
}Import the CSS Module and apply the styles.
src\components\footer.js
import React from 'react';
import * as styles from './footer.module.css';
export default function Footer() {
return (
<div>
<nav className={styles.nav}>
<a className={`${styles.link} ${styles.first}`} href="#">
Privacy
</a>
<a className={styles.link} href="#">
Terms
</a>
<a className={styles.link} href="#">
Careers
</a>
<span> © Acme Inc.</span>
</nav>
</div>
);
}
Using CSS Modules, how do I define more than one class name?
Emotion
In the next few sections we will install Emotion
and style our components using the two different approaches:
- styled components
- css prop
Install
Run this command at the command-promt or terminal in the
acme
directory.npm install gatsby-plugin-emotion @emotion/react @emotion/styled
Create a
gatsby-config.js
file at the root of the project directory (if one does not already exist).Add the plugin to enable emotion to the config file.
\gatsby-config.js
module.exports = {
plugins: [`gatsby-plugin-emotion`],
};Delete all the code in the
header.js
file (you can make a copy of it if you want) and replace it with the code using emotion styled components shown below.src\components\header.js
import { Link } from 'gatsby';
import React from 'react';
import styled from '@emotion/styled';
const NavLink = styled(Link)`
margin-left: 5px;
margin-right: 5px;
padding: 10px;
color: #4b5563;
text-decoration: none;
font-size: 1.25rem;
&:hover {
color: #1f2937;
border: 1px solid #1f2937;
padding: 10px;
}
`;
const StyledHeader = styled.header`
border-bottom: 1px solid #4b5563;
padding-top: 20px;
padding-bottom: 20px;
`;
export default function Header() {
return (
<StyledHeader>
<nav>
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
</nav>
</StyledHeader>
);
}Stop the development server and then run the command again.
// Ctrl+C
gatsby developReload the site and verify the styles are the same as before when we used CSS Modules.
Again, Delete all the code in the
header.js
file and replace it with the code using theEmotion
css prop
to style the component.src\components\header.js
import { Link } from 'gatsby';
import React from 'react';
import { css } from '@emotion/react';
const NavLink = (props) => (
<Link
css={{
marginLeft: '5px',
marginRight: '5px',
padding: '10px',
color: '#4b5563',
textDecoration: 'none',
fontSize: '1.25rem',
'&:hover': {
color: '#1f2937',
border: '1px solid #1f2937',
},
}}
{...props}
/>
);
export default function Header() {
return (
<header
css={{
paddingTop: '20px',
paddingBottom: '20px',
borderBottom: '1px solid #4b5563',
}}
>
<nav>
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
</nav>
</header>
);
}Again, verify the site styles are the same as in the last step.
Take a moment to compare the different syntaxes and determine what you like or do not like about each.