Float

색상을 따로 입력하지 않으면 그 요소가 가지고 있는 글자 색상을 참고하게 된다.

기본적으로 글자 색상은 검정색이기 때문에 color를 지정하지 않으면 border도 검정이 된다.

 

기본적으로 HTML의 요소들은 위에서부터 아래로 수직으로 쌓이게 되는데 float을 이용해서 수평 정렬을 시켜줄 수 있다.

 

float을 사용하면서 가장 중요한 것은 float 속성이 더이상 사용되지 않는다는 것을 알려주기 위해 해제(clear)를 해줘야 한다는 것이다.

 

가상 요소란 가상의 요소를 만든 뒤 거기에 css 요소를 추가할 수 있는 선택자를 의미한다.

가상 요소는 필수적으로 content라는 속성이 있어야지만 동작한다.

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

clearfix라는 클래스를 가지고 있는 요소의 가상 요소 after는 내부의 가장 뒷쪽에 가상의 요소를 만든다.

 

주의할 점은 clearfix가 부여가 되어있는 컨테이너에는 float을 사용하는 요소만 들어있어야 한다.

만일 float을 사용하는 아이템들과 사용하지 않는 아이템을 하나의 부모 요소로 묶어서 만들게 되면 레이아웃 상에 문제가 발생하게 된다.

<div class="container clearfix">
  <div class="item float">1</div>
  <div class="item float">2</div>
  <div class="item float">3</div>
  <div class="item four">4</div>
</div>
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}
.container {
  border: 4px solid;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: royalblue;
  border-radius: 10px;
  font-size: 40px;
  margin: 10px;
}
.container .item.four {
  width: 150px;
  height: 150px;
  background-color: orange;
}
.float {
  float: left
}

해결하기 위해서는 float 요소만 따로 div로 감싸면 된다.

<div class="container">
  <div class="clearfix">
    <div class="item float">1</div>
    <div class="item float">2</div>
    <div class="item float">3</div>
  </div>
  <div class="item four">4</div>
</div>

clearfix와 같이 전역으로 사용되는 스타일은 기본 요소의 스타일들을 정의하기 전에 가장 위쪽에 만드는 것이 좋다.

 

float: right을 사용할 때는 float이 부여 되어 있는 더 이전의 형제 요소들이 오른쪽에서부터 순서대로 쌓이게 된다.

<div class="container clearfix">
  <div class="item float--left">1</div>
  <div class="item float--left">2</div>
  <div class="item float--right">3</div>
  <div class="item float--right">4</div>
</div>
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}
.float--left {
  float: left;
}
.float--right {
  float: right;
}
.container {
  border: 4px solid;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: royalblue;
  font-size: 40px;
}

 

만일 3번과 4번 코드 순서를 뒤집지 않고도 오른쪽 정렬을 하고 싶다면 다음과 같이 작성하면 된다.

float 속성이 부여되어 있는 각각의 아이템의 부모 요소에는 clearfix라는 클래스를 꼭 부여하자.

<div class="container clearfix">
  <div class="item float--left">1</div>
  <div class="item float--left">2</div>
  <div class="float--right clearfix">
    <div class="item float--left">3</div>
    <div class="item float--left">4</div>
  </div>
</div>

 

float블록 레이아웃의 사용을 뜻하기 때문에 일부 경우에 display 값을 수정한다.

 

float - CSS: Cascading Style Sheets | MDN

CSS 속성(property) float 은 한 요소(element)가 보통 흐름(normal flow)으로부터 빠져 텍스트 및 인라인(inline) 요소가 그 주위를 감싸는 자기 컨테이너의 좌우측을 따라 배치되어야 함을 지정합니다.

developer.mozilla.org

참고로 일부 경우가 아닌 그외에는 grid도 포함된다.

 

[참고] inline 요소 특성

  • 필요한 만큼의 너비만 사용
  • 요소가 수평으로 쌓임
  • 크기 지정 불가능
