Search code examples
cssreactjsstyled-components

Styled Components: Style Parent if child has attribute


I have a Parent that has a deeply nested child which can get an attribute if selected.

How do I style the background-color of the parent, only if a deeply nested child has an attribute of 'selected'?

<Parent>
 <Child>
  <NestedChild selected>

This is what I have tried:

const Parent = styled.div`
  &[selected] { // But this only styled the child, not the parent}
`;

Solution

  • The CSS way

    There isn't one - CSS doesn't allow an element to affect styling of its parents, only that of its children or siblings.

    The React purist way

    Use the useContext hook along with createContext and a context Provider, or simply pass a callback down through all the nested levels.

    The hacky-yet-simple React + vanilla JavaScript way

    // set up some styles for `has-child-selected` class
    // ...
    
    const Parent = ({ ... }) => {
      return <div className="parent">
        ...
      </div>
    }
    
    const Child = ({ selected }) => {
      const ref = useRef(null)
    
      useEffect(() => {
        ref.current.closest('.parent')
          .classList[selected ? 'add' : 'remove']('has-child-selected')
      }, [selected])
    
      return <div ref={ref}>
        ...
      </div>
    }
    
    

    Edit: I realized I didn't even mention Styled Components in this answer, but I don't think it would change very much. Perhaps someone with more knowledge of Styled Components would be able to enlighten.