CSS 중급(1)

Jelkov Ahn·2021년 8월 3일
0

HTML & CSS

목록 보기
6/9
post-thumbnail

Before You Learn

아래 내용은 지난 유닛에서 학습한 내용입니다. 잘 이해하고 있는지 점검하세요.


  • CSS의 기본적인 셀렉터 #와 .의 차이를 이해하고 있다.
  • 절대 단위와 상대 단위를 구분할 수 있다.
  • CSS 박스 모델에 대해 이해하고 있다.
  • 박스 측정 기준(content-box, border-box) 두 가지의 차이를 이해하고 있다.

Achievement Goals

  • 다양한 CSS 셀렉터 규칙을 이해할 수 있다.
  • 후손 셀렉터와 자식 셀렉터의 차이는 반드시 알아야 합니다.
  • 레이아웃을 위한 HTML을 만들 수 있다.
  • Flexbox를 이용해 레이아웃을 만들 수 있다. (다음 속성에 대한 이해가 있어야 합니다)
  • 방향: flex-direction
  • 얼마나 늘릴 것인가?: flex-grow
  • 얼마만큼의 크기를 갖는가?: flex-basis
  • 수평 정렬: justify-content
  • 수직 정렬: align-items

checkpoint


1) 레이아웃: 화면을 나누는 방법

1-1) HTML 구성하기

  • CSS로 화면을 구분할 때에는 수직분할과 수평분할을 차례로 적용합니다. HTML 문서를 통해 레이아웃을 작성하면, 다음과 같이 구성할 수 있습니다.
<div id="container">
  <div class="col w10">
    <div class="icon">아이콘 1</div>
    <div class="icon">아이콘 2</div>
    <div class="icon">아이콘 3</div>
  </div>
  <div class="col w20">
    <div class="row h40">영역1</div>
    <div class="row h40">영역2</div>
    <div class="row h20">영역3</div>
  </div>
  <div class="col w70">
    <div class="row h80">영역4</div>
    <div class="row h20">영역5</div>
  </div>
</div>
  • [코드] 레이아웃을 고려해 작성한 HTML 파일

1-2) 레이아웃 리셋

HTML 문서는 기본적인 스타일을 가지고 있습니다. 때때로 HTML 문서가 갖는 기본 스타일이, 레이아웃을 잡는 데 방해가 되기도 합니다.
이러한 수요에 따라 초기화(리셋)을 위한 다양한 라이브러리(Normalize.css)가 등장했지만, 사실 굳이 라이브러리를 사용할 필요는 없으며, 위에 언급한 문제를 해결할 몇 줄의 코드를 적용시키면, 기본 스타일링을 제거하여 디자인한 대로 레이아웃을 구현할 수 있습니다.

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}
  • [코드] 기본 스타일링을 제거하는 CSS 코드의 예시

2) Flexbox로 레이아웃 잡기

2-1)display: flex 분석하기 (to Parent element)

  • 부모 박스요소에 display: flex를 적용해, 자식 박스의 방향과 크기를 결정하는 레이아웃 구성방법입니다.
  • 기본값으로, display: flex가 적용된 부모 박스의 자식 요소는 왼쪽부터 차례대로 이어 배치됩니다.
    • outer가 부모박스 요소 / box가 자식박스 요소
      아래의 그림과 같이 자식박스요소가 왼쪽에서 부터 차례대로 적용된다.
    • [그림] 수직분할
<div id="outer">
  <div class="box">box1</div>
  <div class="box">box2</div>
  <div class="box">box3</div>
</div>
  • [코드] "display: flex"를 적용시키는 예시를 위해 작성한 HTML 코드
#outer {
  display: flex;
  border: 1px dotted red;
  padding: 10px;
}

.box {
  border: 1px solid green;
  padding: 10px;
}
  • [코드] HTML의 div 요소를 선택하여, 부모요소에 "display: flex"를 적용한 예시

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

