토이프로젝트: sticky component 만들기(2)

coolchaem·2022년 3월 2일
0

toyproject

목록 보기
10/21

저번 포스트에서 fixed position 속성으로 구현하였는데 sticky로 변경하려고 한다.

sticky로 변경

Q. 왜 바꾸는가?

  • fixed 속성으로 구현했을 때 위치를 조절하기 어려웠다. 일반적인 흐름에서 벗어나 stacking context를 구성하니까 포스트 글에 대해 상대적인 위치를 조절하기 어려웠다.

그래서 기존 flow에 따라 순서대로 배치될 수 있는 sticky로 변경!

"요소를 일반적인 문서 흐름에 따라 배치하고, 테이블 관련 요소를 포함해 가장 가까운, 스크롤 되는 조상과, 표 관련 요소를 포함한 컨테이닝 블록(가장 가까운 블록 레벨 조상) 을 기준으로 top, right, bottom, left의 값에 따라 오프셋을 적용합니다. 오프셋은 다른 요소에는 영향을 주지 않습니다.
이 값은 항상 새로운 쌓임 맥락을 생성합니다. 끈끈한 요소는 "스크롤 동작"(overflow가 hidden, scroll, auto 혹은 overlay)이 존재하는 가장 가까운 조상에 달라붙으며, 사실 그 조상은 스크롤 불가하며 실제로 스크롤 가능한 조상이 따로 존재할 경우 "끈끈한" 동작을 보이지 않는 점에 주의하세요. (W3C CSSWG의 Github 이슈 참조)"

code는 큰 차이 없다. position 속성이랑 상대적 배치로 top과 left를 rem으로 변경!


const StickyComponent = (props: React.PropsWithChildren<StickyProps>) => {
  return (
    <StickyBlock className={props.className} top={props.top} left={props.left}>
      {props.children}
    </StickyBlock>
  );
};

const StickyBlock = styled.div<StickyProps>`
  position: sticky;
  top: ${props => props.top}rem;
  left: ${props => props.left}rem;
  border: 1px solid rgb(241, 243, 245);
  border-radius: 2rem;
  align-items: center;
  -webkit-box-align: center;
  background-color: ${props => props.backgroudColor || 'rgb(248, 249, 250)'};
`;

그리고 부모 노드에서 사용할 때 height를 지정하고 px값으로 주던걸 rem값으로 변경!

const PostLikeShareButton = () => {
  return (
    <PostLikeShareStickyBox top={10} left={1}>
      <CircleButton key={1} />
      <CircleButton key={2} />
    </PostLikeShareStickyBox>
  );
};

const PostLikeShareStickyBox = styled(StickyComponent)`
  padding: 0.5rem;
  height: 6.5rem;
  flex-direction: column;
  @media (max-width: 1024px) {
    display: none;
  }
`;

sticky 동작은 scroll 가능한 부모 노드기준으로 임계치까지 relative처럼 동작하고 그 후 fixed로 동작한다.

성능 측정

relative로 일부 동작하면 성능에 차이가 심할까싶어 측정도 해봤다.

  • fixed

  • sticky

composite layers에서 차이가 있는 것으로 보인다.
하지만 5sec도 아닌 5ms이면...음...
시간을 좀 들여서 기능에 초점을 둬도 좋을거 같다.

호환 문제 조사

  • I* 브라우저 지원이 끝나면서 sticky와 같은 새로운 속성은 호환이 더 이상 안 된다.
    그럼에도 불구하고 지원할 수 있다면 하고 싶어 조사해봤으나, 다른 문제로 결과를 확인 할 순 없었다.

폴리필 패키지를 설치하거나, media 쿼리로 사용하는 방법 두가지로 좁혀졌었다.

const StickyBlock = styled.div<StickyProps>`
  position: sticky;
  top: ${props => props.top}rem;
  left: ${props => props.left}rem;
  border: 1px solid rgb(241, 243, 245);
  border-radius: 2rem;
  align-items: center;
  -webkit-box-align: center;
  background-color: ${props => props.backgroudColor || 'rgb(248, 249, 250)'};
  @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
    position: fixed;
  }
`;

아쉽게도 이 기능을 넣기 전부터 토이프로젝트가 i*에서 켜지지 않았다.^^...

profile
Front-end developer

0개의 댓글