도움말 - 글감 수집하기 (인용)

도움말 - 부분 리뷰 작성하기

4 - Flexbox 이해: 당신이 알아야 할 모든 것 (Understanding Flexbox: Everything you need to know)

이전 글:



이 글은 Ohans Emmanuel의 Understanding Flexbox: Everything you need to know을 번역한 글 중 Building a Music App Layout with Flexbox 부분부터 마지막까지 번역한 글 입니다. 이전 내용을 번역한 글은 위의 링크를 확인 하시면 됩니다.

Flexbox로 음악 앱 레이아웃 만들기


지루한 이론을 마쳤으니, 재미있는 프로젝트를 만들어 보자.

새로 습득한 Flexbox 기술을 적용 할 때이다.

어떤 프로젝트를 만들면 좋을까 하다 고양이를 위한 음악 앱 레이아웃을 만들어 보는게 좋을것 같다고 생각했다.

나는 이것을 Catty Music이라고 부른다.

완성 된 레이아웃은 다음과 같다. Flexbox로 완전히 레이아웃되었다.


여기에서 온라인으로 볼 수 있다.

모바일에서 볼 경우 약간 다른 모습일 것이다. 이것에 대해서는 이 글의 반응형(responsive) 디자인 섹션에서 다룰 것이다.

나는 사실 많은 사람들이 문제가 있다고 여기는 것을 했다.

그것은 Flexbox로 전체 레이아웃을 완성했다는 것이다.

여러 가지 이유로 이렇게 하는 것은 이상적이지 않을 수 있다. 그러나 이 프로젝트에서는 의도적이었음을 밝힌다. Flexbox로 가능한 모든 작업을 단일 프로젝트 내에서 사용하는 것을 보여주기 위해서였다.

Flexbox 모델을 사용하는 것이 옳은지 아닌지에 대해 궁금한 점이 있다면 내 글을 참고 하자.


Catty Music의 모든 기능은 Flexbox 모델을 사용하였다. 이는 Flexbox로 어떤것이 가능한지 보여주기위한 의도가 포함되어있다.

그럼 이제 시작해보자!

Catty Music 레이아웃을 만드는 계획을 세워보도록 하자.

어디서부터 시작해야 될까?

Flexbox로 레이아웃을 만들기전에 레이아웃의 어떤 부분이 플렉스 컨테이너(flex-containers)가 되어야 할지 생각해봐야 한다.

그런 다음 Flexbox의 강력한 정렬 속성을 활용할 수 있다.

분리(The Breakdown)

전체 컨테이너 바디를 플렉스 컨테이너 (아래 이미지의 빨간색 테두리에 포함)로 배치하고 레이아웃의 다른 섹션을 플렉스 아이템 (item 1과 2)으로 나눌 수 있다.


item 1에는 음악 컨트롤 버튼이 포함 된 섹션인 "푸터(footer)" 이외의 레이아웃의 모든 부분이 포함되어 있기 때문에 전적으로 이해가 되는 부분이다.

플렉스 아이템 역시 플렉스 컨테이너로 변경 할 수 있다는 것을 알고 있었는가?

그렇다, 가능하다!

원하는만큼 중첩시킬 수 있다 (합리적인 수준의 레벨을 유지하는 선안에서).

item 1 (첫 번째 플렉스 아이템)은 플렉스 컨테이너로 만들 수도 있다.

사이드바 (item 1b)와 메인 섹션 (item 1a)은 플렉스 아이템이 된다.


이렇게 레이아웃을 분리하면 정말 좋은 멘탈 모델(mental model)을 얻게 된다.

Flexbox 모델로 더욱 복잡한 레이아웃을 만들게 된다면 이것이 얼마나 중요한지 알 수 있다.

위의 이미지처럼 멋진 이미지는 필요 없다. 간단한 종이로 스케치 해보는 것 정도면 충분하다.

원하는만큼 중첩하여 플렉스 컨테이너를 선언 할 수 있다고 얘기한 것을 기억하는가? 여기에 한번더 중첩해서 사용해도 문제가 되지 않는다.

위의 주요 섹션 (item 1a)을 살펴보자.

