Tokens 🖌️
This page shows some of the design tokens used on this site. Specifically about the colors, I do not define color scales, but I do have some base colors from which I tweak to make custom components like buttons.
Surfaces
There are 6 surfaces ranging from 0 to 5 which denotes how elevated that surface
is. Since they do not need to be highly dynamic, they are defined in the
tailwind.config.js
file. Each surface ( bg-surface-n
) is made to be paired
with its shadow ( shadow-surface-n
).
Surface 1 is the default surface, which is a surface that lies flat on the page, which means it does not have a shadow.
Colors
Most colors used on this site is derived from the following base colors. Some hue rotation, saturation and lightness adjusting is done when needed to build a specific component.
As an example, consider the following buttons and the css used to build it.
export const LightButton = ({
variant = 'primary',
className,
...props
}: Props) => {
const base = css`
color: ${getHslaColor(variant, 1, { l: -12 })};
[data-theme='dark'] & {
color: ${getHslaColor(variant)};
}
background: ${getHslaColor(variant, 0.1)};
border-color: ${getHslaColor(variant)};
border-radius: 4rem;
&:hover,
&:focus {
background: ${getHslaColor(variant, 0.08)};
}
`;
return (
<button className={cn(base, 'px-4', 'py-2', className)} {...props} />
);
};
Other tokens
Other tokens such as text size, spacing, etc. are following tailwindcss
tokens.
Reasons for this approach
I initially started working on this site and fully rely on tailwindcss
for the
styling part. After some time, I started realizing that because I treat my site
as a personal playground to try various things, I tend to be very dynamic in
making styles. While I can definitely update tailwind configuration to
accommodate this use cases, there are problems with that approach.
- It's annoying to have to update
tailwind.config.js
everytime I need to do this - Using
tailwindcss
, we can support dark mode but not multiple themes at once; this is something I plan to do in the future. - The resulting
.css
is never codesplitted. This can result in big stylesheet as I add more different styles.
My current approach is to still rely on tailwindcss
classes for most basic
spacing and layout styles that aren't as dynamic as colors. For colors and other
things that might be more dynamic, I derive them on runtime from a set of css
variables.
Do note that this is most definitely not the best way to do things, but hey, software engineering is about making tradeoffs. This solution seems to work well enough for me, at least for now. 😄