<div>Hello</div>
<div class="float">Hello</div>
div {
  width: 200px;
  height: 100px;
  border: 4px solid;
  display: inline;
}
.float {
  float: left;
}

display: inline이 적용되어 있는 div에 float을 적용하면 display가 block으로 변경되는 것을 볼 수 있다.

 

Position

position요소의 위치 특성을 지정하는 속성이다.

위치의 특성을 정의하고 top, left, right, bottom과 같은 별도의 속성으로 정확한 위치를 설정한다.

 

absolute

abloute조상 요소를 타고 올라가며 위치의 기준이 될 수 있는 css 속성과 값이 들어있는지 확인한다.

<div class="parent3">
  <div class="parent2">
    <div class="parent1">
      <div class="child"></div>
    </div>
  </div>
</div>
.parent3 {
  width: 350px;
  height: 250px;
  background-color: tomato;
}
.parent2 {
  width: 300px;
  height: 200px;
  background-color: skyblue;
}
.parent1 {
  width: 250px;
  height: 150px;
  background-color: orange;
}
.child {
   width: 100px;
  height: 100px;
  background-color: royalblue;
  position: absolute;
  right: 0;
  bottom: 0;
}

왼쪽 상단에 있던 child는 조상 요소를 타고 올라가며 position 값을 확인하다가 모든 조상 요소에 poisiton이 없으므로 화면의 뷰포트를 기준으로 오른쪽 하단에 배치가 되는 것이다.

 

만일 parent2에 relative를 부여한다면 아래와 같이 배치된다.

항상 주의해야 하는 점은 absolute를 사용했을 때는 위치 기준이 있는 구조적으로 가장 가까운 조상 요소가 누구인지 확인해야 한다.

 

fixed

position 속성의 값으로 fixed를 주면 뷰포트를 기준으로 위치를 지정하게 된다.

child의 position이 fixed이고 parent1의 position이 relative라고 할 때 이는 child에게 아무런 영향을 주지 않는다. 

 

하지만 요소의 조상 중 하나가 transform, perspective, filter 속성 중 어느 하나라도 none이 아니라면 뷰포트 대신 그 조상을 컨테이닝 블록으로 삼는다.

 

position - CSS: Cascading Style Sheets | MDN

CSS position 속성은 문서 상에 요소를 배치하는 방법을 지정합니다. top (en-US), right (en-US), bottom (en-US), left (en-US) 속성이 요소를 배치할 최종 위치를 결정합니다.

developer.mozilla.org

.parent3 {
  width: 350px;
  height: 250px;
  background-color: tomato;
}
.parent2 {
  width: 300px;
  height: 200px;
  background-color: skyblue;
  transform: scale(1);
}
.parent1 {
  width: 250px;
  height: 150px;
  background-color: orange;
  position: relative;
}
.child {
   width: 100px;
  height: 100px;
  background-color: royalblue;
  position: fixed;
  right: 0;
  bottom: 0;
}

.parent3 {
  width: 350px;
  height: 250px;
  background-color: tomato;
}
.parent2 {
  width: 300px;
  height: 200px;
  background-color: skyblue;
  perspective: 300px;
}
.parent1 {
  width: 250px;
  height: 150px;
  background-color: orange;
  position: relative;
  transform: rotateX(45deg);
}
.child {
   width: 100px;
  height: 100px;
  background-color: royalblue;
  position: fixed;
  right: 0;
  bottom: 0;
}

요소의 위치 기준을 지정하려는 의도 없이 단순히 화면에 효과를 주기 위해 어떤 속성을 사용했을 때 이러한 속성들이 다른 요소의 위치 기준에 영향을 줄 수 있다는 것에 항상 주의해야 한다. 

 

쌓임 맥락(Stacking Context)

z-index를 사용하지 않고도 요소를 쌓을 수 있는 방법은 여러가지가 있다.

그 중 대표적인 것이 transformopactiy이다.

