React styled-components - How to render styles based on prop condition or pseudo class?

Bryce Snyder

I am trying to conditionally render a hover state / view within styled-components, leveraging the props coming in from react...

Currently, my code looks something like this:

${isHovered}, &:hover {
    background: red;
}

Unfortunately, this does no work to be able to have a true/false as I am missing something I presume to be able to do the either / or pseudo..

I want to be able to explicitly show the hover state while retaining the default pseudo hover. How can I achieve this?

Matt Carlotta

The way you have your selectors right now is invalid:

Problem

${isHovered}, &:hover {
    background: red;
}

As of now, this will always translate to:

undefined, &:hover {
    background: red;
}

For simplicity, in order to interpolate properly, it must be a function accepting props that returns a string:

color: ${props => props.isHovered && "pink" };

On a related note, even if you wrapped your styled component in a higher order component where isHovered is defined as an argument, it unfortunately still won't work in production for styled-components v5 -- this worked in v4, but v5.x doesn't handle css interpolations properly within a styled component when compiled for production (see issue tracker here).

Solutions

A better and recommended approach would be to interpolate within a CSS property:

  background: ${({ isHovered }) => isHovered && "red"};

  :hover {
    background: red;
  }

Alternatively, if you have multiple CSS rules, then you can interpolate outside of a CSS property:


  ${({ isHovered }) => isHovered && "background: red;color: white;"};

  :hover {
    background: red;
  }

Now you just would pass your component an isHovered prop.

<StyledComponent isHovered={isHovered} />

Although, technically you can do this (notice that falsey values equate to true, which may be a bug or an unhandled edge case) ...

${({ isHovered }) => !isHovered && ".hovered"}, &:hover {
    background: red;
}

...it is NOT recommended because of how it's being interpreted:

".hovered", &:hover {
    background: red;
}

Arguably, this isn't what you'd want because .hovered isn't being used at all within the DOM, which may be confusing to other developers. Instead, it reuses the compiled hashed class name to add the CSS property within another rule (focus on the Styles tab to see the difference): screenshot

While the recommended approach sets the CSS property to the hashed class within the same rule block: screenshot


Working demo (this demo includes both example codes above, where Title uses the recommended approach and SubTitle doesn't):

Edit Styled Components - Parent Hover

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

React: Why not just use styles object instead of styled-components?

How to render pseudo before content dynamically in styled-component

How to add multiple styles based on property with styled-components?

Overwriting nested styles in React Bootstrap using Styled-Components

Overriding react components styles with styled component

Share the same styles between two types of component with React Styled Components

Can I create class-based React Styled Components?

React-Router not correctly rendering Styled-Components Styles

React does not recognize the `isActive` prop on a DOM element - styled-components

Styled Components - Conditionally render an entire css block based on props

How do I get a variable from a graphQl query into a pseudo element in either inline styles or styled components

How to dynamically render react components based on selected dropdown value

How to make changes in styled components based on state

How to create shared styles using styled components?

How to do overlapping styles with Styled Components React?

React styled-components not applying styles to components

How to properly use ref with a React class component and styled-components?

How to Declare Styled Components Using React Component Class Syntax

Styled Components - How to style a component passed as a prop?

Styled components not applying styles

How to add a css property only when condition true using styled components and react?

React app with styled components and twin.macro set global styles

How to apply styles to multiple components using styled components

How to add "active" class to styled components in React

How can I make multiple styling for only one prop in React Styled Components?

How to style a component based on state in Styled Components?

styled-components — how to use :not() selector on a prop?

reactjs: I have no idea how to render these components with styled-components

How to write a conditional css pseudo-element with styled-components?