Design System Foundations Using Tailwind
The foundation part of the design system comprises all basic styling necessities for a project.
We will go through them one by one and create them using tailwind css.
We can either extend or completely reset the colors. Let's reset the colors. The brand Color of epicgames.com is
#007dfc . HSL is easy to understand. The brand color translates to
‘hsl(210, 100%, 49%)’ in HSL.
- Hue: 210
- Saturation: 100%
- Lightness: 49%
HSL is great for creating shades for a particular hue.
We can have the hue
210 and change the lightness to create the shades.
50: 'hsl(210, 100%, 97%)',
100: 'hsl(210, 100%, 91%)',
200: 'hsl(210, 100%, 80%)',
300: 'hsl(210, 100%, 70%)',
400: 'hsl(210, 100%, 60%)',
500: 'hsl(210, 100%, 49%)',
600: 'hsl(210, 100%, 39%)',
700: 'hsl(210, 100%, 28%)',
800: 'hsl(210, 100%, 16%)',
900: 'hsl(210, 100%, 10%)',
The range of lightness I came up with is purely using the eyes. We can simply divide them uniformly but I wanted the
primary-50 to be almost white and
primary-900 to be almost black.
It is gray. But “primarily” tinted!
The primary color is for cueing the user about the most important thing to notice on a page. But gray is the most used color in any application.
A plain gray won’t break the user experience but if we tint it with the primary color, it gives a good mood.
Using HSL format helps us easily come up with related colors with great precision.
Gray can be achieved by reducing the saturation to 0% at any hue. But we generate our gray like below to match our primary color.
50: 'hsl(210, 12%, 97%)',
100: 'hsl(210, 12%, 91%)',
200: 'hsl(210, 12%, 80%)',
300: 'hsl(210, 12%, 70%)',
400: 'hsl(210, 12%, 60%)',
500: 'hsl(210, 12%, 49%)',
600: 'hsl(210, 12%, 39%)',
700: 'hsl(210, 12%, 28%)',
800: 'hsl(210, 12%, 16%)',
900: 'hsl(210, 12%, 10%)',
How does our tinted
(12% saturated) look compared to the
GRAY-PLAIN (0% saturated)?
You can increase or decrease the
12% which I found to be a sweet spot to tint.
Imagine doing this in
HSL makes it simple to masterfully come up with colors.
Let's use the same technique to create two more colors.
hsl(0, 93%, 58%)
hsl(150, 100%, 40%)
That's it for the colors. We can revisit later if we want more colors or modify the shades as needed. This tailwind configuration we create here will be propagated throughout the project instantly.
- We have completely replaced the colors that come with tailwind with these four colors.
We reset the tailwind’s type scale with the below.
// Body copy
'xs': ['.75rem', '1rem'],
'sm': ['.875rem', '1rem'],
'base': ['1rem', '1.5rem'],
'lg': ['1.125rem', '1.5rem'], // Headings
'xl': ['1.5rem', '2rem'],
'2xl': ['2rem', '2.5rem'], // Display
'3xl': ['5rem', '6rem'],
'4xl': ['10rem', '10rem'],
We can not discuss font size without line-height. The second item in each array is line-height.
A thing to notice is, we try to achieve an
8px grid as much as possible. All the line heights above are divisible by 8 and hence they fit in 8px grids nicely.
This is how our type scale looks.
text-xsis mostly used for badges. If we go with full uppercase with relaxed letter spacing, an
xslooks good compared to
text-smis helpful for the text in product cards.
text-baseis the base size that applies by default. We picked
16pxas the base for this e-commerce product. But remember the body text you are currently reading is
21px(in desktop mode).
text-lgcan be used for callouts, descriptions, etc. This can be used as a heading too with enough font-weight using
text-4xlare used in rare situations where we need obnoxiously huge texts.
The text size does not have to dictate hierarchy. Our limited headings
text-2xl can be emphasized by providing a thicker font-weight.
The bigger the text is, the tighter the letter-spacing should be.
Line height can be fixed or relative. We have already given suitable line heights for each text size.
Relative line heights work like percentages. I reset the tailwind config to include only the relative line-heights.
'none': ' 1',
'tight': ' 1.25',
'snug': ' 1.375',
'normal': ' 1.5',
'relaxed': ' 1.625',
'loose': ' 2',
The smaller the text is the larger the line height should be.
Tailwind CSS comes with a good range of shadows with the classes
shadow-sm -> shadow-2xl. Let’s use them as it is.
The light source is assumed to be behind the top of the user’s head making the shadows fall below the object.
Making the default background color a shade darker will get de-emphasized automatically.
In dark mode, the shadows almost won't work. The difference in lightness between the foreground vs background gives a sense that the lighter items are closer to the user.
The lighter items look closer.
Also, notice how the darker card
shadow-inner looks like a punched-out hole even though the inner shadow is almost nonexistent.
In the text size section, we did a deliberate effort to make the line-heights divisible by
Spacing is another thing that we have to focus on making them adaptable to the
8px grid. But it is not very practical to have the smallest size as
8px. So, we include
0.125 (2px) and
.25 (4px) for a little nudge here and there. After that, they are all
I copied the necessary SVGs from hero icons. I exported them from an index.
Keeping a separate library instead of relying on a third-party library is debatable. But I believe any software product can do fine with a handful of icons.
- This way is slow when the developers need additional icons.
- Icons can become inconsistent if we start copying SVGs from multiple sources.
Tailwind comes with zIndex classes for values
0,10,20,30,40,and 50. I prefer having one value behind
So, let's extend zIndex to have
Flexbox and Grid
The utility classes tailwind provides for flexbox and grid are going to be responsible for our layout design throughout our application.
It is important to have small how-to-approach demos for layout designs. But currently, I leave this in the flexbox and grid page in our design system. We can develop this later if we want.
Let's add line clamp and aspect ratio as add-ons.
npm i @tailwindcss/aspect-ratio @tailwindcss/line-clamp// Import in tailwind.config.js
const lineClamp = require('@tailwindcss/line-clamp')
const aspectRatio = require('@tailwindcss/aspect-ratio')// Add this in module.exports.
plugins: [lineClamp, aspectRatio]
TailwindCSS JIT brings immense benefits to the developer experience. Have look at the official documentation for details.
mode: ‘jit’in the tailwind.config.js.
TAILWIND_MODE=watchin the start scripts.
"start": "TAILWIND_MODE=watch craco start",
"storybook": "TAILWIND_MODE=watch start-storybook -p 6006 -s public",
The config file
After all the work, taliwind.config.js will become like below.
We have created the foundation for our design system. Next up we will be creating base components like accordions, avatars, buttons etc.
Thank you. See you next time.