웹 개발을 하다 보면 브라우저마다 CSS 속성의 동작 방식이 미묘하게 다를 수 있습니다. 이번에 제가 발견한 이슈는 Firefox에서 position: fixed
가 display: grid
와 함께 사용될 때, 예상과 다르게 동작하는 문제입니다. 검색해보아도 관련 자료를 찾기 어려웠기 때문에, 해결 과정을 공유하고자 합니다.
배경 지식
일반적으로 position: fixed
는 뷰포트를 기준으로 설정된 top
, bottom
, left
, right
위치에 고정됩니다. 그러나 위치 설정이 없다면 top
, bottom
, left
, right
가 auto
가 되어, 브라우저가 자동으로 계산한 문서 흐름 상 원래 있어야 했을 위치에 고정됩니다.
position: fixed;
top: auto;
bottom: auto;
left: auto;
right: auto;
상황 설명
저는 위 사실을 바탕으로 display: grid
와 position: fixed
를 함께 사용하면서, 부모 요소에 grid-template
을 설정하고, 위치 설정 없이 fixed
와 grid-column: 1/2; grid-row: 2/3;
처럼 위치를 지정하면 문서 흐름 상 원래 있어야 했을 위치인 해당 grid 위치에 고정된다는 사실을 발견해 유용하게 사용하고 있었습니다. 아래는 제가 사용한 코드와 웹 이미지입니다:
position: fixed;
padding: 10px;
@media ${media.expanded} {
grid-column: 1/2;
grid-row: 2/3;
}
Firefox에서 발생한 문제
Chrome, Safari, Opera, Edge 등 다른 브라우저에서는 위 코드가 정상적으로 동작하지만, Firefox에서는 요소가 문서 흐름 상 원래 있어야 했을 위치인 grid 영역을 무시하고, 전체 영역의 좌상단에 고정됩니다.
해결 방법
Firefox에서 발생하는 이 문제를 해결하기 위해, position: sticky
로 대체하는 방법을 사용했습니다. position: sticky
는 부모 요소의 grid 영역에 영향을 받으며 특정 스크롤 위치에서 요소를 고정시킬 수 있어, Firefox에서 발생하는 문제를 해결하는 데 적합했습니다.
@supports (-moz-appearance: none) {
position: sticky;
top: 90px;
height: calc(100vh - 90px);
}
위 코드에서 @supports (-moz-appearance: none)
는 Firefox에서만 적용되도록 하는 조건문입니다. position: sticky
를 사용하여 요소를 고정 위치에 두면서, 상단에서 90px 떨어진 위치에 고정시킵니다.
왜 전부 sticky로 대체하지 않았는가?
모든 브라우저에서 position: sticky
를 사용하는 대신, 일부만 사용하는 이유는 UX 때문입니다. 노트북 등 트랙패드나 태블릿 터치 드래그로 스크롤할 때, 오버스크롤 시 고정된 메뉴가 상하단 임계점에 닿으면 튕기는 듯한 움직임이 발생할 수 있습니다. 이는 사용자 경험을 저해할 수 있기 때문에, 최대한 position: fixed
를 유지하고 필요한 부분에만 position: sticky
를 사용했습니다.
결론
이번 문제는 display: grid
와 top: auto
(bottom, left, right
)의 크로스 브라우징 문제로, Firefox에서 발생하는 이슈였습니다. 이를 해결하기 위해 position: sticky
를 사용하여 문제를 해결했습니다. 웹 개발 시 브라우저별 호환성을 고려하여 다양한 방법을 시도해보는 것이 중요합니다. 이 글이 비슷한 문제를 겪는 다른 개발자들에게 도움이 되길 바랍니다.
추가수정
function Left({ children }: LayoutProps) {
return (
<Expanded>
<RelativeLeft>
<LeftContainer>{children}</LeftContainer>
</RelativeLeft>
</Expanded>
);
}
const LeftContainer = styled.aside`
position: fixed;
width: 280px;
padding: 10px;
`;
const RelativeLeft = styled.div`
position: relative;
width: 100%;
height: 100%;
@media ${media.expanded} {
grid-column: 1/2;
grid-row: 2/3;
}
`;
position: relative인 부모 요소를 grid에 맞게 배치한 후, 내부에 fixed를 사용하여 문제를 완전히 해결하였습니다.
'개발일지' 카테고리의 다른 글
RTK-Query의 usePrefetch를 사용하여 로딩 화면 줄이기 (0) | 2024.07.05 |
---|---|
React 프로젝트 설계 2: 컴포넌트 유형 나누기 (0) | 2024.07.03 |
UX를 고려한 개발: react-beautiful-dnd 에서 버튼 클릭 방식으로의 전환 (1) | 2024.06.28 |
React 프로젝트 설계 1: 나만의 폴더 구조 도입 (0) | 2024.06.27 |
Compound Component 패턴으로 반응형 레이아웃 관리하기 (0) | 2024.04.16 |