본문 바로가기

기록/TIL

2023.09.08 모달 z-index가 안먹힌다?

모바일 환경에서 팝업을 보여주기 위해 팝업(모달)을 만들고 있었다.
팝업창이 올라오면 배경을 어둡게 하기 위해 backdrop을 만들기로 했다.
 
 

위 사진에서 필터를 제외한 다른 부분을 어둡게 하고싶다.

 
기존 코드

const MobileCategory = () => {
  const [isOpen, setIsOpen] = useAtom(isMobileFilterAtom);

  return (
    <S.MobileCategorySection $isOpen={isOpen}>
      <S.CategolyClose onClick={() => setIsOpen(false)}>
        <img src={closebar} alt="closebar" />
      </S.CategolyClose>
      <S.MobileCategoryContainer>
        <S.CategoryTextContainer>
          <S.CategoryTextContainer>필터</S.CategoryTextContainer>
        </S.CategoryTextContainer>
        <AnimeCategory />
      </S.MobileCategoryContainer>
    </S.MobileCategorySection>
  );
};

 
여기에 새로운 div를 만들어, fixed로 고정시키고 width, height를 100%로 준 후 모달이 열리면 배경색을 어둡게 할것이다.
 
styled 코드

 MobileCategoryBackdrop: styled.div<Props>`
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.4);
    display: ${({ $isOpen }) => ($isOpen ? 'block' : 'none')};
    z-index: 998; // 모달창보다는 뒤로. 모달창은 999이다.
  `,

 
적용 해 보자.
 

???

 
배경이 모달창을 잡아먹었다. 이러면 안되는데. z-index를 줬는데도 작동하지 않는다. 뭔가 잘못됬다.
 
그러다 아래의 글을 찾아냈다.
 

<section class="content">            
    <div class="modal"></div>
</section><div class="side-tab"></div>
마크업을 보면 content와 side tab 요소들이 같은 위계에 있음을 알 수 있습니다. 즉, 마크업에서 같은 레벨에 존재합니다. (z-index 레벨과는 다릅니다.) 그리고 모달은 content의 자식 요소입니다.
모달이 content 요소 안에 있기 때문에 z-index: 100 은 content 요소 안에서만 효과가 있습니다. 예를 들어 모달과 같은 위계의 다른 자식 요소들이 있다면 그 요소들끼리는 z-index값에 따라서 위 또는 아래에 배치됩니다.
그러나 부모 content 요소의 z-index가 1로 설정되어 있으므로 자식 요소들의 z-index값은 부모 요소밖의 요소들에는 아무 의미가 없습니다. 모달을 포함한 자식 요소들은 부모의 z-index를 벗어날 수 없습니다.

출처 - z-index가 동작하지않는 이유 4가지 (그리고 고치는 방법)

 
그렇다. 모달( 배경색을 어둡게 하는 모달 )이 자식이었기 때문이다.
그럼, 이유도 알았으니 모달을 바깥으로 분리 해 보자.
 
수정된 코드

const MobileCategory = () => {
  const [isOpen, setIsOpen] = useAtom(isMobileFilterAtom);

  return (
    <>
      <S.MobileCategorySection $isOpen={isOpen}>
        <S.CategolyClose onClick={() => setIsOpen(false)}>
          <img src={closebar} alt="closebar" />
        </S.CategolyClose>
        <S.MobileCategoryContainer>
          <S.CategoryTextContainer>
            <S.CategoryTextContainer>필터</S.CategoryTextContainer>
          </S.CategoryTextContainer>
          <AnimeCategory />
        </S.MobileCategoryContainer>
      </S.MobileCategorySection>

      <S.MobileCategoryBackdrop $isOpen={isOpen} />
    </>
  );
};

 
 

 
원하는대로 작동한다!
 
 
결론 : 자녀는 부모에의해 강제되며 부모를 벗어날 수 없다! (적어도 z-index는)

'기록 > TIL' 카테고리의 다른 글

2023.09.12 supabase inner join  (0) 2023.09.12
2023.09.11  (0) 2023.09.11
2023.09.04  (0) 2023.09.04
2023.09.01  (0) 2023.09.01
2023.08.31  (0) 2023.08.31