flexbox는 박스가 수직으로 분할되는 것이 기본값입니다.
그러나 방향을 설정해주면, 수평으로도 분할할 수 있습니다.
flex-direction 속성은 부모 박스요소에 적용합니다. 자식 박스에 특별한 속성을 주지 않아도, 부모 요소에 의해 자식 요소가 영향을 받습니다. 주요 속성은 다음과 같습니다.

  • row (기본값)
  • column (수평분할)
#outer {
  display: flex;
  flex-direction: column;
  border: 1px dotted red;
  padding: 10px;
}

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

  • [그림] 수평문할 예시

  • 알아두기

    • display 속성에 flex를 적용하는 것은 부모 요소에 적용합니다.
    • (display: flex) 자식 요소는 flex라는 속성에 값을 적용합니다. (flex: 0 1 auto)

2-3)반드시 알아두기: grow(팽창 지수), shrink(수축 지수), basis(기본 크기)

  • 1) 자식 박스에 어떠한 속성도 주지 않으면, 왼쪽에서부터 오른쪽으로 콘텐츠의 크기만큼 배치됩니다.
    자식 요소의 flex 속성을 추가하지 않으면, 다음과 같은 기본값이 적용됩니다.
flex: 0 1 auto;
  • [코드] 자식요소에 flex 속성을 추가하지 않으면 적용되는 기본값
  • 2) flex 속성에 적용되는 세 가지 영역은, margin이나 padding에서 띄어쓰기를 기준으로 의미하는 바가 구분되는 것과 동일합니다.
    그러나, flex 속성에 적용되는 세 가지는 기본 크기를 바탕으로 필요에 따라 늘리거나 줄일 수 있는 값이 적용됩니다.
    각각의 값이 의미하는 것은 다음과 같습니다.
flex: <grow> <shrink> <basis>
  • [코드] flex 속성에 적용되는 세 가지 값의 종류
  • 3) 이 순서와 기본값은 반드시 기억하세요. "flex: grow shrink basis", "flex: 0 1 auto"
    margin이나 padding에서 상하좌우 각 방향을 따로 지정할 수 있었던 것처럼, flex에 적용되는 grow(팽창지수), shrink(수축지수), basis(기본크기)도 각 값을 따로 지정할 수 있습니다.
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
  • [코드] flex에 입력되는 세 속성을 따로 입력할 수도 있습니다.
  • 4) grow, shrink 속성은 단위가 없고, 비율에 따라 결과가 달라집니다.
    • 부모 박스 안에 n개의 자식 박스가 있다고 가정합니다.
      각 자식 박스가 갖는 grow값의 총 합이 n이라면,
      grow 속성의 값을 1로 설정하는 것은 1/n 가로 또는 세로길이를 적용한다는 의미입니다.
      grow 속성의 값을 2로 지정하면, 2/n의 길이를 의미합니다.
      HTML 파일을 다음과 같이 변경하고, 첫 번째 자식 박스에 target 클래스를 추가한 다음, 여러가지 방식으로 접근해보겠습니다.
<div id="outer">
  <div class="box target">.box.target</div>
  <div class="box">.box</div>
  <div class="box">.box</div>
</div>
  • [코드] html 파일에서, 자식 박스 요소 중 첫 번째 자식 박스 요소에 target 클래스를 추가합니다.

(3) flex 속성의 하위 속성

3-1) grow: 자식 박스는 얼마나 늘어날 수 있을까요?

  • 1) target 클래스에서, flex-grow 속성의 값을 1로 변경합니다.
    target 클래스를 가지고 있는 첫 번째 자식박스는,
    부모 박스의 가로 길이 중에서 남은 빈 영역만큼 늘어납니다.
    위 설명대로라면 전체 자식요소가 가진 grow 값의 합은 1+0+0 = 1이므로,
    target 클래스를 가지고 있는 자식 박스의 가로 크기는 1/1 = 100% 입니다.
    그러나 다른 자식 박스 안에 이미 콘텐츠가 존재하므로,
    다른 자식 박스안의 콘텐츠가 담긴 길이를 제외한 나머지 가로 길이가 target 클래스를 가진 자식박스의 가로 길이입니다.
  • [그림] target 클래스에만 flex-grow 속성에 1을 적용한 경우
