Welcome to my third and final blog in my styling mini-series. Today I'll be going over the youngest library I've worked with, initially released in 2022, Chakra UI. For this showcase, I'll be using Chakra v2.10.1 with React v18.3.1 in Node v22.
Why Choose Chakra?
You may be wondering, "What's Chakra's selling points?". Well despite being a very young library, Chakra has exploded in popularity. This means you'll have comparable support to some bigger, more established libraries like Material UI. Arguably my favorite aspects of Chakra would be its built in dark and light mode support and how accessible it is out the box. And lastly, Chakra UI has a keen focus on keeping its components customizable to fit your specific needs.
Installation
Chakra is easy to set up and get running. You'll first grab the necessary packages: with npm - npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion
or with yarn - yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
. After installing, you have to set up the ChakraProvider at the root of your application, which will look like this a majority of the time:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ChakraProvider } from '@chakra-ui/react';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ChakraProvider>
<App />
</ChakraProvider>
);
Themes and Customization
Themes allow developers to define a set of design standards that can be applied consistently across an application. Chakra UI comes with built-in theming capabilities that let devs customize the look and feel of their projects.
Applying these themes are as simple as slightly modifying our example from above to include a custom theme:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ChakraProvider } from '@chakra-ui/react';
import customTheme from './Theme';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ChakraProvider theme={customTheme}>
<App />
</ChakraProvider>
);
In a separate file, in this case Theme, you can set your own theming rules to override Chakra's defaults, and then you just pass it as a prop to the ChakraProvider.
Colors
Chakra uses a unique approach to colors, in the form of palettes. This means that their default colors have ranges, from 50 - 900, where the higher you go, the darker shades you have. Their default theme was inspired by Tailwind CSS. Be sure to check out the color spreads in the docs.
Typography
Your theme allows customization for font styles, sizes, and weights to maintain a consistent typography throughout your app. You can also customize headings, and more general body text.
Spacing
Chakra UI enables you to control the spacing between elements. Margins, paddings, and gaps can all be configured within the theme.
Breakpoints
Breakpoints in Chakra allow developers to build responsive designs that look good on any screen size. You can define your own via theming, or use the default Chakra values to create a responsive grid system.
Throwing these together you can have a simple theme that may look like this:
import { extendTheme } from '@chakra-ui/react';
// Define a custom color palette
const colors = {
brand: {
50: '#ffe5f7',
100: '#ffb3e0',
200: '#ff80c9',
300: '#ff4db1',
400: '#ff1a99',
500: '#e60080',
600: '#b30066',
700: '#80004d',
800: '#4d0033',
900: '#1a001a',
},
};
// Define custom typography settings
const typography = {
fonts: {
heading: `'Poppins', sans-serif`, // Custom font for headings
body: `'Roboto', sans-serif`, // Custom font for body text
},
fontSizes: {
sm: '12px',
md: '16px',
lg: '20px',
xl: '24px',
},
fontWeights: {
normal: 400,
bold: 700,
},
};
// Define spacing scale
const space = {
px: '1px',
1: '4px',
2: '8px',
3: '12px',
4: '16px',
5: '20px',
6: '24px',
8: '32px',
10: '40px',
12: '48px',
16: '64px',
20: '80px',
24: '96px',
};
// Extend the default Chakra theme
const customTheme = extendTheme({
colors,
fonts: typography.fonts,
fontSizes: typography.fontSizes,
fontWeights: typography.fontWeights,
space,
});
export default customTheme;
Light/Dark Mode
Light and dark mode has never been easier! Chakra has built in functionality for light and dark mode toggles through their useColorMode and useColorModeValue React hooks.
import { useColorMode } from '@chakra-ui/react';
function Example() {
const { colorMode, toggleColorMode } = useColorMode();
return (
<header>
<Button onClick={toggleColorMode}>
Toggle {colorMode === 'light' ? 'Dark' : 'Light'}
</Button>
</header>
)
}
And just like that, you have a fully functional button to toggle between light and dark mode!
But what if you need to adjust some colors between light and dark mode? Chakra allows this by using useColorModeValue. Its signature looks like this const value = useColorModeValue(lightModeValue, darkModeValue)
.
import { useColorMode, useColorModeValue } from '@chakra-ui/react';
function StyleColorMode() {
const { toggleColorMode } = useColorMode()
const bg = useColorModeValue('red.500', 'red.200')
const color = useColorModeValue('white', 'gray.800')
return (
<>
<Box mb={4} bg={bg} color={color}>
This box's style will change based on the color mode.
</Box>
<Button size='sm' onClick={toggleColorMode}>
Toggle Mode
</Button>
</>
)
}
Here, the background of the box will be a darker shade of red in light mode and a lighter shade in dark mode, while the text will be white, and dark gray respectively.
Accessibility
Chakra UI has accessibility baked into its core, ensuring that your UI components are not just visually appealing but also usable by everyone.
Buttons
Buttons play a vital role in interactivity, and Chakra UI provides several features to ensure they are accessible:
Contrast: Chakra's default button colors are designed to meet accessibility standards for contrast ratios.
Focus States: Automatically include focus styles. This means when a user navigates using a keyboard (via the Tab key), the button receives a visible focus outline, ensuring that it’s clear which element is in focus.
ARIA Attributes: Buttons in Chakra UI are implemented with proper ARIA (Accessible Rich Internet Applications) roles. For instance, if a button has a custom behavior, you can easily add aria-label attributes to enhance screen reader accessibility.
Forms
Forms are crucial for user input, and Chakra UI makes them accessible by default.
Proper Labeling: Form controls like inputs, checkboxes, and radio buttons are designed to be accessible with automatic association between labels and form elements. Chakra's
<FormLabel>
component ensures that labels are correctly bound to the form controls, making it easier for screen readers to interpret them.Validation States: Ensure that error messages are appropriately connected to the form controls using aria-invalid and other ARIA attributes.
For example:
<FormControl isRequired>
<FormLabel htmlFor="email">Email Address</FormLabel>
<Input id="email" type="email" />
<FormHelperText>We'll never share your email.</FormHelperText>
</FormControl>
Here, the htmlFor
attribute binds the label to the input element, and the helper text offers guidance, all accessible by screen readers.
Modals
Chakra's modals are designed with accessibility in mind:
Focus Trapping: When a modal opens, focus trapping ensures that users can't tab out of the modal content unintentionally.
Keyboard Navigation: Modals are fully navigable with a keyboard. Pressing the Tab key moves focus through interactive elements (like buttons or links) within the modal. The Esc key can be used to close the modal.
Aria Labels and Roles: Modals come with built-in ARIA roles such as
aria-modal
to define the dialog role. You can also addaria-labelledby
andaria-describedby
attributes to describe the modal content to assistive technologies.
Conclusions
All in all, Chakra is a very fun and accessible component library to work with. With things like built in light/dark mode support and a very large lean into accessibility, Chakra can be described as THE modern component library, despite being so young. I would implore you to try out Chakra and see if you like it!
Top comments (0)