George
George

Reputation: 2422

Dynamically add styles to styled-jsx in Next.js

Please see the code. I want to add some extra style for the about link conditionally, so I am adding it inside ${} of the template string for the tag. This doesn't apply the new styles.

I have tried by concatenating the template strings. That didn't work either.

I cannot set style={style} in the tag because then I won't be able to use the :hover style.

import Link from 'next/link'
import { withRouter } from 'next/router'

const Header = ({ children, router, href }) => {
  const isIndex = router.pathname === "/";
  const isAbout = router.pathname === "/about";
  return (
    <div>
        <Link href="/">
          <a id="home">Timers</a>
        </Link>
        <Link href="/about">
          <a id="about">About</a>
        </Link>
        <style jsx>{
          `
            a {
              font-family: 'Montserrat Subrayada', sans-serif;
              color: #ffffff;
              text-decoration: none;
              font-size: 24px;
              padding: 2px;
              margin-right: 30px;
            }
            a:hover {
              color: #000000;
              background-color: #ffffff;
              border-radius: 2px;
            }
            ${isAbout ? `
            #about {
              background-color: red;
              color: #000000;
            }
            #about:hover {
              background-color: blue;
              color: #ffffff;
            }
            ` : ``}

          `
        }</style>
    </div>
)}

export default withRouter(Header)

How can I apply conditional styles?

Upvotes: 2

Views: 4688

Answers (2)

La pach&#39;
La pach&#39;

Reputation: 486

Since styled-jsx compiles styles at build time, it cannot preprocess dynamic styles, this is a limitation that is mentioned in the docshere

Plugins make it possible to use popular preprocessors like SASS, Less, Stylus, PostCSS or apply custom transformations to the styles at compile time.

Upvotes: 0

George
George

Reputation: 2422

The solution is to only change the property values dynamically, rather than add entire new selectors in a single conditional you must do it for each property, like this:

<style jsx>{
  `
    a {
      font-family: 'Montserrat Subrayada', sans-serif;
      color: #ffffff;
      text-decoration: none;
      font-size: 24px;
      padding: 2px;
      margin-right: 30px;
      border-radius: 2px;
    }
    a:hover {
      color: #000000;
      background-color: #ffffff;
    }
    #home {
      background-color: ${isHome ? "#ffffff" : ""};
      color: ${isHome ? "#000000" : ""};
    }
    #about {
      background-color: ${isAbout ? "#ffffff" : ""};
      color: ${isAbout ? "#000000" : ""};
    }
  `
}</style>

(I figured out the answer to my question while I was asking it, so I thought i'd just post it with my answer anyway in case someone else needs it)

Upvotes: 2

Related Questions