또한 아래에 하이라이트된 섹션을 플렉스 컨테이너로 만들 수도 있다. "item 1a - A" 및 "item 1a - B"


메인 섹션 (item 1a)에 플렉스 컨테이너를 만들지 않고 하이라이트된 섹션을 위해 두 개의 "div"를 넣을 수도 있다.

그렇다. "item 1a-A"와 "item 1a-B"가 수직으로 쌓여 있기 때문에 가능하다.

기본적으로 "divs"는 세로로 쌓인다. 박스 모델(box model)이 작동하는 방식이다.

메인 섹션을 플렉스 컨테이너로 만들면 강력한 정렬 속성을 사용 할 수 있다.

Flexbox의 "flex"은 유연함(flexible)을 의미한다.

플렉스 컨테이너는 기본적으로 유연하고 일종의 반응형이다.

이것은 일반 "div" 대신 플렉스 컨테이너를 사용하는 또 다른 이유 일 수 있다. 시나리오에 따라 다르긴 하지만 말이다.

Katty Music을 만들면서 다른 것들도 간단히 다루도록 하겠다. 이제 몇 가지 코드를 작성해야한다.

기본 HTML 세팅

아래에 HTML부터 시작하자.

<!DOCTYPE html>
<html>
<head>
<title>Catty Music</title>
</head>
<body>
<main></main> <!--to contain the main section of the app-->
<footer></footer> <!--to contain the music control buttons and song details-->
</body>
</html>

기본 스타일:

html,
body {
height: 100%; /*setting this explicitly is important*/
}
body {
display: flex; /*flex superpowers activated! */
flex-direction: column; /*Stack the flex-items (main and footer elements) vertically NOT horizontally*/
}

Flexbox 모델을 사용하기위한 첫 번째 단계는 플렉스 컨테이너를 설정하는 것이다.

위의 코드와 정확히 같다. body 엘리먼트의 display 속성을 flex로 설정한다.

이제 body 엘리먼트가 플렉스 컨테이너가 됐다.

플렉스 아이템도 정의되어 있다 (item 1item 2) - 이전에 완료된.

이 개념이 여전히 이해가 되지 않는다면 초기 분리(initial breakdown) 단계에서 보여준 이미지를 다시 한 번 보는 것이 좋다.

푸터가 맨 아래에 고정되도록 한다

음악 컨트롤이있는 푸터는 페이지 하단에 붙어 있지만 메인 섹션은 나머지 공간을 채우도록 한다.

어떻게 해야할까?

main {
flex: 1 0 auto; /*fill the available space*/
}
footer {
flex: 0 0 90px; /*don't grow or shrink - just stay at a height of 90px.*/
}

위 코드의 주석을 참조하자.

메인 섹션의 전체 공간을 채우는 것은 flex-grow 속성을 사용하면 상대적으로 쉽다.

flex-grow 값을 1로 설정하면된다. flex-shrink 속성도 0으로 설정해야한다. 왜?

flex-direction이 변경 되었기 때문에 그 이유가 분명하지 않을 수 있다.

일부 브라우저에는 플렉스 아이템이 컨텐츠 크기보다 줄어드는 버그가 있다.

이 버그의 해결 방법은 기본값인 1이 아니라 flex-shrink 값을 0으로 유지하고 flex-basis 속성을 auto로 설정하는 것이다.

이것은 이렇게 말하는 것이다: "플렉스 아이템의 크기를 자동으로 계산하되, 절대 줄어들게 하지 마시오."

이 값을 사용해도 여전히 플렉스 아이템의 기본 동작을 유지한다.

플렉스 아이템은 브라우저의 사이즈를 줄이면 축소되는데, 크기 조정은 shrink 속성을 기반으로하지 않는다. 대신, 플렉스 아이템의 폭을 자동으로 다시 계산하는 것을 기반으로 한다. flex-basis: auto

이렇게하면 플렉스 아이템의 크기가 이것의 폭 또는 높이 (선언 된 경우)만큼 커지게 하거나 기본 컨텐츠 크기만큼 커지게 한다.

flex-shorthand 속성을 잊지 말자. 더 많은 shorthand에 대해서 다룰 것이다.