<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
.item {
  width: 100px;
  height: 100px;
  font-size: 40px;
}
.item:nth-child(1) {
  background-color: royalblue;
}
.item:nth-child(2) {
  background-color: orange;
  transform: scale(1.5);
}
.item:nth-child(3) {
  background-color: tomato;
  opacity: .5;
}

2번이 다시 3번 위로 올라오게 하고 싶어 다음과 같이 z-index 속성을 주어도 변함이 없다.

.item:nth-child(2) {
  background-color: orange;
  transform: scale(1.5);
  z-index: 1;
}

 

z-index가 동작할 수 있는 환경은 position의 기본값인 static을 제외한 값이 존재하는 경우이다.

.item:nth-child(2) {
  background-color: orange;
  transform: scale(1.5);
  position: relative;
  z-index: 1;
}

 

z-index 값의 기본값은 auto이다.

auto는 해당하는 브라우저가 자동으로 값을 만들어 내는 개념을 이야기한다.

 

별도의 z-index 값을 해당 요소에 부여한 적이 없고 조상 요소로부터 상속받은 값이 따로 없다면 그것은 0과 동일하다.

그래서 z-index 값이 없는 것과 동일한 상황에서 그보다 큰 값이 1을 주면 더 위에 쌓일 수 있는 구조가 된다. 

이러한 구조를 쌓임 맥락이라고 한다. 

 

쌓임 맥락 - CSS: Cascading Style Sheets | MDN

쌓임 맥락(stacking context)은 가상의 Z축을 사용한 HTML 요소의 3차원 개념화입니다. Z축은 사용자 기준이며, 사용자는 뷰포트 혹은 웹페이지를 바라보고 있을 것으로 가정합니다. 각각의 HTML 요소는

developer.mozilla.org

위 문서에 나와있듯이 z-indexflexgrid 요소에서도 사용 가능하다.

 

position의 absolutefixed 값을 사용했을 때 display가 block으로 변경될 수 있다.

<div class="item">Hello</div>
.item {
  width: 200px;
  height: 150px;
  background-color: orange;
  display: inline;
  position: absolute;
}

 

Flex Container

flex1차원 레이아웃 구조를 작업할 때 사용한다.

각각의 요소들을 수평(x축) 정렬하거나 수직(y축) 정렬할 수 있는 레이아웃 기술인데 하나의 축만 사용하므로 1차원 레이아웃이라고 부른다. 

 

flex가 부여가 되어 있는 부모 요소를 flex container라고 부르고 flex container의 자식 요소를 flex items라고 부른다.

 

flex container에는 display라는 속성을 사용할 수 있고 flexinline-flex를 값으로 줄 수 있다.

flex는 block 요소의 특성을 지니고 inline-flex는 inline 요소의 특성을 지닌다.

 

flex-direction

flex-direction은 flex 내부의 각각의 아이템들이 어느 축을 사용해서 정렬될 것인지 결정하는 속성이다.

row, column, row-reverse(오른쪽에서 왼쪽을 향하는 수평 정렬), column-reverse(아래에서 위를 향하는 수직 정렬) 값을 가진다.

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
.container {
  border: 4px solid;
  display: flex;
  flex-direction: row-reverse;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
}

frow-reverse

main-axis는 주축을 의미하고 cross-axis는 교차축을 의미한다.

여기서 교차축은 주가 되는 축의 반대축을 생각하면 된다.

 

flex-direction의 값 중 row-reverse는 주축이 x축이고, 교차축은 y축이다.

주축과 교차축은 상대적인 개념이다.

만일 column-reverse라면 주축이 y축이고, 교차축은 x축이 된다.

 

위 그림은 row-reverse로 정렬이 되었으므로 1번 아이템의 오른쪽이 flex-start이고, 3번 아이템의 왼쪽이 아니라 컨테이너의 왼쪽이 flex-end라고 보면 된다.

이 또한 상대적인 개념이다.

column-reverse

위 그림은 column-reverse로 정렬되었으므로 1번 아이템의 아래쪽이 flex-start, 3번 아이템의 위쪽이 flex-end이다.

row

