Next에서 css에 first-child 대신 first-of-type으로 쓰는것이 안전하다.

SSR에서 first-child가 unsafe 하다고 한다.

스크린샷 2022-12-01 오후 4.26.58.png

https://serisepomme.tistory.com/entry/CSS로-자식-요소-갯수-알아내기

왜 그런가 이유를 봤더니

import styled from "@emotion/styled";

const Text = styled.p`
  color: gray;
  &:first-child {
    color: black;
  }
`;

export default () => (
  <div>
    <Text>Title</Text>
    <Text>Subtitle</Text>
  </div>
);

이런식으로 작성된 코드가 있다고 하자

emotion 10에서 SSR을 할때, <head> 내부에 스타일을 전부 넣는게 아니라 component마다 <style> 태그를 붙여서 렌더링을 해준다.

서버측에서의 DOM 구조는 다음과 같다.

<div>
  <style data-emotion-css="1fyxi0m">
    .css-1fyxi0m {
        color: gray;
    }

    .css-1fyxi0m:first-child {
        color: black;
    }
  </style>
  <p class="css-1fyxi0m">Title</p>
  <style data-emotion-css="1fyxi0m">
    .css-1fyxi0m {
        color: gray;
    }

    .css-1fyxi0m:first-child {
        color: black;
    }
  </style>
  <p class="css-1fyxi0m">Subtitle</p>
</div>

여기서 first-child, 즉 첫번째 태그는 뭘까?

바로 <style> 태그이다.

따라서 우리가 원하는 대로 첫번째 p태그에 css 적용이 안되는 것이다. 따라서 상황에 따라 :first-child가 동작을 했다가 안했다가 하게 되므로 unsafe하다.

따라서 emotion 에서 해결법을 제시해준다.

Use :first-of-type:last-of-typeor :nth-of-typeselectors.