간격 및 색상을 정의하기 위해 약간의 스타일을 적용 해자:

body {
display: flex;
flex-direction: column;
background-color: #fff;
margin: 0;
font-family: Lato, sans-serif;
color: #222;
font-size: 0.9em;
}
footer {
flex: 0 0 90px;
padding: 10px;
color: #fff;
background-color: rgba(61, 100, 158, .9);
}

아래의 화면과 같을 것이다:


어떻게 변경되는지를 보면, 훨씬 나아질 것이다.

사이드바 수정.

HTML을 수정하자.

<main>
<aside> <!--This represents the sidebar and contained in it are icon sets from font-awesome-->
<i class="fa fa-bars"></i>
<i class="fa fa-home"></i>
<i class="fa fa-search"></i>
<i class="fa fa-volume-up"></i>
<i class="fa fa-user"></i>
<i class="fa fa-spotify"></i>
<i class="fa fa-cog"></i>
<i class="fa fa-soundcloud"></i>
</aside>
<section class="content"> <!--This section will house everything other than the sidebar-->
</section>
</main>

소스만 확인해도 많은 것을 설명해준다. 

아이콘의 경우 인기있는 Font Awesome 라이브러리를 사용하고 있다.

아이콘을 추가하는 것은 CSS 클래스를 추가하는 것만큼 간단하다.

앞에서 설명한 것처럼, 위의 "main"섹션은 플렉스 컨테이너가 된다. 사이드바 (aside 태그로 표시) 및 섹션은 플렉스 아이템이다.

main {
flex: 1 0 auto; /*Is a flex item*/
display: flex; /*I just included this! - now a flex container with flex items: sidebar & main content section*/
}

점점 흥미로워지는가?

이제 플렉스 컨테이너로 메인 섹션을 갖게되었다. 플렉스 아이템 중 하나인 사이드바를 다뤄보자.

푸터를 페이지 아래쪽에 고정 한 것처럼 페이지의 왼쪽에도 사이드바를 고정 할 것이다.

aside {
flex: 0 0 40px; /*do not grow or shrink. Stay fixed at 40px*/
}

사이드바에 아이콘이 수직으로 쌓여 있어야한다.

사이드바를 플렉스 컨테이너로 만들고 모든 아이콘을 수직으로 쌓을 수있는 flex-direction을 지정할 수 있다.

그런 다음 정렬 속성을 적용하여 아이콘을 배치한다.

아래에서 이 작업을 수행 할 수있는 방법을 확인하자.

aside {
/* ... */
display: flex; /*Now a flex-container too*/
flex-direction: column; /*stack icons vertically*/
/*since direction is changed, this works on the vertical direction*/
justify-content: space-around;
align-items: center; /*direction is changed! This affects the horizontal direction. Places Icons in the center*/
background-color: #f2f2f2; /*make me pretty*/
}
aside i.fa {
font-size: 0.9em; /*font size for the icons*/
}

자세하게 주석을 달았으니 주석을 참조하자.

지저분한 CSS 핵(hack)을 사용하지 않고, 몇 라인의 코드를 추가함으로써 합리적인 코드로 구성이 됐다.


메인 컨텐츠 섹션은 현재 비어 있다.

이제 메인 섹션을 채워보자.

메인 섹션에 컨텐츠 추가.

완성된 프로젝트를 다시 한 번 살펴 보는게 도움이 될지도 모른다. 이것은 얼마만큼 프로젝트가 진행 되고 있는지 짐작 할 수 있기 때문이다.

이보다 더 중요한 점은 다음에 어떤 것을 다룰지 예상하는데 도움이 된다는 것이다.

HTML을 수정하고 .content 섹션 안에 집어 넣자.

