This is a collection of things I find my self copying over from other projects I have done. Handy to have it all in one place 📒

take me there

Responsive css grid

1<section
2 sx={{
3 margin: "2em auto",
4 display: "grid",
5 gridAutoRows: "auto",
6 gridTemplateColumns: "repeat(auto-fill, minmax(auto, 450px))",
7 gap: "1.5em",
8 justifyContent: "space-evenly",
9 width: "100%"
10 }}
11>
12 <div>Box 1</div>
13 <div>Box 2</div>
14 <div>Box 3</div>
15 <div>Box 4</div>
16</section>

Linear gradient background to text

1const GradientText = styled.p`
2 background-image: linear-gradient(
3 90deg,
4 rgba(127, 9, 9, 1) 0%,
5 rgba(255, 197, 0, 1) 12%,
6 rgba(238, 225, 23, 1) 24%
7 );
8 background-size: 100%;
9 background-repeat: repeat;
10 -webkit-background-clip: text;
11 -webkit-text-fill-color: transparent;
12 `
13
14 <GradientText>Check out my beautiful colours!</GradientText>

Check out my beautiful colours!


Global styles from Emotion

1import { Global, css } from "@emotion/core";
2
3<Global
4 styles={css`
5 * {
6 margin: 0;
7 padding: 0;
8 box-sizing: border-box;
9 }
10 body {
11 scroll-behavior: smooth;
12 overflow-y: scroll;
13 -webkit-overflow-scrolling: touch;
14 width: 100%;
15 overflow-x: hidden;
16 }
17 `}
18/>;

Svg Icon with Theme-ui color mode

1/** @jsx jsx */
2import { jsx, useColorMode } from "theme-ui";
3import Github from "../../assets/github.svg";
4
5export const GithubIcon = () => {
6 const [colorMode] = useColorMode();
7 return (
8 <Github
9 sx={{
10 width: "1.5em",
11 height: "1.5em",
12 fill: "accent",
13 marginBottom: "1em",
14 ":hover": {
15 fill: colorMode === "light" ? "#ffffff" : "#000000"
16 }
17 }}
18 />
19 );
20};

1/** @jsx jsx */
2import { jsx } from "theme-ui";
3import { Link } from "gatsby";
4
5const Nav = () => {
6 const { siteName } = useSiteMetadata();
7 return (
8 <nav
9 sx={{
10 display: "flex",
11 justifyContent: ["center", "space-between", "space-around"],
12 alignItems: "center",
13 width: "100%",
14 height: "100%",
15 position: "relative"
16 }}
17 >
18 <Link
19 sx={{
20 textDecoration: "none",
21 fontFamily: "heading",
22 fontSize: ["0.8em", "0.9em", "1em"],
23 color: "text",
24 paddingTop: ["1em", null, null],
25 letterSpacing: "text",
26 ":hover": {
27 color: "accent"
28 }
29 }}
30 to="/"
31 >
32 {siteName}
33 </Link>
34 <Link
35 sx={{
36 textDecoration: "none",
37 fontFamily: "heading",
38 fontSize: ["0.8em", "0.9em", "0.9em"],
39 color: "text",
40 paddingTop: ["1em", null, null],
41 letterSpacing: "text",
42 textTransform: "uppercase",
43 display: ["none", "block", "block"],
44 ":hover": {
45 color: "accent"
46 }
47 }}
48 to="/copy-paste"
49 >
50 Copy/Paste
51 </Link>
52 </nav>
53 );
54};

Theme-ui preset

1export default {
2 initialColorMode: "dark",
3 useCustomProperties: false,
4 fonts: {
5 body: "Jost",
6 heading: "Jost"
7 },
8 fontWeights: {
9 body: 300,
10 heading: 400,
11 bold: 700
12 },
13 lineHeights: {
14 body: "110%",
15 heading: 1.125,
16 tagline: "100px"
17 },
18 letterSpacing: {
19 body: "1px",
20 text: "5px"
21 },
22 colors: {
23 text: "#FFFfff",
24 background: "#121212",
25 primary: "#000010",
26 secondary: "#E7E7E9",
27 secondaryDarker: "#0F1218",
28 accent: "#DE3C4B",
29 modes: {
30 dark: {
31 text: "#000010",
32 background: "#E7E7E9",
33 primary: "#000010",
34 secondary: "#E7E7E9",
35 secondaryDarker: "#0F1218",
36 accent: "#DE3C4B"
37 }
38 }
39 },
40 breakpoints: ["40em", "56em", "64em"]
41};

Breakpoints areas for grid

1export const PhoneTemplateAreas = `
2 'nav nav nav nav'
3 'main main main main'
4 'footer footer footer footer'
5`;
6
7export const TabletTemplateAreas = `
8 'nav nav nav nav nav nav'
9 'main main main main main main'
10 'footer footer footer footer footer footer'
11`;
12
13export const DesktopTemplateAreas = `
14 '. nav nav nav nav nav nav .'
15 '. main main main main main main .'
16 '. footer footer footer footer footer footer .'
17`;

Set up Apollo with Gatsby and Netlify Functions

1// gatsby-browser.js && gatsby-ssr.js
2
3const React = require("react");
4const fetch = require("isomorphic-fetch");
5const {
6 ApolloProvider,
7 ApolloClient,
8 HttpLink,
9 InMemoryCache
10} = require("@apollo/client");
11
12const client = new ApolloClient({
13 cache: new InMemoryCache(),
14 link: new HttpLink({
15 uri: "https://my-app.netlify.app/.netlify/functions/graphql"
16 }),
17 fetch
18});
19
20export const wrapRootElement = ({ element }) => (
21 <ApolloProvider client={client}>{element}</ApolloProvider>
22);