위 그림은 row로 정렬되었으므로 flex-start는 1번 아이템의 왼쪽, flex-end는 3번 아이템의 오른쪽이 아니라 컨테이너의 가장 오른쪽 끝 부분이 된다.

 

 

flex-wrap

flex-wrap줄바꿈 처리에 대한 설정 속성이다.

세 가지의 값이 있는데 nowrap은 줄바꿈 처리가 되지 않는 것을 의미하며 기본값이다.

wrap은 줄바꿈 처리가 되는 것을 의미하고, wrap-reverse는 줄바꿈이 처리되는 방향이 반대(위)인 것을 의미한다.

 

flex의 아이템들은 flex-shrink 속성이 적용되어 있는데 이 속성의 기본값은 1이다.

flex-shrink는 아이템의 감소 너비 비율을 의미하는데 값이 1이라는 것은 컨테이너 너비가 아이템의 너비를 모두 합한 값보다 작으면 아이템의 너비가 감소될 수 있다는 것을 의미한다. 

.container {
  width: 200px;
  border: 4px solid;
  display: flex;
  flex-wrap: nowrap;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
}

nowrap

아이템들의 각 요소가 100px인데 컨테이너의 너비가 200px이므로 아이템의 너비가 감소한 것을 볼 수 있다.

wrap
wrap-reverse

 

justify-content

justify-content는 flex container 단에서 아이템들을 정렬하는 속성이다.

justify-content는 주축의 정렬 방법을 설정해주며 기본값은 flex-start이다.

또 다른 값으로는 flex-end, space-between(아이템의 사이 공간 균등), space-around(아이템의 양 옆 공간 균등)이 있다.

space-between
space-around

 

 

align-items

align-items는 flex container 단에서 아이템들을 정렬하는 속성이다.

교차축에 대한 정렬 방법을 설정하며 기본값은 flex-start이다.

다른 값으로는 flex-end, center(교차축의 가운데 정렬), baseline(아이템에 들어있는 문자의 기준선에 맞춰 정렬)이 있다.

 

block 요소는 가로 너비가 최대한 늘어나려고 하는 반면 세로 너비는 최대한 줄어들려고 한다.

.container {
  height: 200px;
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  background-color: orange;
  font-size: 40px;
}

위 css 코드에서 아이템의 height는 auto이고 컨테이너 내부에서 최대한 넓은 세로 너비를 사용하도록 만들어진다.

이 부분에 영향을 미치는 속성이 바로 align-items라는 속성인데 기본값으로 stretch라는 값을 가진다.

이 stretch로 인해 아이템에 별도의 높이를 지정하지 않으면 block 요소의 특징처럼 최대한 줄어들려고 하는 게 아니라 컨테이너 높이값 내부에서 최대한 늘어나려고 시도한다.

만일 아이템에 height가 별도로 명시되어 잇으면 stretch는 무시된다. 

 

.container {
  height: 200px;
  border: 4px solid;
  display: flex;
  align-items: flex-end;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
}

flex-end

.container {
  height: 200px;
  border: 4px solid;
  display: flex;
  align-items: baseline;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
}
.container .item:nth-child(2) {
  font-size: 80px;
}

baseline

문자의 아랫쪽 기준선에 맞춰서 y축의 교차축이 정렬되었다.

 

align-content

align-content 속성의 기본값은 stretch이다.

두 줄이상 아이템이 쌓여 있을 때 동작할 수 있는 속성이다.

flex-start, flex-end, center, space-between, space-around 값을 지닌다.

.container {
  width: 350px;
  height: 350px;
  border: 4px solid;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-end;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
}

stretch

stretch 같은 경우 최대한 늘어나려는 시도 끝에 하나의 줄이 만들어지기 때문에 사이에 공백이 생긴다.

flex-end
space-between

 

align 키워드가 앞에 붙으면 교차축에 해당하는 정렬을 지정한다.

1줄을 정렬할 경우에는 align-items를 사용하면 되고 2줄 이상은 align-content를 사용하면 된다.

 

