CSS-in-JS is a styling technique where JavaScript is used to style our components. When the components are parsed, CSS is generated and attached to the DOM.
CSS-in-JS prevents style leaking that we saw with plain CSS and CSS naming conventions, and is an alternative to CSS pre-processors. It also allows you to encapsulate styling within a component, which is great for component libraries.
Styled components provide many benefits, like scoped styling (no more worrying about bleeding CSS specificity or rogue !importants
)
Copy npm i styled-components
Copy import styled from "styled-components";
const Button = styled.button`
padding: 8px 12px;
font-size: 1rem;
border-radius: 2px;
min-width: 100px;
cursor: pointer;
font-family: "Roboto Mono", monospace;
`;
const PrimaryButton = styled(Button)`
background-color: red;
border: none;
color: white;
`;
Inside of the utils/
folder create three new files: colors.js
, themes.js
, and typography.js
.
Inside colors.js
add your color palette. The color tokens will be an object containing the values in increments of 100 which will allow us to access them using the syntax blue[100]
.
Copy export const blue = {
100: "#3a36e0",
200: "#0804b8",
300: "#030086",
400: "#5f25a4",
500: "#050449"
};
export const green = {
100: "#529e66",
200: "#367b48",
300: "#276738"
};
export const yellow = {
100: "#e1c542",
200: "#cab23f",
300: "#b49e35"
};
export const red = {
100: "#d0454c",
200: "#b54248",
300: "#95353a"
};
export const neutral = {
100: "#ffffff",
200: "#f4f5f7",
300: "#e1e1e1",
400: "#737581",
500: "#4a4b53",
600: "#000000"
};
typography.js
Copy export const primaryFont = '"Roboto Mono", monospace';
Copy export const typeScale = {
header1: "1.8rem",
header2: "1.6rem",
header3: "1.4rem",
header4: "1.2rem",
header5: "1.1rem",
paragraph: "1rem",
helperText: "0.8rem",
copyrightText: "0.7rem"
};
themes.js
Copy import { blue, neutral } from "./colors";
import { primaryFont } from "./typography";
export const defaultTheme = {
primaryColor: blue[300],
primaryHoverColor: blue[200],
primaryActiveColor: blue[100],
textColorOnPrimary: neutral[100],
textColor: neutral[600],
textColorInverted: neutral[100],
primaryFont: primaryFont
};
Add an index.js
file inside of utils/
which exports each utility.
Copy export * from "./colors";
export * from "./typography";
export * from "./themes";
This will allow us to import utilities from theutils
folder instead of the individual folder.
Copy import { defaultTheme } from "../utils";
// We don't need import { defaultTheme } from "../utils/themes";
Buttons.js
with our theme:
Copy import styled from "styled-components";
import { defaultTheme } from "../utils";
import { typeScale } from "../utils";
const Button = styled.button`
padding: 8px 12px;
font-size: ${typeScale.paragraph};
border-radius: 2px;
min-width: 100px;
cursor: pointer;
font-family: ${defaultTheme.primaryFont};
`;
const PrimaryButton = styled(Button)`
background-color: ${defaultTheme.primaryColor};
color: ${defaultTheme.textColorOnPrimary};
border: 2px solid transparent;
`;
export const SecondaryButton = styled(Button)`
border: 2px solid ${defaultTheme.primaryColor};
color: ${defaultTheme.primaryColor};
`;
export const TertiaryButton = styled(Button)`
border: 2px solid transparent;
color: ${defaultTheme.primaryColor};
`;
export default PrimaryButton;