
스크롤을 내리면 사이드바가 위에 그대로 멈춰 있고, 독자는 본문만 읽으면서 사이드바는 이미 저 위 어딘가로 사라져 버린다. 티스토리 블로그 기본 레이아웃에서 자주 있는 상황이다. 사이드바에 광고를 넣어뒀는데 독자가 스크롤을 내리는 순간 광고는 안 보이고, 본문만 보이는 구조. 이게 얼마나 비효율적인지 처음엔 몰랐다.
낚시로 비유하면 이런 거다. 미끼를 달아서 물속에 내려뒀는데, 물고기가 다가오는 순간 낚싯줄을 올려버리는 것과 같다. 독자가 글을 읽으러 왔는데 광고가 이미 위로 올라가버려서 노출 기회를 날리는 것. sticky는 그 낚싯줄을 물속에 계속 유지하는 방법이다.
사이드바에 광고를 달아놨는데 클릭이 거의 없다면, 한 번쯤 직접 내 블로그를 독자 입장에서 읽어봐야 한다. 나도 그랬다. 스크롤을 조금만 내리니 사이드바 광고가 화면에서 사라져버렸고, 그 순간 왜 수익이 제자리인지 바로 이해됐다. position: sticky 한 줄이 그 문제를 해결해줬지만, 거기까지 가는 길이 생각보다 험했다.
sticky 적용법과 동작 원리, 제대로 알고 쓰기
혹시 position: fixed를 쓰다가 사이드바가 화면 전체에 달라붙어 버린 경험이 있는가. 나는 그 경험을 먼저 하고 나서 sticky를 찾게 됐다. position: fixed는 뷰포트 기준으로 요소를 고정한다. 뷰포트란 브라우저 화면에서 실제로 보이는 영역을 말하는데, fixed를 쓰면 스크롤 위치나 부모 요소와 무관하게 화면 어딘가에 항상 고정된다. 그게 내가 원하는 게 아니었다. 사이드바가 본문 영역을 벗어나도 계속 따라다니면 레이아웃이 망가진다.
반면 position: sticky는 부모 요소의 범위 안에서만 따라온다. 사이드바가 있는 영역을 벗어나면 고정이 풀리기 때문에, 레이아웃을 망가뜨리지 않으면서도 스크롤을 따라오게 만들 수 있다. fixed와 sticky의 차이가 처음엔 말로는 이해가 됐는데, 직접 써보기 전까진 진짜로 체감이 안 됐다. 두 가지 모두 직접 구현해보고 나서야 어느 상황에 어느 것이 맞는지 몸으로 알게 됐다.
sticky를 적용할 때 반드시 알아야 할 것이 있다. top 값을 지정하지 않으면 아무 일도 일어나지 않는다. 나도 처음에 position: sticky만 넣고 왜 안 되지 하고 한참 헤맸다. top: 80px처럼 스크롤됐을 때 어느 위치에서 고정될지를 명시해줘야 비로소 동작한다. 이 사실을 모르면 sticky가 안 된다고 포기하게 된다. 나도 한 시간쯤 헤매다 포기할 뻔했다.
그다음 함정은 flex 컨테이너 안에서 sticky를 쓸 때다. flex 컨테이너란 display: flex가 적용된 부모 요소를 말한다. 이 안에서는 자식 요소가 기본적으로 부모의 전체 높이에 맞춰 늘어난다. 사이드바가 본문 영역 높이만큼 죽 늘어나버리면, sticky는 고정될 여지가 없어진다. 이때 사이드바에 align-self: flex-start를 추가해야 한다. align-self란 flex 자식 요소가 교차축 방향으로 어떻게 정렬될지를 개별적으로 지정하는 속성으로, flex-start를 주면 콘텐츠 높이만큼만 차지하게 된다. 내가 두 번째로 삽질한 지점이 바로 여기였다. 왜 안 되는지 몰라서 sticky 관련 글을 열 개는 읽은 것 같다.
sticky가 작동하지 않는 주요 원인은 크게 세 가지다. 부모 요소에 overflow: hidden 또는 overflow: auto가 설정된 경우, 부모 요소의 높이가 sticky 요소보다 충분히 크지 않은 경우, top, bottom, left, right 중 하나도 지정하지 않은 경우다. 나는 이 세 가지 중 첫 번째에 정확히 걸렸다. overflow: hidden이란 부모 요소의 경계를 벗어나는 콘텐츠를 잘라내는 속성인데, 이 값이 있으면 브라우저가 sticky의 스크롤 기준을 제대로 계산하지 못한다. 해당 overflow 설정을 제거했더니 sticky가 바로 작동했다. 코드 한 줄을 지웠을 뿐인데 사이드바가 스크롤을 따라 움직이기 시작했을 때의 그 허무함이란. 원인을 몰랐을 때는 몇 시간씩 헤맸는데 알고 나니 10초면 해결이었으니까.
광고 수익과 독자 경험, 둘 다 챙기려면
sticky 사이드바가 수익에 실제로 영향을 미치는지 궁금한 분들이 많을 것이다. 내가 직접 써봤는데, 적용 후 한 달간 사이드바 광고의 클릭 수가 체감상 늘었고 RPM도 소폭 올랐다. RPM이란 페이지 1,000회 노출당 예상 수익을 나타내는 지표로, 광고가 실제로 독자 눈에 얼마나 노출되는지와 밀접한 관계가 있다. 노출이 없으면 클릭도 없고, 클릭이 없으면 수익도 없다는 당연한 사실을 sticky를 달고 나서야 제대로 실감했다.
비유를 들자면 이렇다. 사이드바에 광고를 올려두고 sticky 없이 운영하는 건, 슈퍼마켓 입구에만 간판을 달아놓고 매장 안에는 아무 안내도 없는 것과 같다. 손님이 안으로 들어오는 순간 간판은 이미 보이지 않는다. sticky는 그 간판을 손님 옆에서 함께 이동하게 만드는 방식이다.
단, 여기서 한 가지 짚고 넘어가야 한다. Google AdSense 정책에서는 광고가 화면을 지나치게 많이 차지하거나 콘텐츠를 방해하는 방식으로 고정되는 것을 금지하고 있다. sticky 사이드바 광고 자체가 금지된 것은 아니지만, 광고가 콘텐츠보다 더 눈에 띄는 구조가 되면 정책 위반 소지가 생기고, 독자 신뢰도도 함께 떨어진다. 내 경험상 이 지점을 간과하는 블로그들이 꽤 많다. 수익을 높이려다 독자를 잃는 결과가 나오면 장기적으로는 손해다.
모바일 환경에서도 주의가 필요하다. 사이드바를 모바일에서도 sticky로 유지하면 화면의 절반 가까이를 광고가 차지하는 경우가 생긴다. 미디어 쿼리를 활용해 특정 화면 너비 이하에서는 sticky를 해제하는 처리가 필수다. 미디어 쿼리란 화면 크기, 해상도 등 조건에 따라 CSS를 다르게 적용하는 방법으로, 반응형 웹 디자인의 핵심 기술이다. MDN Web Docs에서도 sticky 위치 지정 속성은 스크롤 컨테이너와 뷰포트 크기에 따라 동작이 달라질 수 있다고 명시하고 있다. 직접 모바일로 확인하지 않으면 이 문제는 대부분 발견하지 못한 채 지나간다.
sticky 사이드바 하나를 제대로 구현하기까지 overflow: hidden 제거, align-self: flex-start 추가, top 값 지정, 모바일 미디어 쿼리 처리까지 총 네 번의 수정이 필요했다. 두 번 삽질하고 나서야 완성됐지만, 덕분에 각 속성이 왜 필요한지 몸으로 익혔다. 처음부터 잘 됐다면 이 중 절반은 이해 없이 그냥 붙여넣고 끝났을 것이다.
sticky 하나를 제대로 설정하고 나서 느낀 건, 블로그 운영은 글 잘 쓰는 것 이상으로 구조를 잘 설계하는 게 중요하다는 점이다. 광고 수익을 높이고 싶다면 sticky 적용은 분명히 시도해볼 만하다. 다만 독자가 글을 끝까지 읽고 싶은 환경을 먼저 만드는 것, 그게 장기적으로 더 이익이라는 게 지금 내 판단이다. 수익을 목적으로 sticky를 붙이되, 독자 경험이 망가지지 않는 선을 지키는 것. 그 균형을 찾는 게 결국 블로그 설계의 본질이다. 적용 전에 직접 내 블로그를 독자처럼 한 번 읽어보는 것, 그게 가장 정직한 점검이다.
참고
- MDN Web Docs – position: sticky
- CSS-Tricks – Sticky Positioning
- web.dev – Avoid non-composited animations
- Google AdSense – 고정 광고 정책