Flex Items

flex-grow

flex-grow 속성은 flex 아이템의 증가 너비 비율을 설정하며 기본값은 0이다.

.container {
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
  flex-grow: 1;
}
.container .item:nth-child(2) {
  flex-grow: 2;
}

기본 너비 100px을 제외한 나머지 너비를 1 : 2 : 1비율로 설정했다.

만일 전체 너비를 1 : 2 : 1로 완벽하게 일치시키고 싶다면?

요소가 가지고 있는 기본 너비 100px을 없애주면 된다. 

위 css 코드에서 .item의 flex-grow: 1을 제거한다면 1번과 3번은 100px이 되고 2번은 최대한 늘어날 수 있는 길이(가변)를 지니게 된다. 

2번의 flex-grow는 2로 설정이 되어 있는데 1번과 3번은 늘어나지 않으므로 1만 적용해도 동일하게 출력이 된다. 

 

flex-shrink

flex-shrink 속성은 아이템의 감소 너비 비율을 설정한다. 

.container {
  width: 250px;
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
  flex-shrink: 0;
}

아이템의 크기가 의도치않게 줄어드는 것을 방지하려면 flex-shirink 속성을 통해서 감소 너비 비율을 0으로 주면 된다.

 

.container {
  width: 250px;
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
  flex-shrink: 1;
}
.container .item:nth-child(2) {
  flex-shrink: 4;
}

감소 너비 비율은 숫자가 크면 클수록 감소하는 비율이 늘어난다.

 

flex-basis

flex-basis 속성은 아이템의 기본 너비를 설정하며 기본값은 auto이다.

기본값이 auto인 경우 해당하는 아이템에 지정되어 있는 가로 너비와 세로 너비의 값을 이용하여 아이템을 출력한다.

.container {
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
  flex-basis: 50px;
}

아이템의 기본 width 100px값이 더이상 사용이 되지 않고 있다.

flex-basis 값이 auto가 아니면 지정한 너비는 적용되지 않는다. 

 

.container {
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
  flex-basis: 0;
  flex-grow: 1;
}
.container .item:nth-child(2) {
 flex-grow: 2; 
}

flex-basis의 값이 auto가 아니라 수치이므로 width: 100px은 무시되고, 무시가 된 상태에서 기본 너비가 0px이므로 1 : 2 : 1 비율로 각각의 아이템이 만들어진다.

 

flex

flex는 위의 3가지 속성 flex-grow, flex-shrink, flex-basis를 한 번에 다룰 수 있는 단축 속성이다.

.container {
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
/*   flex: grow shrink basis  */
/*   flex: 0 1 auto; */
  flex: 1;
}
.container .item:nth-child(2) {
 flex-grow: 2; 
}

flex: 1 (width 100px 무시)
flex: 1 1 auto (width 100px을 제외한 나머지 영역에 비율 적용)

flex: 1flex: 1 1 auto는 서로 다르다

flex 단축 속성을 다룰 때 굉장히 주의해야 하는 점인데 basis를 생략하게 되면 기본값인 auto가 아닌 숫자 0이 들어간다.

 

order

order아이템의 순서를 지정해주는 속성으로 기본값은 0이다.

order의 숫자가 늘어나게 되면 순서가 뒤로 밀린다.

.container {
  border: 4px solid;
  display: flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
}
.container .item:nth-child(1) {
  order: 1;
}

1번의 order가 크므로 순서가 뒤로 밀리는 것을 볼 수 있다.

 

HTML 구조를 변경하지 않더라도 css를 통해 화면에 출력되는 아이템의 순서를 관리할 수 있다.

HTML 구조와 css를 분리해서 생각할 수 있게 되는 장점이 있다.

 

order는 음수도 사용이 가능하다.

숫자가 작으면 작을수록 더 앞 순서를 차지할 수 있다.

3번 아이템에 order 값을 -1을 주면 3번이 맨앞으로 오게 된다.

 

align-self