Glitch text

1import React from "react";
2import styled from "@emotion/styled";
3
4const Container = styled.div`
5 position: relative;
6
7 &:hover {
8 &:before {
9 content: attr(data-text);
10 position: absolute;
11 top: 0;
12 left: 0;
13 width: 100%;
14 height: 100%;
15
16 left: 2px;
17 text-shadow: -1px 0 #de3c4b;
18 background: #121212;
19
20 overflow: hidden;
21 animation: noise-anim-2 5s infinite linear alternate-reverse;
22 }
23
24 &:after {
25 content: attr(data-text);
26 position: absolute;
27 top: 0;
28 left: 0;
29 width: 100%;
30 height: 100%;
31
32 left: -2px;
33 text-shadow: -1px 0 #de3c4b;
34 background: #121212;
35 overflow: hidden;
36 animation: noise-anim 2s infinite linear alternate-reverse;
37 }
38
39 @keyframes noise-anim {
40 0% {
41 clip-path: inset(100% 0 1% 0);
42 }
43 5% {
44 clip-path: inset(45% 0 41% 0);
45 }
46 10% {
47 clip-path: inset(8% 0 18% 0);
48 }
49 15% {
50 clip-path: inset(94% 0 7% 0);
51 }
52 20% {
53 clip-path: inset(23% 0 69% 0);
54 }
55 25% {
56 clip-path: inset(21% 0 28% 0);
57 }
58 30% {
59 clip-path: inset(92% 0 3% 0);
60 }
61 35% {
62 clip-path: inset(2% 0 35% 0);
63 }
64 40% {
65 clip-path: inset(80% 0 1% 0);
66 }
67 45% {
68 clip-path: inset(75% 0 9% 0);
69 }
70 50% {
71 clip-path: inset(37% 0 3% 0);
72 }
73 55% {
74 clip-path: inset(59% 0 3% 0);
75 }
76 60% {
77 clip-path: inset(26% 0 67% 0);
78 }
79 65% {
80 clip-path: inset(75% 0 19% 0);
81 }
82 70% {
83 clip-path: inset(84% 0 2% 0);
84 }
85 75% {
86 clip-path: inset(92% 0 6% 0);
87 }
88 80% {
89 clip-path: inset(10% 0 58% 0);
90 }
91 85% {
92 clip-path: inset(58% 0 23% 0);
93 }
94 90% {
95 clip-path: inset(20% 0 59% 0);
96 }
97 95% {
98 clip-path: inset(50% 0 32% 0);
99 }
100 100% {
101 clip-path: inset(69% 0 9% 0);
102 }
103 }
104 }
105`;
106
107export default ({ children }) => {
108 return <Container data-text={children}>{children}</Container>;
109};
110
111<h3>
112 <Glitch>Hover over me and watch me wobble (or click me on mobile)</Glitch>
113</h3>;

Hover over me and watch me wobble (or click me on mobile)


Load custom font in Gatsby

1// gatsby-ssr.js
2
3const React = require("react");
4export const onRenderBody = ({ setHeadComponents }) => {
5 setHeadComponents([
6 <link
7 rel="stylesheet"
8 href="https://indestructibletype.com/fonts/Jost.css"
9 type="text/css"
10 charset="utf-8"
11 />
12 ]);
13};
14
15// Can then be accessed like: font-family: Jost in your code

Base scripts for Gatsby project

1// package.json
2// Assumes you have prettier installed
3
4 "scripts": {
5 "dev": "gatsby develop",
6 "build": "gatsby build",
7 "clean": "gatsby clean",
8 "pretty-check": "prettier --check \"src/**/*.{js}\"",
9 "pretty": "prettier --write \"src/**/*js\"",
10 "sitemap": "gatsby build && gatsby serve",
11 "z": "gatsby clean && gatsby develop"
12 },
13 "prettier": {
14 "singleQuote": false,
15 "printWidth": 80,
16 "proseWrap": "always"
17 }

State management w/ context

1// Create a your context using a reducer to manage the state
2// Wrap your root component in the exported provider
3
4import React from 'react';
5
6export const StateContext = React.createContext(null);
7export const DispatchContext = React.createContext(null);
8
9const initialValues = {
10 name: '',
11 email: '',
12 location: '',
13 description: '',
14 website: '',
15}
16
17const reducer = (state, action) => {
18 const { type, payload } = action;
19 return { ...state, [type]: payload };
20};
21
22const Provider = ({ children }) => {
23 const [state, dispatch] = React.useReducer(reducer, initialValues);
24
25 return (
26 <DispatchContext.Provider value={dispatch}>
27 <StateContext.Provider value={state}>{children}</StateContext.Provider>
28 </DispatchContext.Provider>
29 );
30};
31
32export default Provider;
33
34// Wrap your root component in the exported provider.
35// This example uses Gatsby, in a normal React project wrap the App.js
36export const wrapRootElement = ({ element }) => (
37 <Provider>{element}</Provider>
38);
39
40
41// Usage
42
43 const dispatch = React.useContext(DispatchContext);
44 const state = React.useContext(StateContext);
45
46 // Update state =>
47 dispatch({ type: 'name', payload: e.target.value });
48
49 // Access state =>
50 <p>{state.name}</p>