<section class="content"> <!--This section was empty. Populating it with content-->
<div class="music-head"> <!--First list item: contains music details-->
<img src="images/cattyboard.jpg" /> <!--Album art-->
<section class="catty-music"> <!--other details of the album-->
<div>
<p>CattyBoard Top 100 Single Charts (11.06.36)</p>
<p>Unknown Artist</p>
<p>2016 . Charts . 100 songs</p>
</div>
<div> <!--Music controls-->
<i class="fa fa-play"> &nbsp;Play all</i>
<i class="fa fa-plus"> &nbsp;Add to</i>
<i class="fa fa-ellipsis-h">&nbsp;&nbsp;More</i>
</div>
</section>
</div> <!--end .music-head-->
<!--Second list item: Contains a list of all songs displayed-->
<ul class="music-list">
<li>
<p>1. One Dance</p>
<p>Crake feat CatKid &amp; Cyla</p>
<p>2:54</p>
<p><span class="catty-cloud">CATTY CLOUD SYNC</span></p>
</li>
<li>
<p>2. Panda</p>
<p>Cattee</p>
<p>4:06</p>
<p><span class="catty-cloud">CATTY CLOUD SYNC</span></p>
</li>
<li>
<p>3. Can't Stop the Feeling!</p>
<p>Catin Cimberlake</p>
<p>3:56</p>
<p><span class="catty-cloud">CATTY CLOUD SYNC</span></p>
</li>
<li>
<p>4. Work From Home</p>
<p>Cat Harmony feat Colla</p>
<p>3:34</p>
<p><span class="catty-cloud">CATTY CLOUD SYNC</span></p>
</li>
</ul>
</section>

코드가 길어 보이지만 꽤 간단한 코드이다.

나는 비어있는 컨텐츠 섹션에 앨범 아트와 Catty 앨범의 일부 세부 사항을 담고있는 div를 넣었다.

ul은 앨범에서 노래 목록을 포함하고 있다.

노래 제목, 아티스트, 시간 및 "catty cloud sync"는 목록 내의 개별 단락에 포함된다.

그럼 어떻게 스타일을 추가해야 할까?

먼저, .content 섹션을 플렉스 컨테이너로 만들어야한다.

.content {
display: flex;
flex: 1 1 auto; /*this makes sure the section grows to fill the entire available space and shrinks too*/
flex-direction: column;
}

플렉스 아이템 역시 다루어야 한다:

.music-head {
flex: 0 0 280px; /*Same memo, don't grow or shrink - stay at 280px*/
display: flex;
padding: 40px;
background-color: #4e4e4e;
}
.music-list {
flex: 1 0 auto;
list-style-type: none;
padding: 5px 10px 0px;
}

.music-head는 앨범 아트 및 기타 관련 앨범 세부 정보를 포함하고 있다.

확대(grow)하거나 축소(shrink)되지 않도록 height는 280px로 고정한다.

이미 부모 엘리먼트의  flex-direction이 바뀌어 있기 때문에 width가 아닌 height를 고정하는 것이다.

오, 나중에 플렉스 컨테이너가 필요하기 때문에 display: flex를 추가한다.

.music-list는 노래 목록을 가지고 있으며 위의 .music-head와 공유되도 남은 가능한 공간을 채운다.

이것은 아직 예쁘진 않지만 계속 따라오고 있다면 잘하고 있는 것이다.


여기에 몇 가지 문제가 있다.

1. 노래 목록은 끔찍해 보인다.

2. 뮤직 아트가 포함된 섹션에는 정말 보기 흉한 텍스트가 있다.


다시 말하지만, 나는 이러한 문제들을 해결할 수 있도록 여러분을 안내 할 것이다.

아래에 해결책이 있다.

노래 목록 다루기

각 노래 목록에는 4 개의 단락이 있다. 노래 제목, 아티스트, 재생 시간 및 "catty cloud sync".

이 모든 것을 한 줄에 넣고 각 단락이 같은 공간을 차지할 수 있는 방법이 있어야한다.

Flexbox를 이용하자!

여기의 개념은 많은 그리드 시스템에서 사용되는 것과 동일하다.

그것을 코드로 변환하자.

li {
display: flex; /*Paragraphs are now displayed on one line*/
padding: 0 20px; /*Some breahing space*/
min-height: 50px;
}
li p {
flex: 0 0 25%; /*This is the sweet sauce*/
}

이 단락에서 무슨 일이 일어나고 있는지 보이는가?

flex: 0 0 25%;

