Search code examples
cssreactjscss-transitionsgatsbytailwind-css

How do I transition background color with Tailwind CSS in React?


I am building a gatsby site and I want to have my header change background color opacity as I scroll down. What's the best way to approach this?

I currently have this, where isScrolled is a state value that I'm updating with a custom hook. The problem I have is that there is no transition appearing, I'm pretty sure because React is re-rendering the whole component when the state changes.

What would be the appropriate tool / method for solving this problem?

 <header
          className={
            `h-16 z-10 fixed top-0 left-0 w-screen transition-all`
              ${
               isScrolled ? "bg-white" : "bg-transparent"
             }`
          }
        >
          <div className="px-8 container mx-auto flex items-center justify-between h-full">
            <Logo />
            <nav>
              <HeaderLink to="about-us">About</HeaderLink>
              <HeaderLink to="blog">Blog</HeaderLink>
              <HeaderLink to="contact">Contact</HeaderLink>
            </nav>
          </div>
        </header>

I've tried the HeadlessUI Transition component but that doesn't work because it only transitions in an entire component (as opposed to a property) and I haven't been able to get React-Transition-Group working either. Any help would be appreciated,

Thanks


Solution

  • try use this in your component,

    ...
    const [isScrolled, setIsScrolled] = useState(false);
    ...
      <header
        className={`h-16 z-10 fixed top-0 left-0 w-screen transition-all duration-200
              ${isScrolled ? "bg-white" : "bg-transparent"}`}
      >
    

    and read this article to detect the correct scroll event. Happy coding!

    Update version in Dec. 2023 is useing clsx package

    Install clsx package check this package document

    import clsx from 'clsx'
    ...
    // state define to use conditional logic
    const [isScrolled, setIsScrolled] = useState(false);
    ...
    // define base css classes as constant
    const base = 'h-16 z-10 fixed top-0 left-0 w-screen transition-all duration-200' as string
    
    return (
       ...
         <header className={clsx(base, isScrolled ? "bg-white" : "bg-transparent")}
      >
       ...
    )
    

    Another usages

    // Strings (variadic)
    clsx('foo', true && 'bar', 'baz');
    //=> 'foo bar baz'
    
    // Objects
    clsx({ foo:true, bar:false, baz:isTrue() });
    //=> 'foo baz'
    
    // Objects (variadic)
    clsx({ foo:true }, { bar:false }, null, { '--foobar':'hello' });
    //=> 'foo --foobar'
    
    // Arrays
    clsx(['foo', 0, false, 'bar']);
    //=> 'foo bar'
    
    // Arrays (variadic)
    clsx(['foo'], ['', 0, false, 'bar'], [['baz', [['hello'], 'there']]]);
    //=> 'foo bar baz hello there'
    
    // Kitchen sink (with nesting)
    clsx('foo', [1 && 'bar', { baz:false, bat:null }, ['hello', ['world']]], 'cya');
    //=> 'foo bar hello world cya'
    

    Happy coding :)