<Html>
<div id="outer">
  <div class="box target">.box.target</div>
  <div class="box">.box</div>
  <div class="box">.box</div>
</div>
<Css>
#outer {
  display: flex;
  border: 1px dotted red;
  padding: 10px;
}

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

.target {
  flex: 1 1 auto;
}
  • [코드] target 클래스에 flex-grow 속성의 값을 1로 설정
  • 2) box 클래스의 flex-grow는 기본값인 0입니다.
    만약 box 클래스의 flex-grow 속성에 값을 1로 설정하면, 모든 박스가 늘어나려고(grow) 합니다.
    결과적으로 모든 박스가 동일한 비율로 가로 길이가 늘어납니다.
    (총 grow 값 1+1+1, 각 박스는 1/3씩 크기를 가짐)
  • [그림] box 클래스의 flex-grow 속성에 1을 적용한 경우 / (target 클래스 이미 flex-grow 1)
<Html>
<div id="outer">
  <div class="box target">.box.target</div>
  <div class="box">.box</div>
  <div class="box">.box</div>
</div>
<Css>
#outer {
  display: flex;
  border: 1px dotted red;
  padding: 10px;
}

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

.target {
  flex: 1 1 auto;
}
  • [코드] box 클래스의 flex-grow 속성의 값을 1로 설정

  • 3) flex-grow 속성에 적용하는 값은 비율을 의미합니다.
    모든 자식 박스의 flex-grow 속성이 0보다 큰 값을 동일하게 가지는 경우, 각 박스의 가로 길이는 동일한 비율을 가집니다.
    다음 코드는 전부 같은 모양으로 렌더링됩니다.

.box {
  flex: 1 1 auto;
  /*
  flex: 2 1 auto;
  flex: 3 1 auto;
  flex: 4 1 auto;   // 모두 같은 값을 렌더링 합니다.
  */
}

.target {
  /* flex 값을 지정하지 않음 */
}
  • [코드] 모든 자식 박스에 flex-grow 속성의 값을 동일하게 적용하면, 모든 자식 요소의 flex-grow 속성의 값을 1로 설정한 것과 같습니다.

  • 4) box 클래스의 flex-grow 속성에는 1을 그대로 두고, target 클래스의 flex-grow 속성의 값을 변경해보겠습니다. target 클래스를 가지고 있는 자식 박스는, 다른 자식 박스와의 비율만큼 크기가 더 커집니다.

  • [그림] target 클래스의 flex-grow 속성에만 2를 적용하고, box 클래스의 glex-grow 속성은 1로 설정한 경우

.box {
  flex: 1 1 auto;
}

/* 
 * 자식 박스가 총 세개인데, target만 2의 비율을 가집니다.
 * 2(target) + 1(box2) + 1(box3) = 4 이므로,
 * target의 비율은 50% 입니다.
 */
.target {
  flex: 2 1 auto;
}
  • [코드] target 클래스의 flex-grow 속성을 2로 설정

3-2) shrink: 자식 박스는 얼마나 줄어들 수 있을까요?

  • shrink는 grow와 반대로, 설정한 비율만큼 박스 크기가 작아집니다.
  • flex-grow 속성과 flex-shrink 속성을 함께 사용하는 일은 추천하지 않습니다.
    • 비율로 레이아웃을 지정할 경우
      flex-grow 속성 또는 flex: <grow> 1 auto와 같이 grow 속성에 변화를 주는 방식을 권장합니다.
    • flex-shrink 속성은 width나 이후 설명할 flex-basis 속성에 따른 비율이므로 실제 크기를 예측하기가 어렵기 때문입니다.
  • flex-grow 속성으로 비율을 변경하는 경우, flex-shrink 속성은 기본값인 1로 두어도 무방합니다.