"확장(grow), 축소(shrink)하지 말고 각 단락은 공간의 25%를 채워야 한다".

공백은 단락간에 동일하게 공유된다.

이 테크닉 사용하기

이 테크닉은 매우 중요하다. 이를 사용하여 서로 다른 컨텐츠 영역을 만들 수 있다.

예를들어, 한 섹션은 사용 가능한 공간의 60%를 채우고, 다른 섹션은 공간의 40%를 채우게 할 수 있다.

.first-section: 0 0 60%;
.second-section: 0 0 40%;

그리드 시스템을 만드는 데 이 테크닉을 사용할 수 있다.

목록은 이제 아래처럼 보일 것이다.


목록에 색상을 번갈아 표시하고 "catty cloud sync"레이블도 처리하자.

li span.catty-cloud {
border: 1px solid black;
font-size: 0.6em;
padding: 3px;
}
li:nth-child(2n) {
background-color: #f2f2f2;
}

이제 정말로 Flexbox 용어에 대해 더 잘 이하하게 될 것이다.

이것은 당신이 지금 해야만 하는 것이다.


두 번째 문제를 지금 다룰 것이다.

앨범 세부 정보 텍스트를 더 예쁘게 보이도록.

정말 간단한 것들을 다룰 것이다.

.catty-music{
flex: 1 1 auto;
display: flex;
flex-direction: column;
font-weight: 300;
color: #fff;
padding-left: 50px;
}
.catty-music div:nth-child(1){
margin-bottom: auto;
}
.catty-music div:nth-child(2){
margin-top: 0;
}
.catty-music div:nth-child(2) i.fa{
font-size: 0.9em;
padding: 0 0.7em;
font-weight: 300;
}
.catty-music div:nth-child(1) p:first-child{
font-size: 1.8em;
margin: 0 0 10px;
}
.catty-music div:nth-child(1) p:not(:first-child){
font-size: 0.9em;
margin: 2px 0;
}

거의 끝났다.


간단한 연습

나는 당신이 연습 해볼 수 있도록 푸터를 남겨뒀다.

푸터를 직접 고쳐보자. 위에서 사용한 같은 테크닉을 사용하자.

막힌다면 Catty Music의 전체 소스 코드를 언제든지 확인할 수 있다.

전체 푸터를 플렉스 아이템으로 나눌 수도 있다.


와우. 나는 당신이 여기까지 왔다는 것을 믿을 수 없다. 멋지다! 이제 Flexbox 닌자가되고 있다.

다음으로, Flexbox가 반응형 디자인에 어떻게 도움이되는지 살펴 보겠다.

Flexbox를 이용한 반응형 디자인


이 글은 Flexbox 모델에 중점을 두었으므로 반응형 디자인에 대해서는 깊이 다루지는 않을 것이다.

앞서 말했듯이, 우리는 Flexbox 모델을 통해 이미 어느정도 반응형 디자인을 얻었다.

Flexbox는 "유연한 상자(flexible box)"와 같다.

그러나 미디어쿼리를 통해 다양한 화면 크기를 타겟팅 한 다음 플렉스 동작을 변경할 수 있다.

다음은 그 예제이다.

정렬되지 않은 목록을 다시 사용하자.

<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
<li>Register</li>
<li>Login</li>
</ul>

그리고 약간의 스타일 추가...

ul {
list-style-type: none;
display: flex;
border: 1px solid #4e4e4e;
}
li {
flex: 0 0 auto;
padding: 10px;
margin: 10px;
background-color: #8cacea;
color: #fff;
font-size: 1em;
}

당신은 이제 플렉스 전문가이다. 그래서 당신은 무슨 일이 일어나고 있는지 이해 할 것이다.

네비게이션 바 모양은 다음과 같다.

Flexbox 네비게이션

데스크탑 및 태블릿의 경우 멋지지만 특정 화면 크기에서는 이상해 보인다.

모바일에서는 네비게이션 아이템을 세로로 쌓아 올릴 수 있다.

미디어쿼리를 사용하면 된다.

@media screen and (max-width: 769px) {
/* code here only applies to screen devices that have a width lesser than 769px*/
ul {
flex-direction: column; /* On smaller devices, switch the direction*/
}
}

