2021. 10. 19. 18:21ㆍ프론트엔드/HTML, CSS, Javascript
내가 최근에 만들고 있는 페이지인데, 중앙의 리스트만 스크롤하고 싶었다.
그래서 이렇게 저렇게 찾아서 땜빵을 해보는데 잘 안 되서 그냥 근본적으로 접근해보자고 생각했다.
Flex Container
Flex를 쓰기 위해선 컨텐츠들을 담는 컨테이너가 필요하다.
이 컨테이너 역할을 하는 div는 두가지 특성을 설정해주면 된다.
- display: flex;
- flex-direction: row;
display: flex;를 통해 이 div의 하위 컨텐츠는 flex 방식으로 처리하겠다는것을 알리고,
flex-direction을 통해서 flex를 진행하는 방향을 알려준다.
flex-direction의 종류는 다음을 보자.
https://developer.mozilla.org/ko/docs/Web/CSS/flex-direction
Flex Content
이제 컨텐츠들을 설정할 때다.
컨텐츠는 다음의 옵션으로 설정한다.
- flex: 0 1 auto;
이 flex는 세가지 옵션의 축약어인데, 각각 flex-grow, flex-shrink, flex-basis이다.
즉 0 1 auto;란, flex-grow: 0; flex-shrink: 1; flex-basis: auto;와 같다.
기본 값은 위처럼 0 1 auto;이다.
https://developer.mozilla.org/ko/docs/Web/CSS/flex
자세한건 위의 링크를 보고, 간단한 사용법을 익혀보자.
우선 화면을 몇 대 몇으로 나눌지 생각해 봐야한다.
만약 내가 세개를 1:2:1로 화면을 분할하고 싶다면, 다음과 같이 설정하면 된다.
<div style="display: flex;">
<div style="flex: 1;" />
<div style="flex: 2;" />
<div style="flex: 1;" />
</div>
실전
이제 내가 쓰는 페이지를 구성해보자.
여기에 필요한 요소는 다음과 같다.
- 고정 높이를 가진 App Bar (파란색 바탕 영역)
- 아래 전체 영역이 화면을 꽉 채워야 함
- 하단 영역은 좌, 우로 나뉘어야 함
- 좌측 영역은 스크롤이 되어야 함
고정 높이를 가지는 Content
우선 상, 하단으로 분리해야 한다. 해보자.
(html, body는 height: 100%; margin: 0;으로 설정하자)
<div class='column-container'>
<div class='column1'>먼저 해야하는 걸 보여줘, Worky</div>
<div class='column2'></div>
</div>
.column-container {
display: flex;
height: 100%;
flex-direction: column;
background-color: olive;
}
.column1 {
flex: 0 1 64px;
background-color: orange;
}
.column2 {
flex: 1;
background-color: orangered;
}
html의 구조는
컨테이너(.column-container)안에 두 컨텐츠(.column1, .column2)가 있다.
CSS는 우선 중요한 부분만 뽑아서 보자
.column-container {
display: flex;
height: 100%;
flex-direction: column;
}
.column1 {
flex: 0 1 64px;
}
.column2 {
flex: 1 1 auto;
}
우선 container는 높이는 화면 전체, display: flex; 방향은 column(세로)로 설정하였다.
column1이 중요한데, 세번째 속성(flex-basis)가 64px로 설정되었다.
즉, 이 컨텐츠의 기본 사이즈는 64px로 설정이 된다.
그러면서 첫번째 속성(flex-grow)가 0이기 때문에, 비율적으로 늘어나지도 않는다.
column2는 첫번째 속성(flex-grow)가 1이기 때문에,
다른 flex-grow를 가진 컨텐츠가 없기 때문에 1/1, 즉 100%가 된다.
실제 출력 화면은 이렇다.
보다시피 상단 64px를 제외하고는 나머지가 전부 column2의 영역이 된 것을 알 수 있다.
하단 영역 가로로 쪼개기
이제 하단 영역 (column2)를 가로로 쪼개보자.
<div class='column-container'>
<div class='column1'>먼저 해야하는 걸 보여줘, Worky</div>
<div class='column2'>
<div class='row-container'>
<div class='row1'></div>
<div class='row2'></div>
</div>
</div>
</div>
... 기존 CSS 코드
.row-container {
display: flex;
height: 100%;
flex-direction: row;
background-color: orchid;
}
.row1 {
flex: 1;
background-color: palegreen;
}
.row2 {
flex: 3;
background-color: red;
}
세로 쪼개기와 구조가 거의 같다.
flex-direction은 row가 되었고, row1과 2는 1:3이 된 것만 체크하면 되겠다.
실제 화면은 이렇게 된다. 초록(row1)과 빨강(row2)가 1:3의 비율로 분할됨을 알 수 있다.
좌측 영역(초록)에 스크롤 넣기
우선 스크롤을 만들기 위해 다음과 같이 만들어주자
<div class='column-container'>
<div class='column1'>먼저 해야하는 걸 보여줘, Worky</div>
<div class='column2'>
<div class='row-container'>
<div class='row1'>
<div class='list-container'>
<div>li</div>
... 스크롤이 생길때까지 (<div>li</div>)를 복붙해주세요
<div>li</div>
</div>
</div>
<div class='row2'></div>
</div>
</div>
</div>
우선 list-container를 새로 만들어 감싸고, 안에 div를 오지게 넣었다.
자, 이제 스크롤이 생겼지만 전체 페이지에 걸쳐 생기게 되었다.
그리고 별개로 주황영역 (column1)의 영역도 망가졌다.
그 이유는, flex가 처리를 할 때 아랫 영역이 화면보다 길어지면서 주황 영역을 밀어냈기 때문이다.
flex-shrink를 0으로 설정하여 처리할 수 있지만, 다른 방식으로 해보겠다.
왼쪽 영역에만 스크롤이 될 수 있도록 CSS를 적용해주자.
... 기존 CSS 코드
.row1 {
display: table;
height: 100%;
}
.list-container {
height: 100%;
overflow-y: auto;
}
'갑자기 왜 table이 나오지?' 라고 의문이 들 수 있는데, 나도 정확히는 모른다.
하지만 원리를 알아보면 .row를 table로 만들어서 높이를 고정한 다음,
list-container가 범위를 벗어나는 컴포넌트를 스크롤로 만든다.
실제 결과물이다.
마무리
사실 왜 display를 table로 설정하면 높이가 고정되는지에 대한 원리를 나도 잘 모르겠다.
열심히 찾아봤지만 Document에서도 내부 원리를 설명하지 않는다.
다른 방식으로 시도를 해봤지만 해결이 되진 않았다.
물론 브라우저를 뜯어보면 되겠지만 당장은 프로젝트에 집중하기로 했다.
다소 아쉽다.
'프론트엔드 > HTML, CSS, Javascript' 카테고리의 다른 글
Javascript Prototype 오염 (0) | 2022.04.21 |
---|---|
브라우저 객체 모델 - BOM (0) | 2022.04.21 |
[HTML] 글자 사이에 원하는 길이만큼 공백 넣기 (feat. React) (0) | 2022.02.08 |
JS, HTML 복습 (메모용) (0) | 2021.08.09 |
DOM이란 무엇인가 (0) | 2021.07.11 |