새로운 Position Sticky

position: sticky 는 정말 유용한 기능으로 고정 픽스 네비게이션 등을 구현할 때 아주 편리합니다.
다음과 같은 코드에 다음과 같이 적용만해주면 바로 적용이 되는데요.

다음과 같은 코드는 스크롤을 내릴 때 nav 엘리먼트가 상단에 고정되어 따라다니게 해줍니다.
참 좋은 기능이죠. 그러나 아주 치명적인 단점이 있습니다.

IE 에서 지원하지 않는 기능입니다.

 

브라우저 지원 현황

이게 얼마나 치명적인 느낌인지 모르시는 분들을 위해..

2018년 한국의 브라우저 사용 점유율

위 사진은 2018년 한 해를 기준으로 한국에서 데스크톱의 경우 각 브라우저의 점유율을 나타내주는 지표입니다.
위 지표를 보러가시려면 이 곳을 클릭하세요.
IE는 점유율이 지속적으로 낮아지고 있지만 아직까지도 전체 사용량의 약 20%를 차지할만큼의 비율을 보여주고 있습니다.
다시 말하자면, 어떤 서비스를 런칭할 때 20%의 비율은 절대 무시할 수 없는 큰 비율입니다.
따라서 반드시 고려해야하는 상황이죠.

position: sticky 의 브라우저 지원 현황

브라우저 지원 현황은 무난한 편입니다. 대신 위에서 언급한 것 처럼 IE 가 전혀 지원을 하지 않는 상황이네요.

Polyfill 구현

그렇다면 이 문제를 해결하는 방법은 아예 없는 걸까요? 그렇지는 않습니다.

 

1) 기존의 스펙 변경

이게 무슨 해결책이냐 할 수도 있지만 어떤면에선 가장 빠르고 확실한 해결책입니다.
문제가 되는건 IE 뿐인데, 이 브라우저만 제외하면 모든 브라우저에선 동작하죠.
position: sticky 는 지원하는 브라우저에서는 동작하지만 지원하지 않는 브라우저에서는 동작하지 않습니다.
만약에 현재 운영중인 어플리케이션을 이용하는 사용자의 IE 비율이 많이 낮거나 무시할정도가 된다면, 재협의를 통해 다시 스펙을 변경하는 것도 좋은 방법이라고 생각합니다.

 

2) StickyBits 라이브러리 사용하기

position: sticky 를 구현할 수 있도록 도와주는 라이브러리가 존재합니다. StickyBits 라고 부르는 라이브러리인데, 제법 유명한 라이브러리인 것 같습니다.
라이브러리 답게 여러가지 추가 기능이 붙어있으며 이슈 제기에도 제법 빠르게 답변해주는 편입니다.
그러나 저는 이 라이브러리를 사용하지 않았습니다.

 

3) 직접 구현하기

2번을 사용을 하지 않았던 이유는 사실 제가 사용했을 땐 IE 에서 여전히 동작하지 않았습니다.
왜 그런지는 코드 내부를 들여다보지 않아서 모르겠지만요.
해당 깃허브에 PR 을 보내 코드 수정을 요청하는 것도 하나의 방법입니다만,
코드 안정성 검사를 받아야하기 때문에 시간이 걸리죠.

사실 귀찮습니다.

우선 마크업이 다음과 같이 있다고 가정합시다.

여기에 적용할 코드는 다음과 같습니다. position: fixed; top: 0;
자바스크립트를 사용해 현재 스크롤의 위치에 따라 네비게이션을 고정하는 방식입니다.

네비게이션의 top 값을 가지고와서 window.pageYOffset 과 비교하면서 position: fixed 의 여부를 결정하는 로직이 메소드 안에 들어있습니다. 그런데 이런 방식은 문제점이 있습니다.

 

Position: fixed 방식의 문제점

이러한 방식은 문제점이 있습니다.
아래의 코드를 첨부하겠습니다.

See the Pen QPLzWy by Munkyu Yang (@moonformeli) on CodePen.

스크롤을 내리다보면 뭔가 이상합니다. 네비게이션이 상단에 고정이되서 붙어 다니긴하는데, 고정이 될 때
다른 글이 팍! 하고 위로 올라가는게 느껴지시나요?

position: fixed 로 요소가 더 이상 그 공간에 종속되지 않으면서 생기는 사이드 이펙트입니다.
그럼 네비게이션 부분만큼이 빠지니까 당연히 그 아래의 컨텐츠들이 위로 올라가는거죠.

이 부분을 고정해줄 무언가가 필요합니다.

사이드 이펙트 해결

position: fixed 로 빠진 부분을 어떻게 채울 수 있을까요.
해결 방법은 똑같은 요소를 만들어서 대신 넣는다 입니다.

cloneNode 의 옵션값을 true 로 넣어주면 자식 요소들까지 복제가 됩니다. cloneNode API 보러가기
자식들까지 복제하는 이유는 자식 요소가 없으면 요소를 복제한다해도 height 값이 0 이기 때문입니다.

네비게이션을 고정할 때 복제한 요소를 넣어주고, 고정을 해제할 때 복제한 요소를 제거하는 방식으로하면 IE 에서도 부드럽게 구현됩니다.

구현 결과는 다음과 같습니다.

See the Pen rbBodd by Munkyu Yang (@moonformeli) on CodePen.

부드럽게 동작하네요!

codepen 은 IE 에서 동작하지 않습니다. 테스트를 원하신다면 아래의 코드를 복사해서 직접 테스트하시기 바랍니다

아래는 각 작업환경에 맞는 버전별 폴리필입니다. 필요하신 부분을 참고하시면 될 것 같네요.

 

ES6

 

ES5 + jQuery

 

HTML + CSS

...더보기

더 보기

참고가 되셨으면 좋겠습니다!

+ Recent posts