Search code examples
cssreactjscss-selectorsstyled-components

Styled components, reverse selector pattern on input elements


I'm trying to follow the 'Reverse Selector' pattern detailed here. Both of the below are nested within a label tag. Clicking the label activates the input, but the conditional styling in FakeInput isn't applied.

Any ideas?

export const CheckboxInput = styled.input`
  position: absolute;
  opacity: 0;
`;

export const FakeInput = styled.div`
  height: 2.2rem;
  width: 2.2rem;
  margin-right: 1rem;
  border-radius: 0.2rem;
  background-color: #333;
  color: #333;
  font-size: 1.8rem;

  ${CheckboxInput}:checked & {
      background-color: green;
      color: white;
  }
`;

It's being rendered from this function:

renderInputRow({ key, name }) {
    const inputRow = (
        <CheckboxLabel key={key}>{name}
            <CheckboxInput type="checkbox" name={key} />
            <FakeInput className="fa fa-check" />
        </CheckboxLabel>
    );

    return inputRow;
}

Solution

  • There's luckily nothing wrong with our example on the site, but it's a problem with your selector here:

    ${CheckboxInput}:checked &
    

    On its own this selector is totally fine and signifies "any children of CheckboxInput when it's checked", but your code contains this:

    <CheckboxInput type="checkbox" name={key} />
    <FakeInput className="fa fa-check" />
    

    So you'll want to say "any sibling of CheckboxInput", which would be:

    ${CheckboxInput}:checked ~ &
    

    I've quickly pasted your code into a CodeSandbox to confirm that it works: https://codesandbox.io/s/rkmNRByE4

    Hope this helps :)