Markup-language/CSS

CSS :) [중요] 레이아웃 구성하기!! display: flex, flex(felx-direction/grow/shink/basis), justyfy-content, align-items

euncheol kim 2022. 4. 28. 14:28

 

 

goal

CSS레이아웃을 구성하는 방법에 대해서 이해한다

 

 

1 ] CSS 구성하기


1. 레이아웃 구성에 어려움을 겪는 경우

  • <body>태그가 가진 기본 스타일에 약간의 여백이 있어 박스의 시작을 (0,0)위치에서 시작하지 못하는 경우
  • width, height 계산이 여백을 포함하지 않아 계산되는 경우 (*box-sizing으로 해결한다)
  • 브라우저의 종류(크롬, 사파이 ,IE 등)에 따라 여백이나 글꼴, 기본스타일이 조금씩 다름

3가지 문제의 해결법

CSS파일

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

※ 위의 문제들을 해결하기위해 표준화된 라이브러리들이 제공되기도 한다.

 

 

2. 분할의 종류

  • 수직분할 : 화면을 수직으로 구분하여, content가 가로로 배치될 수 있도록 요소를 배치한다.
  • 수평분할 : 분할된 각각의 요소를 수평으로 구분하여, 내부 content가 세로로 배치될 수 있도록 요소를 배치한다.
    • 수평으로 구분된 요소에 height 속성을 추가하면, 수평분할을 보다 직관적으로 할 수 있다.

 

2 ] 레이아웃 잡기 : Flexbox로!

image

사전적 의미의 flex : 잘 구부러지는, 유연한

  • flexbox로 레이아웃을 구성한다는 것은, 박스를 유연하게 늘리거나 줄여 레이아웃을 잡는 방법이다.

 

 

1. display옵션과 flex 속성.. (display: flex)


[1] display: flex을 적용해보기

display: flex를 적용해, 자식 박스의 방향크기를 결정하는 레이아웃 구성법

  • 기본값으로, display: flex가 적용된 부모 박스의 자식 요소는 왼쪽부터 차례대로 배치된다.
    • index.html
      •  
      • <div id="outer"> <div class="box">box1</div> <div class="box">box2</div> <div class="box">box3</div> </div>
    • index.css
      • #outer {
          display: flex;
          border: 1px dotted red;
          padding: 10px;
        }
        
        .box {
          border: 1px solid green;
          padding: 10px;
        }
    • 결과화면
      • image
        • 만약, padding을 주지 않는다면 내부 속성의 div 친구들은 빨간 점선에 붙어버린다.
        • 기본적으로 flex만 설정할 경우, 수직분할되어 버린다.

 

[2] flex요소에 방향 지정하기 (flex-direction)

  • flex의 수직/수평 분할을 결정해준다.
  • flex-direction 적용시 상속에 대해서 꼭 신경써줘야한다.
  • 중요한 부분은 아래와 같다.
옵션 설명
row (default) 수직 분할 (컨텐트를 가로로 배치)
image
column 수평 분할 (컨텐트를 새로로 배치)
image
row-reverse 요소들을 텍스트의 반대 방향으로 정렬
column-reverse 요소들을 아래에서 위로 정렬

※ [중요] flex-direction에 대한 추가 설명

flex-directiondisplay:flex의 적용한 곳에 입혀주어한다. 이유는 아래와 같다.

  • flex-direction자식 및 후손 요소 들에게 상속이 되어진다. (아래의 실습으로 확인하자)

 

 

 

※ flex-direction 값의 상속에 대한 실습[1]

  • index.html
    <div id="outer">
        <div class="box">box1
            <div class="direction">내용1</div>
            <div class="direction">내용2</div>
            <div class="direction">내용3</div>
        </div>
        <div class="box">box2</div>
        <div class="box">box3</div>
    </div>
  • index.css
#outer {
    display: flex;
    flex-direction: column;
    border: 1px dotted red;
    padding: 10px;
  }

  .box {
    border: 1px solid green;
    padding: 10px;
  }

  .direction {
      border: 2px solid blue;
      padding: 10px;
  }
  • 결과

image