align-selfalign-items를 개별적인 아이템 단위로 관리할 때 유용하게 사용할 수 있는 속성이며 기본값은 auto이다.

auto는 컨테이너에 지정되어 있는 align-items의 값을 상속받는다.

align-self의 다른 값으로는 stretch, flex-start 등 align-items 속성이 가지고 있는 모든 값들을 사용할 수 있다.

 

.container {
  width: 350px;
  height: 300px;
  border: 4px solid;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
}
.container .item:nth-child(1) {
  align-self: flex-start;
}

개별적인 아이템의 교차축 정렬이 가능하다.

 

gap

gap아이템 간에 여백을 만들 수 있다.

최신 기술이므로 동작하지 않는 브라우저가 많기 때문에 하위호환성을 고려한다면 리스크가 있다.

 

"gap" | Can I use... Support tables for HTML5, CSS3, etc

gap property for Flexbox `gap` for flexbox containers to create gaps/gutters between flex items

caniuse.com

.container {
  border: 4px solid;
  display: inline-flex;
  gap: 10px;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
}

gap을 사용하지 않고 margin을 사용해서 위와 같이 여백을 줄 수 있다.

.container {
  border: 4px solid;
  display: inline-flex;
}
.container .item {
  width: 100px;
  height: 100px;
  background-color: orange;
  font-size: 40px;
  border: 2px solid;
  margin-right: 10px;
}
.container .item:last-child {
  margin-right: 0;
}

 

Grid Container

grid는 2차원의 레이아웃 구조를 만들 수 있다.

display: grid가 부여된 요소가 grid container이고 grid container의 자식 요소들을 grid items라고 부른다.

 

grid container에는 display라는 속성을 사용할 수 있고 grid inline-grid를 값으로 줄 수 있다.

grid는 block 요소의 특성을 지니고 inline-grid는 inline 요소의 특성을 지닌다.

 

gird-template-rows / grid-template-columns

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: 100px 100px;
  grid-template-columns: 200px 200px 200px;
}
.container .item {
  border: 2px solid;
  font-size: 30px;
}

행축과 열축의 개수와 너비를 지정해주면 기본적인 2차원 레이아웃 구조가 된다.

.container .item:nth-child(2) {
  grid-row: span 2; 
}

위 코드를 추가하면 다음과 같다.

 

fr은 fraction의 약어로 공간 비율을 의미한다.

repeat이라는 그리드 함수를 이용해 비율을 반복적으로 적는 것을 방지할 수 있다.

 

grid-template-rows에 fr을 사용하기 위해서는 컨테이너에 높이값이 지정되어 있어야 한다.

현재 높이값이 없으므로 높이는 height의 기본값인 auto가 되고 block 요소의 특성상 높이값이 최대한 줄어들려고 한다.

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(8, 1fr);
}
.container .item {
  border: 2px solid;
  font-size: 30px;
  background-color: orange;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

아이템 안에 글씨가 있는 경우에는 글씨 크기에 딱 맞춰서 height가 맞춰진다.

<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

아이템 안에 글씨가 없다면 위와 같이 나오게 된다.

 

gird-auto-rows / grid-auto-columns

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(2, 100px);
  grid-template-columns: repeat(2, 1fr);
}
.container .item {
  border: 2px solid;
  font-size: 20px;
  background-color: orange;
}

행과 열의 개수를 2개로 설정했으므로 총 4개의 셀만 사용하고 있다.

그 안에 포함되지 못한 5, 6, 7번 아이템은 높이가 지정되지 않은 상태이다.

 

이럴때 사용할 수 있는 것이 grid-auto-rowsgrid-auto-colums 속성이다.

.container {
  border: 4px solid;
  display: grid;
  /* 명시적 영역 */
  grid-template-rows: repeat(2, 100px); 
  grid-template-columns: repeat(2, 1fr);
  /* 암시적 영역 */
  grid-auto-rows: 100px;
}
.container .item {
  border: 2px solid;
  font-size: 20px;
  background-color: orange;
}

 

