인스타그램에서 스크롤 해도 고정된 위치를 갖는 "회원님을 위한 추천" 부분을 구현해보고자 한다.
처음에는 고정위치이기 때문에 단순하게 position fixed로 접근을 했지만 이 구조는 조금 다른 구조를 가지고 있었다. .main-right
부분이 화면 전체에서 독자적으로 고정된 위치를 갖는 것이 아니라 main
안에서 .feeds
와 함께 가운데 정렬이 됨과 동시에 스크롤 시에만 고정위치를 갖고 있다.
이런 상황에서 position fixed를 사용하면 안되는 것은 아니지만 브라우저 크기가 변할 때마다 .main-right
의 left
값을 동적으로 바꿔주어야 한다. (실제 인스타그램에서 이런 방법을 쓰는 것 같았다.)
하지만 position: sticky 를 사용하면 보다 간단하게, css 만으로 같은 레이아웃을 구현할 수 있다.
<main>
<secton class="feeds">
...
</<section>
<div class="main-right">
...
</div>
</main>
main {
display: flex;
justify-content: center;
padding-top: 30px;
}
.feeds {
width: 100%;
max-width: 610px;
}
.main-right {
position: sticky;
top: 84px;
margin-left: 30px;
width: 100%;
max-width: 295px;
height: 0;
}
하지만 position : sticky를 줘도 스크롤 했을 때 고정되지 않았다. 이 때 .main-right { height: 0 }
을 지정했더니 그제서야 잘 적용되는 것을 볼 수 있었다.
sticky 속성을 가진 요소는 처음에는 원래의 위치(relative 일 때의 위치)에 있다가 스크롤 했을 때 정해진 좌표값을 만나면 더이상 움직이지 않고 그 좌표값에서 고정된 위치를 갖는다. 단 이런 속성은 부모 요소의 크기 안에서만 제한된다.
그래서 position : sticky 를 사용할 때 주의할 점이 있다.
justify-content 속성을 사용하면 손쉽게 정렬을 할 수 있지만 간혹 여러 flex item 중에 하나만 오른쪽 정렬을 한다거나 하나만 왼쪽 정렬을 해야하는 경우가 있다. 그럴 때 한 가지 정렬이 다른 요소때문에 나머지 요소를 div로 감싸지 않아도 1~2개의 요소만 다르게 정렬시키는 방법이 있다.
정렬해야하는 요소가
{ margin-right : auto }
{ margin : 0 auto }
{ margin-left : auto }
이는 수직정렬에도 똑같이 적용된다. (margin-top
, margin-bottom
를 사용)
<div class="flex-container">
<div></div>
<div></div>
<div></div>
<div class="align-right"></div>
</div>
.flex-container {
display: flex;
align-items: center;
}
.align-right {
margin-left: auto;
}
stackoverflow | 'position: sticky' not working when 'height' is defined
NAVER D2 | flexbox로 만들 수 있는 10가지 레이아웃