- 부모(#outter)에 적용된 flex-direction이 자식 및 후손들에게 영향을 미친다.

 

 

 

 

※ flex-direction 값의 상속에 대한 실습[2]

  • index.html : 위와 동일하니 생략
  • index.css
#outer {
    display: flex;
    border: 1px dotted red;
    padding: 10px;
  }

  .box {
    border: 1px solid green;
    padding: 10px;
    flex-direction: column;

  }

  .direction {
      border: 2px solid blue;
      padding: 10px;
  }
  • 결과

image

- 부모(#box)에 적용된 flex-direction자식 및 후손들에게 영향을 미친다.

- 반대로, #outerflex-direction이 default이며 수직정렬(컨텐츠가 가로로 붙음)이 붙었고, 다음 자식은 영향을 받지 않는다.

 

 

[3] flex: 옵션1 옵션2 옵션3 (grow / shrink / basis)

- display-flex의 옵션을 정의한다.

  • 옵션1은 grow : 팽창 지수 (단위 x)
  • 옵션2는 shrink : 수축 지수 (단위 x)
  • 옵션3은 basis : 기본크기

 

사용방법

[가정] : 부모 박스 안에 n개의 자식 박스가 있다.

  • 각 자식 박스가 갖는 grow 값의 총합이 n일 때
  • grow에 1을 설정하는 것은 1/n 가로 또는 세로 길이로 적용한다는 것
  • gorow에 2를 설정하는 것은 2/n의 길이를 의미하는 것

 

 

1. grow : 자식 박스는 얼마나 늘어날 수 있을까?

- grow의 default는 0이다!

 

 

[1] grow의 적용 : 전체 범위 먹어야 하는거 아니야 ㅡㅡ?, NO!

  • index.html
<div id="outer">
  <div class="box target">.box.target</div>
  <div class="box">.box</div>
  <div class="box">.box</div>
</div>
  • index.css
#outer {
  display: flex;
  border: 1px dotted red;
  padding: 10px;
}

.box {
  border: 1px solid green;
  padding: 10px;
}

.target {
  flex: 1 1 auto;
}
  • 결과

image

[설명]

  • 예상대로라면 grow가 1이기 때문에 .target은 전체를 포함해야한다.
  • 하지만 형제들의 요소가 존재하므로 형제들의 콘텐츠의 크기를 제외하고 .target은 자리를 차지하게 된다.

 

 

[1] - 1:: grow 다양한 실습 적용

  • index.html
    <div id="outer">
        <div class="box">box1</div>
        <div class="box">box2</div>
        <div class="box">box3</div>
    </div>
  • index.css
#outer {
    display: flex;
    border: 1px dotted red;
    padding: 10px;
  }

  .box {
    border: 1px solid green;
    padding: 10px;
    flex: 1 1 auto;
    /* flex: 2 1 auto; */
    /* flex: 3 1 auto; */
    /* flex: 4 1 auto; */
  }
  • 결과값

image

  • [설명]
    • flex-grow의 기본값은 0이다.
    • 만약, box 클래스의 flex-grow 속성에 값을 1로 설정하면 box클래스를 가진 요소들은 커지려고한다.
    • 총 grow의 값은 1+1+1 = 3, 각 박스는 1/3씩의 크기를 가진다. (grow의 값은 비율임을 잃지말자)
    • 그리고 해당 코드에서는 1보다 큰 값이 들어와도 결과값과 동일하게 렌더링된다.

 

 

 

아래와 같이 코드를 작성하고 결과값을 봐보자

  • index.html
    <div id="outer">
        <div class="box taget">box1</div>
        <div class="box">box2</div>
        <div class="box">box3</div>
    </div>
  • index.css
#outer {
    display: flex;
    border: 1px dotted red;
    padding: 10px;
  }

  .box {
    border: 1px solid green;
    padding: 10px;
    flex: 1 1 auto;
  }

  .taget{
      flex: 2 1 auto;
  }
  • 결과값

image

  • [설명]
    • 우선 어려울게 없다. 위에 코드와 달리 target이 추가되었고
    • targetflex-grow에 2를 준 상태이다. 그러면 자연스럽게 부모 공간에서 비율이 2만큼의 공간을 차지하고
    • boxflex-grow가 1이므로 남은 공간에서 비율을 가져가게 된다.
    • 모든 동작은 위와 같은 원리를 따라간다.

 

 

