reactjsstyled-componentsemotioncss-in-js

Sibling Selectors not working correctly with Emotion


I have the following code:

const CardContainer = styled(Flex)`
  flex-direction: column;
  padding: 12px;
  width: 100%;
  max-width: 450px;
  height: auto;
  border-radius: 32px;
  overflow: hidden;
  z-index: 1;
  background: rgba(218, 228, 242);
  box-shadow: 4px 4px 12px 2px rgba(black, 0.6);
  transition: 0.2s;

  &:not(:first-child) {
    background: red;
    margin-left: -50px;
  }

  &:hover,
  &:focus-within {
    transform: translatey(-1rem);
  }

  &:hover ~ &,
  &:focus-within ~ & {
    transform: translatex(50px);
  } 
`;

But the last statement is not working. The CSS code that I'm trying to copy is:

.card:hover ~ .card,
.card:focus-within ~ .card {
  transform: translatex(50px);
}

And here is the original codepen:

https://codepen.io/toddwebdev/pen/yWMgQX?editors=1100


Solution

  • You need to do this instead:

    & + ${() => CardContainer} {
      transform: translateX(var(--distance));
    }
    

    Also your import styled from "@emotion/styled has to be import styled from "@emotion/styled/macro in order to support the above.

    Note: changed the styled(Flex) to styled("section") to prevent errors in sandbox

    Codesandbox Demo


    import styled from "@emotion/styled/macro";
    import "./styles.css";
    
    const CardContainer = styled("section")`
      flex-direction: column;
      padding: 12px;
      width: 100%;
      max-width: 450px;
      height: auto;
      border-radius: 32px;
      overflow: hidden;
      z-index: 1;
      background: rgba(218, 228, 242);
      box-shadow: 4px 4px 12px 2px rgba(black, 0.6);
      transition: 0.2s;
    
      &:not(:first-of-type) {
        margin-left: -50px;
      }
    
      &:hover,
      &:focus-within {
        transform: translateY(-1rem);
    
        & + ${() => CardContainer} {
          transform: translateX(var(--distance));
        }
      }
    `;
    
    export default function App() {
      return (
        <div className="cards">
          <CardContainer>
            <div className="card">
              <h1>
                <a href="#0">Title</a>
              </h1>
              <p>This is an article and this has some content.</p>
            </div>
          </CardContainer>
          <CardContainer>
            <div className="card">
              <h1>
                <a href="#0">Title</a>
              </h1>
              <p>This is an article and this has some content.</p>
            </div>
          </CardContainer>
          <CardContainer>
            <div className="card">
              <h1>
                <a href="#0">Title</a>
              </h1>
              <p>This is an article and this has some content.</p>
            </div>
          </CardContainer>
          <CardContainer>
            <div className="card">
              <h1>
                <a href="#0">Title</a>
              </h1>
              <p>This is an article and this has some content.</p>
            </div>
          </CardContainer>
          <CardContainer>
            <div className="card">
              <h1>
                <a href="#0">Title</a>
              </h1>
              <p>This is an article and this has some content.</p>
            </div>
          </CardContainer>
        </div>
     );
    }