.container {
  border: 4px solid;
  display: grid;
  /* 명시적 영역 */
  grid-template-rows: repeat(2, 100px); 
  grid-template-columns: repeat(2, 1fr);
  /* 암시적 영역 */
  grid-auto-rows: 100px;
  grid-auto-columns: 100px;
}
.container .item {
  border: 2px solid;
  font-size: 20px;
  background-color: orange;
}
.container .item:nth-child(5) {
  grid-column: 4;
}

grid-column이 4이므로 5번 아이템이 4번 column 라인으로 이동한다.

5번 뒤에 6과 7을 쌓아야 하므로 위처럼 지그재그로 아이템이 쌓이게 된다.

 

grid-auto-flow

하지만 이러한 빈공간은 효율적이지 않다.

이럴 때 사용할 수 있는 속성이 grid-auto-flow: dense이다.

참고로 grid-auto-flow의 기본값은 row이다.

.container {
  border: 4px solid;
  display: grid;
  /* 명시적 */
  grid-template-rows: repeat(2, 100px); 
  grid-template-columns: repeat(2, 1fr);
  /* 암시적 */
  grid-auto-rows: 100px;
  grid-auto-columns: 100px;
  grid-auto-flow: dense;
}
.container .item {
  border: 2px solid;
  font-size: 20px;
  background-color: orange;
}
.container .item:nth-child(5) {
  grid-column: 4;
}

dense는 아이템이 정렬될 때 빈 공간이 있으면 그 빈공간을 메우면서 정렬한다.

 

span은 아이템이 사용할 수 있는 cell이 총 몇 개로 확장될 수 있는지를 지정해주는 키워드이고 기본값은 1이다.

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(3, 100px); 
  grid-template-columns: repeat(3, 1fr);
/*   grid-auto-flow: dense; */
}
.container .item {
  border: 2px solid;
  font-size: 20px;
  background-color: orange;
}
.container .item:nth-child(2) {
  grid-column: span 3;  
}

2번 아이템이 사용할 수 있는 셀이 3칸이므로 아래 그림처럼 한 줄을 다 차지하게 된다.

이렇게 되면 컨테이너의 오른쪽 상단에 두 개의 셀 크기만큼 빈 공간이 생긴다.

여기에서 grid-auto-flow: dense를 사용하면 아래와 같이 변한다.

grid-auto-flow를 dense가 아니라 column으로 두면 열축으로 기준으로 지그재그로 쌓이게 된다.

 

grid-auto-flow의 값으로 dense만 입력하게 되면 앞에 row가 생략되어 있는 것이다.

그래서 행축으로 쌓이는 순서대로 빈공간을 메우게 된다.

 

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(3, 100px); 
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: column;
}
.container .item {
  border: 2px solid;
  font-size: 20px;
  background-color: orange;
}
.container .item:nth-child(1) {
  grid-column: 2 / span 2;  
}
.container .item:nth-child(2) {
  grid-column: span 3;  
}

grid-column: 2 / span 2는 1번 아이템을 컬럼의 2번 라인부터 시작해서 2개의 셀만큼 확장하여 아이템을 배치하겠다라는 의미이다.

이 상태에서 1번 아이템의 왼쪽을 메우고 싶으면 grid-auto-flow의 값을 columns dense로 주면 된다.

 

jutify-content

justify-content는 그리드의 아이템을 행축으로 정렬(수평 정렬)하는 속성으로 기본값은 normal이다.

normal은 stretch와 같은 개념으로 너비가 지정되어 있지 않은 경우 최대한 늘어나려고 한다. 

 

다른 값으로는 start, end, center, space-between(시작점과 끝점에 붙어서 나머지 공간 균등하게 분배), space-around(각 열의 왼쪽과 오른쪽의 여백 균등하게 분배), space-evenly(모든 여백 균등하게 분배)가 있다.

.container {
  width: 500px;
  height: 300px;
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(3, 70px);
  grid-template-columns: repeat(3, 70px);
  justify-content: space-evenly;
}
.container .item {
  border: 2px solid;
  background-color: orange;
}