반응형 디자인에 대해 어느정도 지식이 있다면 많이 도움이 된다.

Flexbox 모델을 기존 지식으로 바꾸기만 하면 된다.

그건 그렇고, 나는 당신이 미디어쿼리가 무엇인지 이해한다고 가정을 했는데, 만약 미디어쿼리에 대해 잘 모른다면 아래의 간단한 요약을 참고하자.

미디어쿼리(Media Queries)

미디어쿼리는 반응형 디자인의 핵심이다. 이 도구를 사용하여 특정 화면 크기에서 실행할 코드를 지정 할 수 있다.

미디어쿼리가 사용되는 가장 보편적인 형식은 @media 룰이다.

이것은 다음과 같다:

@media screen and (max-width: 300px) {
/*write your css in this code block*/
}

소스만 봐도 거의 이해 할 수 있을 것이다.

"최대 너비 300px의 화면 디바이스의 경우 이 작업을 수행"

코드 블록 내의 모든 스타일은 "screen and (max-width: 300px)"과 일치하는 디바이스에만 적용된다.

이것으로 약간의 혼란을 해결하는데 도움이되었으리라 생각한다.

간단한 연습

Catty Music은 모바일 디바이스에서 다르게 보인다. 그것은 좋은 소식이다. 더 나은 점은 이것을 다시 만들어야한다는 것이다.


문제가 발생하는 경우 이 튜토리얼의 저장소 링크는 다음 섹션에 있다. 이것에 대한 해결책 또한 repo에 있다.

이제 거의 끝나간다!

결론 섹션에서는 브라우저 지원, 유용한 링크 및 리소스에 대해 설명하겠다.

결론


플렉스 컨테이너 및 플렉스 아이템 정렬 속성을 사용하는 방법을 배웠다.

절대적(absolute) 및 상대적(relative) 플렉스, auto-margin 정렬 및 flex-direction 전환에 대해 설명했다.

Catty Music을 제작할 때 "플렉스 스킬(flex skills)"을 적용 할 수 있는 기회를 얻었다. 그런 다음 반응형 디자인에 대해서도 언급했다.

정말로 긴 여정이었다.

이제 최종 개념을 설명하겠다. 리소스와 링크를 통해 도움을 받길 바란다.

How’s the browser support for Flexbox?

This is a common question asked when looking to use the Flexbox model in production.

I can’t answer the question perfectly, but the caniuse website does justice to this.

Here’s a screenshot from caniuse, and browser support is quite impressive. You may see for yourself here.

브라우저의 Flexbox 지원 범위는 어떨까?

프로덕션 환경에서 Flexbox 모델을 사용할 때 자주 묻는 질문이다.

나는 그 질문에 완벽하게 대답 할 수는 없지만, canisuse 웹 사이트에서 확인 할 수 있다.

여기 스크린샷이 있으며 브라우저 지원은 아주 인상적이다. 여기서 직접 볼 수 있다.


처음에 이 사이트를 여러 번 보았지만 데이터가 의미하는 바를 파악할 수 없었다. 여기에 간단한 설명이 있다.

caniuse 웹사이트의 오른쪽 하단에는 legend가 있다.


위의 이미지를 보거나 사이트를 방문하여 legend를 찾아 볼 수 있다.

Additional resources

I hope you find these helpful:

추가 리소스

도움이 됐기를 바란다:

  1. PDF document (Understanding Flexbox) — direct link
  2. Play with the Catty Music code online
  3. The Repo for the entire “Understanding Flexbox” tutorial
  4. Mastering Modern CSS layouts Book
  5. Flexbox Playground and Code Generator
  6. Flexbox Froggy: A Cool Flexbox Game

마지막으로, 여기까지 따라와 주셔서 감사하다.


Call to Action

저는 Flexbox와 CSS Grid를 처음부터 마스터하는 것을 도울 수 있다. 여기에 연락처를 남겨 준다면 기꺼이 돕겠다. Flexbox Cheatsheet 가이드를 무료 선물로 보내준다. 여기서 가입하면 된다.



리뷰