Chakra UI (v2) - Troubleshooting Styling
Posted on Dec 28, 2023 in Blog Posts
At the time of writing, @chakra-ui/react
's version is 2.8.2
.
Overview
While working with Chakra UI , I've come across instances where styling did not behave as I expected. Here are a few tips for troubleshooting unexpected style behaviors in Chakra UI. In this post, I'll walk through the resources and process I use to find where to set a style in Chakra UI.
While frequenting the Chakra UI Discord and Stack Overflow tag , I've noticed repeating themes around styling tables.
Perhaps we tried to achieve setting a width for each row by adding a style directly on the Tr
, but the border didn't show up. Or perhaps we tried to set our Th
and Td
with a fixed width, but once they all were set, the sizes no longer worked.
As an example, let's cover 3 objectives of styling a table:
- Setting a border bottom width for each row
- Allowing all table columns to be a fixed width
- Adjusting the padding for each table cell
Here's a Replit sandbox showing the final solution. Feel free to fork it and use it as a sandbox.
Know Your Sources
In the Chakra UI documentation, each component links to a Source
and Theme source
on GitHub. Both of these links are valuable when you're determining where to set a style or troubleshooting why a border color or other element isn't changing.
Let's take a look at the Table component documentation .
Theme Source
The Theme source link references the style factory Chakra UI uses to generate the styles for component parts. This is the first place to look for how Chakra UI set up the component styling and any base, variant, or size styles that could conflict with the styles we're trying to set.
Chakra UI has a layered approach for styling components.1 There are three main parts:
- Base Styles - Component styling that applies to all variants. Usually excludes color and size-related styling.
- Sizes - Component styling that applies to a specific size of a component. Usually includes margins, padding, font sizes, line heights, and other spacing.
- Variants - Component styling that changes the visual appearance of a component. Different styles may be
solid
,outline
,striped
, etc. This is usually where color is applied.
The theme files look different depending on whether the component is a single-part component or a multi-part component.2
Single-part components, like a Button
, have one main element to style. They have a base style, variants, and sizes.
Multi-part components, like a Table
, have multiple elements/components that work together to build the desired visual. They also have base styles, variants, and sizes, and each base, variant, and size is broken down into multiple elements, called parts. A common mistake for developers new to Chakra UI is to try to style a multi-part component without labeling the parts in the styles, variants, or sizes.
All components have default styles, including a base style, variant, and size. All of these work together with the base style to create the final styles displayed for the component.
Let's take a deeper look at the Table theme source .
Default Props
If the default variant, size, and other style elements for a component aren't specified in the documentation, it can typically be found in the theme source file defined in the style config exported near the end of the file.
Here's an example from the Table
theme source3.
Looking at the defaultProps
, we can infer that the Table
component uses the simple
variant, md
size, and the gray
colorScheme by default.
We can use this information to look up the simple
variant, md
size, and gray
colorScheme to see if any of those cause a conflict with our Tr
border.
Base Style
The base styles apply to all variants and sizes, unless the variants or sizes override them.
Here is the Table
component's base style, pulled from the Table
theme source3:
Here we learn that by default, the table
width is set to full
, and borderCollapse
4 is set to collapse. That means that it's possible that the tr
border style we want to add is getting merged with something else's border style.
The table width set to full
is a pointer to 100%
. Since it's rendering <table />
HTML elements, it's likely using the default CSS properties for table
, th
, and other table components. table
by uses a default table-layout
5 of auto
, which sizes cells to their cell content. If the table is set to 100%
, auto-layout is going to try to fill all of that space proportionally to the cell's content. This is why our fixed content widths aren't working.
Variant
There are no border styles on the base style, so we can check the variant
. The default variant is simple
, so let's try to find something like that in the theme source.
In the Table
theme source3, we find variantSimple
, which returns a theme style broken down into parts, like th
, td
, caption
, and tfoot
.
Looking through these styles, both th
and td
have a borderBottom
and borderColor
. tr
is only mentioned in the context of tfoot
. We can infer that Chakra UI decided to set the border styles on the th
and td
components rather than tr
. Our tr
styles may be collapsed into the th
and td
styles. It may make more sense to set the bottom row border on th
and td
.
Size
The only thing we haven't found is where to adjust our padding. Chakra UI breaks size-related items like spacing, font sizes, and line heights into sizes
. This gives flexibility without needing to define sizes multiple times for each variant.
In the Table
theme source3, we conveniently find a constant named sizes
.
Here, padding, line heights, and font sizes are set for the th
and td
components, so that's a good place for us to adjust our cell padding.
Source
The Source link, in most cases, references the individual component package. There are a few components, like Box
, Flex
, Stack
, HStack
, VStack
, etc. that are grouped into a package like layout
.
The source is valuable when you've already looked at the theme source and are unable to find a conflicting style. It is rare, but there are a few components that have hard-coded styles or defaults on the component itself that may be interfering with other styles.
Putting It All Together
I won't go into depth about theme extension in this post, but let's resolve our styling objectives by extending our theme.
Once the exported theme extension is added to our ChakraProvider
as the theme, our new default table styles are automatically applied.
Here's the Replit sandbox showing the final solution