space-evenly

위 코드에서 justify-content를 normal로 바꾸어도 70px이라는 값이 지정되어 있기 때문에 늘어나지 않는다.

 

align-content

align-content는 그리드의 아이템을 열축으로 정렬(수직 정렬)하는 속성으로 기본값은 normal(=stretch)이다.

값은 jutify-content와 동일하다. 

.container {
  width: 500px;
  height: 300px;
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(3, 70px);
  grid-template-columns: repeat(3, 70px);
  justify-content: stretch;
  align-content: space-around;
}
.container .item {
  border: 2px solid;
  background-color: orange;
}

 

justify-content와 align-content를 사용할 수 있는 기본 조건은 오렌지 영역인 grid content를 제외하고 행축과 열축에 정렬할 수 있는 빈 공간이 존재해야 한다는 것이다.

 

jutify-items

그리드 셀 내부에서 행축과 열축으로 빈 공간을 가지고 있을 때 사용할 수 있는 속성이다. 

jutify-items셀 내부에서 아이템을 행축으로 정렬하고자 할 때 사용한다. 

.container {
  width: 500px;
  height: 500px;
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
  justify-items: center;
}
.container .item {
  width: 100px;
  height: 100px;
  border: 2px solid;
  background-color: orange;
}

center

normal(=stretch), start, end 값을 가지고 있다.

jutify-items 같은 경우는 하나의 셀 안에는 어차피 하나의 아이템만 들어있을 것이기 때문에 space로 시작하는 속성값은 존재하지 않는다. 

 

align-items

그리드 셀 내부에서 행축과 열축으로 빈 공간을 가지고 있을 때 사용할 수 있는 속성이다.

align-items 셀 내부에서 아이템을 열축으로 정렬하고자 할 때 사용한다. 

.container {
  width: 500px;
  height: 500px;
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
  justify-items: end;
  align-items: end;
}
.container .item {
  width: 100px;
  height: 100px;
  border: 2px solid;
  background-color: orange;
}

end

 

grid-template-areas

grid-template-ares는 grid-area를 통해 영역에 이름을 부여한 뒤 제어할 수 있는 속성이다.

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(4, 100px);
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas: 
    "header header header"
    "main main aside"
    ". . aside"
    "footer footer footer";
}
.container > * {
  border: 2px solid;
}
.container header { grid-area: header; }
.container main { grid-area: main; }
.container aside { grid-area: aside; }
.container footer { grid-area: footer; }

큰 따옴표로 감싸진 영역이 하나의 행이라고 보면 된다.

마침표(.) 대신 none을 입력해도 된다. 

 

grid-gap

grid-gap아이템과 아이템 사이의 간격, 즉 여백을 줄 때 사용한다. 

이러한 여백을 그리드에서는 라인 혹은 거터라고 부른다.

.container {
  border: 4px solid;
  display: grid;
  grid-template-rows: repeat(4, 100px);
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas: 
    "header header header"
    "main main aside"
    ". . aside"
    "footer footer footer";
/*   grid-gap: 10px 40px; */
  grid-row-gap: 10px;
  grid-column-gap: 40px;
}
.container > * {
  border: 2px solid;
}
.container header { grid-area: header; }
.container main { grid-area: main; }
.container aside { grid-area: aside; }
.container footer { grid-area: footer; }

grid-gap에 두 값을 적으면 각각 행과 행 사이, 열과 열 사이의 여백 크기를 지정한다.

만일 값을 하나만 적으면 둘 다 한 번에 제어한다.

 

grid-gap이라는 단축 속성을 grid-row-gapgrid-column-gap이라는 개별 속성으로 정의할 수도 있다.

이 속성들은 앞에 있는 grid 키워드를 제거하고 사용할 수도 있다. 

 


출처: 프로그래머스 프론트엔드 데브코스 

[Day 29] CSS 심화 (1)

복사했습니다!