CSS 레이아웃 분할과 Flexbox

teo.yu·2021년 12월 19일
37

입문 + CSS

목록 보기
5/8
post-thumbnail

사이트 전체 레이아웃 잡는 방법이 여러가지가 있을텐데 빨리빨리 되지가 않더라고요 많은 연습이 있어야겠지만 flexgrid 사용해서 어떻게 전반적인 레이아웃 잡으시는지 궁금해요 css 각각의 속성 어떤건지는 대강 아는데 효과적으로 사이트 만드는 건 또 다른 이야기인거 같아서... 어떻게 보면 그리드 시스템?에 대한 궁금증일 수도 있을거 같습니다만 너무 구체적인 활용예가 궁금한거 같기도 하네요...ㅎ

블로그에 글을 이어갈 수 있도록 좋은 질문을 해주신 분께 너무 감사드립니다.

프롤로그

글을 쓰다 보니 이 하나의 질문을 대답하기에 너무 많은 얘기들을 해야 했습니다.

특히 CSS Grid에 대해서는 빌드업을 해야할 얘기가 워낙 많았기 때문에 Flex vs Grid의 글을 쓰다가 멈칫해둔 상태입니다.

문의를 해주신 뒤로 시간이 계속 흘러가고 있고 블로그 글을 계속 미루는게 스스로에게 좀 불편했기에,

CSS Grid Layout에 대한 이야기는 따로 크게 정리하는 시간을 가져보기로 했고, 그 글에서 Grid System까지 같이 풀어보도록 하겠습니다.

그래서 이번 글의 목차는 다음과 같습니다.

1. 사이트 전체 레이아웃 잡는 방법
2. Grid Layout을 알아보고 Flex layout과 Grid Layout의 차이와 어떨때 어느 것을 쓰면 좋은지?
3. 그리드 시스템이란 무엇인가? 이며 CSS에서는 어떻게 사용하는가

나머지 파트는 다른 글로 찾아뵙겠습니다!

사이트 전체 레이아웃 잡는 방법

사이트 전체 레이아웃을 잡는 방법에 대한 방법과 빨리빨리 연습할 수 있는 방법 그리고 전반적인 레이아웃에 대한 개념에 알아보도록 하겠습니다.

여러가지 레이아웃들을 어떻게 만들까?

레이아웃의 기본은 분할! 선긋기, 자르기, 그리고 Flexbox!

그리고 다음과 같은 규칙을 머리속에 기억해두고 종이를 꺼내들고 네모를 그린뒤에 적당히 선을 한번 그어 보면서 이미지를 그려봅시다.

  1. 선은 처음부터 끝까지 그어야 합니다. 그래서 완전히 2개의 영역으로 구분이 되도록 하세요.
  2. 같은 방향의 선은 몇번이고 그을 수 있지만 다른 방향의 선은 안됩니다.

영역이 2개 이상으로 분리가 되면 진행방향 이라는 것이 생깁니다. 진행방향은 선의 방향과 반대의 방향입니다.

이렇게 분리된 영역을 컨텐트(Content) 그리고 이 컨텐츠를 묶어주는 것을 컨테이너(Container) 라고 부르며 진행방향은 컨테이너가 결정하게 됩니다.

처음으로 익혀야할 부분은 이 이 분할과 HTML코드를 이미지로 비슷하게 생각하는 일입니다.

<style>
.vbox {
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.vbox > * { outline: 1px solid #4f80ff; } /* 이렇게 가이드 선을 그어둘 수 있게 하면 좋다. */
</style>
  
<div class="vbox"> <!-- Container -->
  <div>1</div> <!-- Content -->
  <div>2</div> <!-- Content -->
</div>

<section class="vbox"> <!-- 헷갈리면 Container Tag명을 div 대신 section을 써보세요. -->
  <div>1</div>
  <div>2</div>
  <div>3</div>
</section>

세로로 선 긋기 = 가로 방향

HTML은 항상 세로로 작성되므로 가로형 컨텐츠에 대해서는 조금 더 생각이 필요합니다.

그리고 레이아웃에 원칙을 하나 더 추가를 하려고 합니다.

  1. 거의 대부분 컨텐츠 중 하나Flexible하다.

아닐경우도 있지만 레이아웃의 경우 반응형을 고려해야 하므로 거의 대부분 나머지 공간의 크기를 모두 받아줄 하나 이상의 메인컨텐츠가가 있기 때문에,

컨텐츠의 크기가

1) 고정 크기인지
2) 컨텐츠를 따라가는지 아니면
3) 남는 공간을 모두 채우는 flex인지를 생각해봅시다.

