Patrickkx
Patrickkx

Reputation: 1870

Change styles of component when hovering sibling

I have a simple case where I want the box2 to change background to yellow, if the box1 was hovered.

code sample:

const Box = styled.div`
  height: 200px;
  width: 200px;
  background: blue;
`;

const Box2 = styled.div`
  height: 200px;
  width: 200px;
  background: green;
  margin-top: 20px;

  ${Box}:hover {
    background: yellow;
  }
`;

in render:
  <Box>Box 1</Box>
  <Box2>Box 2</Box2>

Link to the code preview:

https://stackblitz.com/edit/react-rvhgov

Thanks!

Edit This one above doesnt seem to work, dont know why, it should work?

Upvotes: 0

Views: 1959

Answers (2)

SMAKSS
SMAKSS

Reputation: 10520

Depend on your render items you can do it with different approaches but as things we got here, you can use adjacent sibling combinator (+) or general sibling combinator (~). So all you have to do is to replace this

${Box}:hover {
  background: yellow;
}

with

/* If you want to only select the next element sibling, you should replace ~ with + */

${Box}:hover ~ & { 
  background: yellow
}

Working Demo:

https://stackblitz.com/edit/select-next-sibling

Upvotes: 5

Danko
Danko

Reputation: 1864

You can try this:

import React, { Component, useState } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

import styled, {css} from 'styled-components';

const Box = styled.div`
  height: 200px;
  width: 200px;
  background: blue;
`;

const Box2 = styled.div`
  height: 200px;
  width: 200px;
  background: green;
  margin-top: 20px;
  ${props => props.hovered && css`
    background: yellow;
  `} 
`;

export default function App() {
  const [hovered, setHovered] = useState(false);

  return (
    <div className="App">
      {'' + hovered}
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Box onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)}>Box 1</Box>
      <Box2 hovered={hovered}>Box 2</Box2>
    </div>
  );
}

render(<App />, document.getElementById('root'));

With this approach, it doesn't matter are elements/components siblings or not. It will work for siblings but also when components are nested in different subtrees.

Upvotes: 1

Related Questions