Search code examples
cssreactjsgatsbyantdemotion

Emotion style overruled by antd default style


I have a Gatsby project and created a component as such:

/** @jsx jsx */
import { jsx, css } from '@emotion/core'
import styled from '@emotion/styled'
import { Link } from 'gatsby'
import React from 'react'

import { AntDesignOutlined } from '@ant-design/icons'
import { Layout, Typography } from 'antd'
const AntHeader = Layout.Header
const { Title } = Typography

type Props = {
  siteTitle: string
}

const Header: React.FC<Props> = ({ siteTitle }) => (
  <AntHeader>
    <div>
      <h1>
        <Link to="/" css={LinkStyle}>
          <AntDesignOutlined />
          {` `}
          {siteTitle}
        </Link>
      </h1>
      <TitleStyled>Title</TitleStyled>
    </div>
  </AntHeader>
)

Header.defaultProps = {
  siteTitle: ``,
}

const TitleStyled = styled(Title)`
  color: red;
`

const LinkStyle = css`
  color: #fff;
`

export default Header

And the style rules result in the TitleStyle being overwritten as in this example: enter image description here

I have demoed this on the following Gatsby starter: https://github.com/yusugomori/gatsby-starter-antd-typescript-emotion

I am at a loss at what I can do to fix this.


Solution

  • This doesn't actually have anything to do with React, Gatsby, Ant Design, or Emotion, it's just CSS specificity. The selector el.foo has a higher specificity than just .foo, therefore its styles will take precedence. See How are the points in CSS specificity calculated for more detail.

    You might also find the techniques for overriding styles outlined in the Ant documentation useful. Additionally, there are a handful of alternate approaches here: How to customize Ant.design styles