Headings in Chakra-ui theme vary in size according to their heading level

I have been attempting to customize the font size for h elements within a Chakra-UI theme, but I am facing challenges in overriding the default responsive definitions set by the base theme.

In my NextJS project, where I fetch content from DatoCMS headless CMS, the implementation of the h elements is as follows:

      ...
      renderRule(isHeading, ({ node, children, key }) => {
        return (
          <Heading key={key} as={`h${node.level}`} pt={6} pb={4}>
            {children}
          </Heading>
        );
      }),
      ...

If I try to modify it within this structure by including something like

<Heading key={key} as={`h${node.level}\`} pt={6} pb={4} size=('5xl')>
, then it works perfectly fine. My theme is functional overall (e.g., defining brand color variables and setting font weight for Heading elements), except for adjusting the size of headings.

The closest I've come is by tweaking the size within the global object:

const styles = {
    global: (props) => ({
      h1: { fontSize: [null, null, '5xl'] }
    })
}

While this does reflect changes in the browser, it still gets overridden. In the developer tools, the computed CSS showcases conflicting values for font sizes.

I have also experimented with:

Specifying a single value in textStyles:

const textStyles = {
    h1: {
        fontSize: '5xl'
    }
}

Defining an array in textStyles:

const textStyles = {
    h1: {
        fontSize: [ null, null, '5xl' ]
    }
}

Setting the baseStyle at the component level:

const Heading = defineStyleConfig({
    baseStyle: {
        fontWeight: 'light', // Functional
        textStyles: { h1: [ null, null, '5xl' ] } // Not effective 
    }
})

Unfortunately, none of these modifications seem to take effect on the final output in the browser.

Could someone guide me on the correct approach to adjust text size at the theme level?

Answer №1

In solving the issue in my project, I encountered a problem where setting the fontSize was being overridden by the default size prop, which is set to xl. This default size comes with specific styles that include setting the fontSize and lineHeight. For more information on the default sizes, you can refer to the Heading Theme Source.

To work around this, I found that specifying a custom empty size ("dynamic" as shown in the code below) and creating a baseStyle that depends on the value of the as prop was the solution:

// Define your preferred heading sizes here
const headingSizes = {
  "4xl": defineStyle({
    fontSize: "5xl",
    lineHeight: 1.1,
  }),
  "3xl": defineStyle({
    fontSize: "4xl",
    lineHeight: 1.3,
  }),
  "2xl": defineStyle({
    fontSize: "3xl",
    lineHeight: 1.5,
  }),
  xl: defineStyle({
    fontSize: "2xl",
    lineHeight: 1.7,
  }),
  lg: defineStyle({
    fontSize: "xl",
    lineHeight: 1.8,
  }),
  md: defineStyle({
    fontSize: "lg",
    lineHeight: 1.9,
  }),
  sm: defineStyle({
    fontSize: "md",
    lineHeight: 2,
  }),
  xs: defineStyle({
    fontSize: "sm",
    lineHeight: 2,
  }),
};

// Chakra theme incorporating dynamic heading size based on the "as" prop
const theme: ThemeOverride = {
  components: {
    Heading: {
      baseStyle: ({ as }) => {
        switch (as) {
          case "h1":
            return headingSizes["4xl"];
          case "h2":
            return headingSizes["3xl"];
          case "h3":
            return headingSizes["2xl"];
          case "h4":
            return headingSizes["xl"];
          case "h5":
            return headingSizes["lg"];
          case "h6":
            return headingSizes["md"];
          default:
            return headingSizes["3xl"];
        }
      },
      sizes: {
        dynamic: {},
      },
      defaultProps: {
        size: "dynamic",
      },
    },
  }
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it feasible to update just one key within an exported type using setState in TypeScript?

Recently, I decided to dive into Typescript within my React App and encountered an error that has left me stumped. I'm wondering if it's possible to access a specific key in an exported type and modify its value? Here is how I've exported ...

What steps do I need to take in order to create a Stripe prebuilt page that enables users to choose from a variety of

Currently, I am implementing Next.js and have a business selling packs of credits. The pricing structure is $10 for 10 credits, $20 for 30 credits, and so forth. My goal is to integrate a prebuilt Stripe page that allows users to choose the credit packag ...

What are the risks of storing confidential keys in environment variables for a next.js application?

From my understanding, environment variables that start with NEXT_PUBLIC_ will be replaced with their values in the final bundle. Is it considered secure to include sensitive information like API keys and OAuth secrets using NEXT_PUBLIC_* variables, or is ...

Enhancing MUI Stepper Designs in React for the Year 2022

I've been struggling with customizing styles for a React MUI Stepper component in 2022, especially for the active and completed states of the label and circle icon. My Customization Code import { ThemeProvider } from '@mui/styles'; import { ...

Creating a Personalized Color Palette Naming System with Material UI in TypeScript

I have been working on incorporating a custom color palette into my material ui theme. Following the guidance provided in the Material UI documentation available here Material UI Docs, I am trying to implement this feature. Here is an excerpt from my cod ...

Passing multiple functions to child components in ReactJS as a single prop

I am utilizing the technique of passing multiple functions as individual props from the parent component to its child components. Everything is working correctly without any errors or problems, but I'm interested in exploring if there is a more effici ...

Is there a way to transform these into five columns within a single row using the Material-UI Grid system?

I'm trying to align 5 columns in one row, but I'm struggling to achieve the desired layout. Here is what I currently have: https://i.stack.imgur.com/d3z3n.png Any tips on how to make all columns appear in a single row? You can also view my att ...

Enhance user experience by implementing an interactive feature that displays

I have a form for adding recipes, where there is an ingredients button. Each recipe can have multiple ingredients. When the button is clicked, an input field for adding ingredients should appear below the ingredient button. What I've attempted so far ...

Modifying arrays in ReactJS

Having trouble editing my array list, need some help. I can update a single input value successfully, but struggling with updating the entire array. Any suggestions on why the method isn't working and how to edit the array? When I try to store data ...

Experiencing trouble with cross-origin resource sharing when attempting to transfer data to my server

"Access to XMLHttpRequest at 'http://localhost:3000/campgrounds/6411f03e718f68104cac045a' (redirected from 'http://localhost:5000/campgrounds') from origin 'http://localhost:3000' has been blocked by CORS policy: Response ...

Struggling to incorporate this script tag into my next.js application and encountering some difficulties

If you want to integrate EmailJS into your website, simply add the code snippet below before the closing tag, making sure to replace "YOUR_USER_ID" with your actual user ID: <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/emailjs-com@2 ...

What is the best way to set a value for a variable within a UI component in React?

I'm still learning the ropes with React and JavaScript. My current challenge involves declaring a temporary variable and assigning the value of companyData.name to it, as I need to gather data from two variables like companyData.name. Below is my cod ...

Deactivate a input field depending on an autocomplete selection in React.js using Material-UI

Currently, I am facing an issue with two fields on my form. The first field is an autocomplete feature while the second field is a textfield. By default, my second field is disabled but I need it to become enabled every time a user types and selects an opt ...

Apologies, we were unable to establish a connection as the server refused to respond on the specified IP address and port

kubectl get namespace default Active 3h33m ingress-nginx Active 3h11m kube-node-lease Active 3h33m kube-public Active 3h33m kube-system Active 3h33m kubectl get services -n ingress-nginx NAME ...

Struggling with Running the Webpack serve Command

Struggling to set up a React app using Webpack and Babel. After following various tutorials on YouTube and other websites, I keep encountering the same error whenever I run the webpack serve command, even if my index.js file is empty. [ERROR]: ERROR in .. ...

What steps should I follow to incorporate WordPress as a subdomain within a Next.js application?

Currently, I am working on a project where I have developed a Next.js (React) application with the backend running on WordPress. The app is live on the Vercel platform and connected to my GoDaddy domain. However, I am encountering an issue when trying to ...

Encountering a client component error with the app router in Next.js version 13.4.9

Encountering an error in Nextjs that persists until the 'use client' directive is removed. Warning: Rendering <Context.Consumer.Consumer> is not supported and will be removed in a future major release. Did you mean to render <Context.Con ...

Using either Google Maps or a customized mapping solution in a React Native application

I am currently developing an application that allows users to input addresses and locate them on a map. I am wondering if implementing AI technology or utilizing specific libraries is necessary in order for this feature to function properly within a reac ...

ReactJS and Docker-Compose issue: "Essential file not found"

My ReactJS application has been dockerized for development using Docker for Windows. The application is built into a docker image and runs on a container with the help of docker-compose tool. The package.json file below shows an outdated ReactJS scaffoldin ...

Get the selected row value from a Table and convert it into an array. Then, pass this array as a parameter to another function

I need help with logging and storing selected values from a Table component in React My Table component displays data from an API with checkboxes on each row. I'm using the <Table /> Material UI component for React. The documentation states th ...