Target another styled component on hover
ReactjsStyled ComponentsReactjs Problem Overview
What is the best way to handle hovers in styled-components. I have a wrapping element that when hovered will reveal a button.
I could implement some state on the component and toggle a property on hover but was wondering if there is a better way to do this with styled-cmponents.
Something like the following doesn't work but would be ideal:
const Wrapper = styled.div`
border-radius: 0.25rem;
overflow: hidden;
box-shadow: 0 3px 10px -3px rgba(0, 0, 0, 0.25);
&:not(:last-child) {
margin-bottom: 2rem;
}
&:hover {
.button {
display: none;
}
}
`
Reactjs Solutions
Solution 1 - Reactjs
As of styled-components v2 you can interpolate other styled components to refer to their automatically generated class names. In your case you'll probably want to do something like this:
const Wrapper = styled.div`
&:hover ${Button} {
display: none;
}
`
See the documentation for more information!
The order of components is important. It will only work if Button
is defined above/before Wrapper
.
If you're using v1 and you need to do this you can work around it by using a custom class name:
const Wrapper = styled.div`
&:hover .my__unique__button__class-asdf123 {
display: none;
}
`
<Wrapper>
<Button className="my__unique__button__class-asdf123" />
</Wrapper>
Since v2 is a drop-in upgrade from v1 I'd recommend updating, but if that's not in the cards this is a fine workaround.
Solution 2 - Reactjs
Similarly to mxstbr's answer, you can also use interpolation to reference a parent component. I like this route because it encapsulates a component's styling a little better than referencing the child component in the parent.
const Button = styled.button`
${Wrapper}:hover & {
display: none;
}
`;
I couldn't tell you when this feature was introduced but this works as of v3.
Relevant link: https://www.styled-components.com/docs/advanced#referring-to-other-components
Solution 3 - Reactjs
My solution is
const Content = styled.div`
&:hover + ${ImgPortal} {
&:after {
opacity: 1;
}
}
`;
Solution 4 - Reactjs
This is what worked for me
const NoHoverLine = styled.div`
a {
&:hover {
text-decoration: none;
}
}
`
Solution 5 - Reactjs
const ConnectButton = styled(WalletDialogButton)`
background-color: #105b72;
border: none;
margin: 10vh auto;
width: 250px;
&:hover {
background-color: #105b72c2;
}
`;
This worked for me as Marcos said. I'm using styled() instead of styled.something
I don't really know why, but I'm referencing a node_modules package where WalletDialogButton
exists.
Solution 6 - Reactjs
This solution worked for me:
const ContentB = styled.span`
opacity: 0;
&:hover {
opacity: 1;
}
`
const ContentA = styled.span`
&:hover ~ ${ContentB} {
opacity: 1;
}
`