<style>
.hbox {
  display: flex;
  flex-direction: row;
  align-items: stretch; /* 큰 레이아웃을 잡을 때에는 stretch가 더 편할 거에요. */
}
.flex { flex: 1 }
.guide > * { outline: 1px solid #4f80ff; } /* 아예 guide class를 만들어둬도 좋다! */
</style>
  
<div class="hbox guide"> <!-- Container -->
  <div flex>1</div> <!-- Content -->
  <div flex>2</div> <!-- Content -->
</div>

<section class="hbox guide">
  <div style="width:100px">1</div>
  <div flex>2</div>
</section>

<section class="hbox guide">
  <div flex>1</div>
  <div flex>2</div>
  <div flex>3</div>
</section>

자르기

저도 그런것들은 기초시간에 이미 다 배웠어요. 그정도는 쉽죠! 저는 이런것들을 만들고 싶은거라구요.

두번째로 생각해야 할 것은 복합적인 컨텐츠가 만들어질때의 영역을 나누는 방법입니다. 방법은 간단합니다.

가위로 이 선을 자른다고 생각할때 둘로 반드시 나뉘는 것을 먼저 자르면 됩니다.

이 것들을 한데 모아 조립을 하기 위해서는 제일 큰데부터 안으로 들어가는 Top-Down 방식제일 잘게 잘린 조각들로 부터 올라오는 Bottom-up 방식이 있습니다. 물론 중간부터 하셔도 아무 상관없고 레이아웃과 HTML의 형태를 같이 그릴 수 있는 본인만의 편한 방법을 찾아보세요.

<div class="hbox">
  <div>1</div>
  <div>2</div>
  <div class="vbox">
    <div>3</div>
    <div>4</div>
    <div class="hbox">
      <div>5</div>
      <div>6</div> 
    </div>
  </div>
</div>

어때요? 참 쉽죠?

죄송합니다... 😚

개념 설명을 위해서 align-items, justify-content, flex, padding, gap등 핵심요소는 포함시키지 못했습니다. 자료를 만들기가 너무 어렵네요ㅠㅠ

레이아웃 분할에 대한 이미지만 명확히 가져가 주신다면 감사하겠습니다!

CSS 공부 어떻게 해야 하나요? - 이론편 (feat. figma) 을 보고서 flexbox의 나머지 역할들도 다시 한번 상기해주세요.

분할은 내가 해봐야 는다.

뭐 하지만 다들 이걸 모르시겠습니까? 정작 디자인으로 받고 나면 막막해지는 거죠. 특히 현대 웹 디자인의 정석인 Flat Design은 border등을 잘 안쓰는 편이라 어디를 잘라서 나눠야 가늠하기가 어렵습니다.

이것도 자료 만들기 힘들어서 그냥 개발자 도구에서 + 기호 눌러서 전부 outline을 그리는 꼼수를 부렸습니다. 😢 하지만 이 방식을 쓰게 되면 어떤식으로 박스가 구성되어 있는지 시각적으로 참고하기 좋습니다. 👍

일부러 복잡한 예시를 좀 가져왔는데 처음에는 간단하게 늘려나가면 좋습니다. 레이아웃을 분할할 때에는 이러한 원칙이 있습니다.

  1. 선을 다른 영역을 침범하게 긋지 않는다!
  2. 의미론적으로 다른 성격의 것들이 섞이지 않게 잘라야 한다.

세로가 먼저일까? 가로가 먼저일까?


컨텐츠의 구조가 어떻게 확장되고 어떻게 그룹이 되는냐에 따라 같은 분할이라도 순서가 다르다. 지금 예시에서는 세로 -> 가로의 형태가 더 적절하다.

연습하는 법

연습할때는 유틸리티 클래스나 inline-style를 남발해도 좋으니 디자인을 보고 적절한 HTML의 구조를 바로 직관적으로 떠올릴수 있도록 연습해봅시다.

<style>
*{margin:0;padding:0;box-sizing:border-box}
.guide, .guide > * { outline:1px solid #4f80ff;}
.hbox{display:flex;flex-flow:row;align-items:center;}
.vbox{display:flex;flex-flow:column;align-items:stretch;}
.pack{display:flex;align-items:center;justify-content:center;}
.flex{flex:1}
.space-between{justify-content:space-between;}

*{outline: 1px solid #4f80ff;}
html,body{height:100%}
div{padding: 20px}
</style>

<div class="hbox">
  <div>1</div>
  <div>2</div>
  <div class="flex vbox">
    <div class="flex">3</div>
    <div class="flex">4</div>
    <div class="hbox">
      <div class="flex">5</div>
      <div class="flex">6</div> 
    </div>
  </div>
</div>

유틸리티 클래스는 홍보겸 제가 사용하는 AdorableCSS의 문법에서 가져왔지만 본인이 직접 유틸리티 CSS를 만들어보시는 것이 더 좋아요!

.row { display:flex; flex-flow: row }
.column { display:flex; flex-flow: column }
...

Flex? Grid? 더 효과적인 방법은?

레이아웃의 대부분의 경우는 Flexbox가 더 좋습니다. Grid의 경우 레이아웃이 확정이 되지 않으면 만들기가 어려워서 처음부터 Grid로 레이아웃을 잡고 가면 경직된 구조가 만들어지기 때문에 특히 수정이 잦은 경우에는 좋지 않습니다. 하지만 일단 Grid 세팅이 되고 난 다음의 반응형 처리라던가 Grid로 했을때 훨씬 더 좋은 구조들이 존재하니 Flexbox로 먼저 하고 Grid가 더 유리한 곳에는 Grid를 쓰면 좋을 것 같아요. 자세한 얘기는 꼭 다음번 포스트에 작성할 예정입니다!

다음번 포스트 예고:

  • FlexGrid를 언제 사용하면 좋은가? 각 레이아웃의 특징으로 알아보는 실전 레이아웃
  • Grid System이란 무엇이고 CSS로는 어떻게 구현하는가?

끝으로...

아... 어느 정도의 수준인지를 모르니 강의나 연습용 컨텐츠를 만든다는 것이 정말 어렵네요. 😢 그리고 설명보다 자료를 만드는 게 정말 쉬운일이 아니라는 것을 깨닫습니다.

자자 그래도 확실히 할 것 해두겠습니다. 일단 이것은 강의도 아니고 검증된 효과적인 연습법도 아닙니다(!). CSS를 하다보면 분할이니 선긋기니 이런것들 없이 종국에는 바로바로 직관적으로 생각이 나게 됩니다.

이 글을 통해서 전달하고자 했던 바는,

  1. 디자인을 어떻게 레이아웃으로 분할을 하는지 (는 알려주지 않았지만 2번을 통해서 감각을 익히시길 바라며)
  2. 분할된 레이아웃과 HTML과 Flexbox 개념의 시각화

이 2번에 대한 것을 이해하는데 있어서 도움이 되기를 바랍니다.

질문을 해주신 분께 이번에는 적절한 답이 되지 되었을지 모르겠네요.
CSS GridGrid System은 정보를 기반으로 하는 포스트가 될거라서 조금 더 잘 작성할 수 있을 것 같아요.

아무쪼록 이 글이 도움이 되었으면 좋겠습니다.

감사합니다.
좋은 하루 되세요 🥰

profile
AdorableCSS를 개발하고 있는 시니어 프론트엔드 개발자입니다. 궁금한 점이 있다면 아래 홈페이지 버튼을 클릭해서 언제든지 오픈채팅에 글 남겨주시면 즐겁게 답변드리고 있습니다.

3개의 댓글

comment-user-thumbnail
2022년 3월 31일

이것은 좋은 기사, 좋은 아이디어입니다
https://wordlesolver.onl/
https://tinyfishing.online/

답글 달기
comment-user-thumbnail
2023년 7월 1일

컨텐츠의 구조가 어떻게 확장되고 어떻게 그룹이 되는냐에 따라 같은 분할이라도 순서가 다르다. 지금 예시에서는 세로 -> 가로의 형태가 더 적절하다.

왜요? 전 가로 세로를 생각했었거든요. 저... 혹시 왜 그런지 알 수 있을까요?

1개의 답글