[2] shrink : 자식 박스는 얼마나 줄어들 수 있을까?

  • grow와 반대되는 개념으로 설정한 비율만큼 줄어든다.
    • flex-growflew-shrink를 같이 쓰는 것은 비추천한다.
    • flew-grow속성 또는 flew: grow | 1 | auto와 같은 grow 속성에 변화를 주는 방식으로 권장
    • flex-shrink속성은 widthflex-basis 속성에 따른 비율이므로 실제 크기를 예측하기 힘들다.

 

 

 

[3] basis : 이 박스의 기본 크기는 몇일까?

  • flew-growflew-shrink적용되기 전에 가지는 기본 크기 (그니까 요소의 크기를 말하는 것이다)
  • index.html
    <div id="outer">
        <div class="left">메뉴</div>
        <div class="right">본문</div>
    </div>
  • index.css
#outer {
    display: flex;
    border: red solid 2px;
    padding: 20px;
}
.left {
    border: blue solid 2px;
    flex: 0 1 100px;


  }

  /* 우측 박스는 grow를 1로 설정해 나머지 공간을 채워줍시다 */
  .right {
    border: blue solid 2px;
    flex: 1 1 auto;
  }
  • 결과값

image

  • [설명] : 생략

 

 

 

2 ] 콘텐츠 정렬방법

  • axis(축)에 대한 이해
  • 구분은 아래와 같다
axis 구분 설명
main axis flex-direction에 의해서 결정된다.
- flex-direction: row이면 즉, default이면 main axis는 가로축이 된다.
cross axis main-axis와 수직을 이루는 방향이다.
- main-axis가 가로일때 cross axis는 세로가 된다.

 

 

1. axis를 기준으로 요소들을 정렬하기

속성명 설명
justify-content main-axis를 기준으로 정렬한다.
align-items cross-axis를 기준으로 정렬한다.

 

 

- 콘텐츠 수평 정렬 justify-content

  • 자식 박스를 수평으로 정렬한다.
  • 주요옵션은 아래와 같다
    • flex-start : 요소들을 왼쪽으로 정렬
    • flex-end : 요소들을 우측으로 정렬
    • center : 요소들을 가운데 정렬
    • space-between : 요소를 동일한 간격 배치
    • space-around : 요소들 주위에 동일한 간격

 

- 콘텐츠 수직 정렬 align-items

  • 자식 박스를 수직으로 정렬한다.
  • 주요 옵션은 아래와 같다.
    • flex-start : 요소들을 꼭대기로 정렬
    • flex-end : 요소들을 바닥으로 정렬
    • center : 요소들을 가운데 정렬
    • stretch : 요소들을 컨테이너에 맞도록 늘림
    • baseline : 요소들을 컨테이너의 시작 위치에 정렬

 

 

※ align-self : 개별 요소에 적용할 수 있는 속성

이 속성은 align-items가 사용하는 값들을 인자로 받고, 그 값들은 지정한 요소에만 적용된다.

 

※ flex-wrap :

옵션은 아래와 같다.

- nowrap: 모든 요소들을 한 줄에 정렬

- wrap : 요소들을 여러 줄에 걸쳐 정렬

- wrap-reverse: 요소들을 여러 줄에 걸쳐 반대로 정렬합니다.

 

※ flex-flow flex-direction | flex-wrap

: flex-direction와 flex-wrap은 같이 쓰이기 때문에 flex-flow로 대신하여 쓸 수 있다.

 

 

※ align-content : 여러 줄 사이의 간격을 정할 수 있다.

옵션은 아래와 같다.

- flex-start : 여러 줄들을 컨테이너의 꼭대기에 정렬한다.

- flex-end : 여러 줄들을 컨테이너의 바닥에 정렬한다.

- center : 여러 줄들 사이에 동일한 간격을 둔다.

- space-between : 여러 줄들 사이에 동일한 간격을 둔다.

- space-around : 여러 줄들 주위에 동일한 간격을 둔다.

- stretch : 여러 줄들을 컨테이너에 맞도록 늘린다.

 

 

 

문제풀 수 있는 사이트

https://flexboxfroggy.com/#ko

 

Flexbox Froggy

A game for learning CSS flexbox

flexboxfroggy.com