3-3) basis: 이 박스의 기본 크기는 몇일까요?

  • 자식 박스가 flex-grow나 flex-shrink에 의해 늘어나거나 줄어들기 전에 가지는 기본 크기입니다. flex-grow가 0일 때, basis 크기를 지정하면 그 크기는 유지됩니다.
<div id="outer">
  <div class="left">메뉴</div>
  <div class="right">본문</div>
</div>
  • [코드] HTML 파일에 작성된 메뉴와 본문이라는 두 가지 자식 박스
/* grow를 0으로 설정해줘야 100px 이상으로 늘어나지 않습니다. */
.left {
  flex: 0 1 100px;
}

/* 우측 박스는 grow를 1로 설정해 나머지 공간을 채워줍시다 */
.right {
  flex: 1 1 auto;
}
  • [코드] 왼쪽 메뉴 박스는 크기를 유지해야 하므로 flex-basis 속성에 100px을 적용합니다.

  • [그림] 오른쪽 본문 박스는 flex-basis 속성이 auto로 설정되어 flex-grow 속성의 영향을 받습니다.

  • 알아두기
    flex-grow 속성의 값이 0인 경우에만 flex-basis 속성의 값이 유지됩니다.
    diplay 속성에 flex가 적용된 컨테이너 내부에 존재하는 자식 박스는 경우에 따라, basis로 설정된 크기가 항상 유지되는 것은 아닙니다.
    flex-grow 속성의 값이 1 이상인 경우, flex-basis 속성에 적용한 값보다 커질 수도 있습니다.
    실제 레이아웃을 구현하면서 막히는 경우에는, 다음의 원리를 참고할 수 있습니다.

    • width와 flex-basis를 동시에 적용하는 경우, flex-basis가 우선됩니다.
    • 콘텐츠가 많아 자식 박스가 넘치는 경우, width가 정확한 크기를 보장하지 않습니다.
    • (flex-basis를 사용하지 않는다면) 콘텐츠가 많아 자식 박스가 넘치는 경우를 대비해,
      width 대신 max-width를 쓸 수 있습니다.

(4) 콘텐츠 정렬 방법

  • axis

    • main axis
    • cross axis
  • main axis은 flex-direction 속성에 의해서 결정됩니다.
    flex-direction의 기본 값인 row 인 상태일 때 main axis 는 가로축이 됩니다.

  • cross axis는 여러 개의 main axis와 수직을 이루는 방향입니다.
    main axis가 가로일 때 cross axis는 세로가 됩니다.

  • axis들을 기준으로 정렬할 수 있는 속성

    • justify-content: main axis(수평)를 기준으로 정렬
    • align-items: cross axis(수직)를 기준으로 정렬
  • flex-direction 속성의 값을 column 으로 준다면 main axis과 cross axis는 서로 바뀐다.

  • flex-direction 이 row 인 상태, 즉 main axis가 가로인 상태를 기준으로 설명하는 내용입니다.

    • 콘텐츠 수평 정렬 (justify-content)
      부모 박스에 justify-content 속성을 적용하면, 자식 박스를 수평으로 정렬할 수 있습니다.

    • justify-content 속성의 값이 될 수 있는 주요 옵션

      • flex-start
      • flex-end
      • center
      • space-between
    • 콘텐츠 수직 정렬 (align-items)
      부모 박스에 align-items 속성을 적용하면, 자식 박스를 수직으로 정렬할 수 있습니다.

    • align-items 속성의 값이 될 수 있는 주요 옵션

      • flex-start
      • flex-end
      • center
      • stretch

출처 코드스테이츠

profile
끝까지 ... 가면 된다.

0개의 댓글