z!gMOO

#3: Please push my buttons

December 29, 2022

I highly recommend checking out Josh Comeau's CSS button tutorial, which does a great job explaining how to craft snazzy buttons. After an afternoon of tinkering on my end, I was able to build some handy buttons for this site's nav. I also made buttons that link to the Discord and wiki, but they're not available on the public website yet. 😇

I approached the task by creating a base button component and style that looks like this:

components/Button.jsx
components/Button.module.scss
devlog/3.mdx
Copy

import * as React from "react"
import * as styles from "./Button.module.scss"
export interface ButtonProps {
children: React.ReactNode
onClick?: () => void
bgColor?: string
active?: boolean
}
export const Button: React.FC<ButtonProps> = ({
children,
onClick,
bgColor = "white",
active = false,
}) => {
return (
<button
className={`${styles.pushable} ${active ? styles.active : ""}`}
onClick={onClick}
>
<span className={styles.shadow} />
<span
className={styles.edge}
style={bgColor ? { backgroundColor: `var(--${bgColor}` } : {}}
/>
<span
className={styles.front}
style={bgColor ? { backgroundColor: `var(--${bgColor})` } : {}}
>
{children}
</span>
</button>
)
}

Out of the box, the button can be configured to use any CSS variable color as an overlay and can handle an onClick function. For example, here's a button that increments a counter and changes its own color when clicked:

components/RainbowButton.jsx
devlog/3.mdx
Copy

import { Button } from "../Button"
import { useState } from "react"
export const RainbowButton = () => {
const [count, setCount] = React.useState(0)
const colors = [
"red",
"orange",
"yellow",
"green",
"cyan",
"blue",
"purple",
"pink",
]
return (
<Button
bgColor={colors[count % colors.length]}
onClick={() => setCount(count + 1)}
>
Clicked {count} times!
</Button>
)
}

The color names just work because they're already in :root as CSS variables, but in the future I want to make this more robust. In the process of composing this post, I also made a few tweaks and removed some unhelpful code. It was helpful to practice using the button different ways directly on the blog post since the site uses MDX.