[TIL] 2022-04-29/05-01 / 29, 30일차
미음제
·2022. 5. 2. 16:48
오늘 배운 내용
CSS
CSS float
float 속성은 과거 수평 정렬을 위해 많이 사용했는데, 최근 1차원 레이아웃 구조를 만들 때 flex 기술이 있어 수평 정렬을 위해 float 속성을 사용하는 빈도가 많이 줄었다. 과거에 작성된 프로젝트에 float으로 수평 레이아웃이 짜인 프로젝트가 종종 있을 수 있다.
float 요소를 사용하기 위해서는 float 요소만을 사용해야 한다. html tag를 작성하면 위에서 아래로 구성된다. 구성되는 item을 수평으로 정렬하기 위해 float 속성을 사용한다.
<div class="container">
<div>
<div class="item float">1</div>
<div class="item float">2</div>
<div class="item float">3</div>
</div>
</div>
// CSS
.container {
border: 4px solid;
}
.container .item {
width: 100px;
height: 100px;
background-color: royalblue;
border-radius: 10px;
font-size: 40px;
margin: 10px;
}
.float {
float: left;
}
이렇게 CSS를 작성하면 float item 3개가 수평으로 정렬된다. float: left를 통해 주축의 시작점부터 item을 정렬해 그리는 것이다. 그러나 float이 아닌 요소를 사용하면 레이아웃이 겹치게 된다.
<div class="container clearfix">
<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>
// CSS
.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;
}
4번째 item이 겹치게 나오는 것을 확인할 수 있다. ::after 가상요소를 사용하면 float이 아닌 요소가 레이아웃이 겹치지 않고 정렬된다.
<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>
// CSS
.clearfix::after {
content: "";
display: block;
clear: both;
}
inline vs block
- block : 수직으로 요소가 쌓이고, 가로의 넓이가 '최대한 늘어나려고' 함
- inline : 수평으로 요소가 쌓이고, 가로의 넓이가 '최대한 줄어드려고' 함
float, posion(absolute, fixed)를 사용하면 display inline이 block 속성으로 바뀌게 된다.
CSS flex
1차원 정렬을 만들고자 하는 각각의 아이템의 부모 요소에 display 속성(flex, inline-flex)을 부여한다. display: flex 속성을 부여한 것을 flex-container라고 하고, 그 속에 속한 자식 요소(item)들은 자연스럽게 flex-items가 된다.
flex-direction: row, column
flex-container의 자식 요소들의 정렬 축(주축 = main-axis)을 지정하는 속성이다. row는 아이템을 행(x 축)으로 정렬하고, column은 열(y 축)으로 정렬한다. row-reverse와 column-reverse를 통해 정렬의 순서를 역순으로 바꿀 수 있다.
flex-wrap
기본 값은 nowrap. flex-wrap: wrap으로 변경하면 width를 초과한 item들이 줄 바꿈이 된다. 이때 줄 바꿈이 되어 나오는 것이 첫 번째 줄의 item의 바로 밑으로 붙는 것이 아니라 간격이 조금 있는 것처럼 나오는데, container의 높이를 절반으로 나누고 두 번째 줄에 item을 옮겨 사용했기 때문이다.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
// CSS
.container {
border: 2px solid;
width: 350px;
height: 400px;
display: flex;
flex-wrap: wrap;
}
.container .item {
border: 1px solid;
width: 100px;
height: 100px;
background-color: yellow;
font-size: 30px;
}
이렇게 item이 width 내에 전부 들어온 경우 display: flex 속성때문에 가로로 정렬된 것을 볼 수 있다. 여기에 4번째 아이템을 container에 추가해 보면, 줄 바꿈이 이상하게 되는 것을 볼 수 있다.
// CSS
.container {
border: 2px solid;
width: 350px;
height: 400px;
display: flex;
flex-wrap: wrap;
align-content: start;
}
.container .item {
border: 1px solid;
width: 100px;
height: 100px;
background-color: yellow;
font-size: 30px;
}
flex-container에 align-item: start 속성을 부여하면 줄바꿈 된 item이 바로 밑으로 정렬된 것을 볼 수 있다. align keword가 붙은 것은 교차축(현재 예제에서는 y 축)에 대한 정렬 기준을 지정한다.
justify-conent
flex-direction으로 정의한 주 축에 대한 정렬을 지정한다.
.container {
border: 2px solid;
width: 350px;
height: 400px;
display: flex;
justify-content: flex-start; /* flex-start, flex-end, center, space-between, space-around */
}
.container .item {
border: 1px solid;
width: 100px;
height: 100px;
background-color: yellow;
font-size: 30px;
}
- flex-start : 기본 값으로 주 축의 시작점으로 부터 정렬한다
- flex-end : 주 축의 끝지점부터 정렬한다.
- center : 주 축의 가운데 정렬을 한다.
- space-between : 첫 번째와 마지막 아이템을 가장 끝점에 두고 균등하게 분배한다.
- space-around : 각 아이템의 좌우 공간을 균등하게 분배한다.
align-items, align-content
justify-content가 주 축에 대한 정렬이라면 align keyword가 붙은 속성은 주 축의 교차 축에 대한 정렬이다.
.container {
border: 2px solid;
width: 350px;
height: 400px;
display: flex;
justify-content: flex-start;
align-items: stretch; /* stretch, flex-start, flex-end, center, baseline */
}
.container .item {
border: 1px solid;
width: 100px;
height: 100px;
background-color: yellow;
font-size: 30px;
}
- stetch : 기본 값으로 flex-items의 요소가 height가 지정되어 있지 않는 경우 flex-container의 높이와 동일하게 설정되고 배치된다.
- flex-start : 교차 축의 시작 지점으로부터 정렬된다.
- flex-end : 교차 축의 끝 지점으로부터 정렬된다.
- center : 교차 축의 가운데 정렬을 한다.
- baseline : flex-container의 기준선으로 정렬된다. stretch나 flex-start처럼 나오는데, 문자 기준선을 맞춰서 정렬(글자가 가지고 있는 기준선을 기준으로 y축에 정렬) -> flex를 사용할 때 박스의 레이아웃 보다 글자를 기준으로 교차축 정렬을 할 때 유용하다.
align-items는 한 줄에 대한 정렬을 지정하는 반면, align-content는 flex items가 두 줄 이상일 때 전체 줄을 통째로 정렬한다.
// CSS
.container {
border: 2px solid;
width: 350px;
height: 400px;
display: flex;
/* flex-wrap: wrap; */
justify-content: flex-start;
align-content: center;
}
.container .item {
border: 1px solid;
width: 100px;
height: 100px;
background-color: yellow;
font-size: 30px;
}
flex item이 줄 바꿈이 정의되어 있지 않은 경우, align-content는 유효하지 않은 속성이다.
flex items 속성
- flex-grow : flex item의 증가 너비 비율을 설정한다. 기본 값 = 0
- flex-shrink : flex item의 감소 너비 비율을 설정한다. 기본 값 = 1
- flex-basis : flex item의 기본 너비를 지정한다. 기존의 width 값을 무시하고 flex-basis의 설정값으로 출력된다. 기본 값 = auto
- flex : 단축 속성으로, 위 상위 3개의 속성을 한 번에 사용할 수 있다.
- order : flex item의 순서를 지정한다. 기본 값 = 0. order 속성의 숫자가 증가할수록 뒤로 밀려난다. 숫자가 작을수록 앞으로 배치되고 클수록 되로 배치된다. 음수 값도 지정이 가능하다.
- align-self : flex-container에 지정하는 align-items 속성을 개별 flex item에 지정할 수 있는 속성이다.
CSS Grid
<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>
// CSS
.container {
border: 4px solid;
display: grid; /* inline-grid */
grid-template-rows: 100px 100px;
grid-template-columns: 200px 200px 200px;
}
.container .item {
border: 2px solid;
font-size: 30px;
}
flex 속성이 1차원의 레이아웃 구조를 잡는 것이라면, grid 속성은 2차원의 레이아웃 구조를 만드는 것이다. display: grid속성을 통해 gird 구조를 만들 수 있고, inline-grid속성을 통해 display: inline-block와 동일한 효과를 나타낼 수 있다. grid-template-rows/colums를 통해 행렬 구조의 grid 레이아웃을 만들 수 있다. 각각 속성 값으로 입력값을 띄어쓰기 단위로 구분하고, 띄어쓰기 한 번에 한 개의 행과 열이 추가되는 구조이다. rows와 column에 지정한 값은 각 행과 열의 크기를 지정해 준 것이다.
grid fraction
fraction은 fr로 사용할 수 있고, 공간의 비율을 의미한다. 공간은 grid-container의 사용 가능한 나머지 공간의 공간 너비 비율을 말한다.
.container {
border: 4px solid;
display: grid;
grid-template-rows: 50px 50px;
grid-template-columns: 1fr 2fr 1fr;
}
.container .item {
border: 2px solid;
font-size: 30px;
background-color: yellow;
}
1 행과 2 행은 50px의 크기를 갖도록 지정하고, 1 열은 1fr, 2 열은 2fr, 3 열은 1fr 비율로 크기를 갖도록 지정한다.
grid repeat() 함수
.container {
border: 4px solid;
display: grid;
grid-template-rows: 50px 50px;
grid-template-columns: repeat(3, 1fr);
}
.container .item {
border: 2px solid;
font-size: 30px;
background-color: yellow;
}
repeat() 함수를 통해 반복을 나타낼 수 있다. 행과 열을 많이 만들어야 한다고 했을 때, 모든 값을 입력하는 것은 번거로운 일이다. repeat() 함수의 첫 번째 인자를 통해 몇 번 반복할 것인지 지정할 수 있고, 반복할 크기를 두 번째 인자로 지정할 수 있다. columns의 크기를 1fr 비율로 지정하고 3개의 columns를 지정한 것이다.
grid 명시적, 암시적 rows/columns
<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 class="item">6</div>
<div class="item">7</div>
</div>
// CSS
.container {
border: 4px solid;
display: grid;
grid-template-rows: repeat(2, 200px);
grid-template-columns: repeat(2, 1fr);
/* grid-auto-rows: 100px; */
}
.container .item {
border: 2px solid;
font-size: 30px;
background-color: yellow;
}
grid-template-rows와 grid-template-columns를 통해 명시적 grid를 지정했다. 2 * 2의 grid 형태이고, rows는 각각 200px의 크기를 colums는 1fr 비율을 갖도록 지정되어 있다. 2 * 2 grid 레이아웃 구조이기 때문에, 5, 6, 7번 item들은 크기가 지정되어 있지 않은 상태이다. 이때 (주석처리되어 있는) 암시적 rows를 정의해주면, 명시적으로 지정한 레이아웃 이외의 item들이 어떻게 추가될지 지정해줄 수 있다.
grid-auto-flow-dense
// CSS
.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: 1fr;
/* grid-auto-flow: dense; */
}
.container .item {
border: 2px solid;
font-size: 30px;
background-color: yellow;
}
.container .item:nth-child(5) {
grid-column: 2;
}
grid-items의 5번째 요소를 기준선 2번 line에서 시작하도록 배치하면, 아무런 지정이 없었던 때와 달리 4번 item과 5번 item 사이에 공백이 발생한다. item이 정렬될 때 빈 공간이 있는 경우, grid-auto-flow: dense 속성을 사용하면 빈 공간을 매우며 정렬이 된다. 주석 처리되어 있는 곳의 속성을 추가하면 다음처럼 변경된다.
grid-container - justify-content / align-content
<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 class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
.container {
width: 500px;
height: 500px;
border: 4px solid;
display: grid;
grid-template-rows: repeat(3, 70px);
grid-template-columns: repeat(3, 70px);
justify-content: center;
align-content: center;
}
.container .item {
border: 2px solid;
font-size: 20px;
background-color: pink;
}
grid-container 내부에 grid-content를 제외한 빈 공간이 있을 경우에만 사용할 수 있다.
justify-content와 align-content는 flex container에서 사용했던 것과 마찬가지로 justify-content는 주 축에 대한 정렬을, align-content는 교차 축에 대한 정렬을 지정한다.
- normal : 기본 값으로 stretch와 동일하다.
- start : 축의 시작점으로부터 정렬된다.
- center : 축의 가운데 정렬된다.
- end : 축의 끝으로 부터 정렬된다.
- spae-between : 첫 아이템과 마지막 아이템을 양쪽 끝으로 붙이고, 균등하게 분배하여 정렬한다.
- space-around : 아이템의 좌우에 동일한 너비를 갖고 정렬된다.
- sapce-evenly : 동일한 너비로 균등하게 분배된다.
grid-container - justify-items / align-items
grid-container 내부의 items 모두를 지정하는 속성이다.
<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 class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
// CSS
.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;
align-items: end;
}
.container .item {
width: 100px;
height: 100px;
border: 2px solid;
font-size: 30px;
background-color: skyblue;
}
- normal : 기본 값으로 stretch와 동일하다.
- start : 축의 시작점으로부터 정렬된다.
- center : 축의 가운데 정렬된다.
- end : 축의 끝으로부터 정렬된다.
- space keyword : justify-content와 align-content와 달리 space keyword는 사용할 수 없다. grid-container의 개별 item은 하나의 cell(행, 열의 한 칸)에 들어가 있는 것이다. cell 내부에는 하나의 item 밖에 없기 때문에 space keyword는 사용할 수 없다.
gird-items - justify-self / align-self
<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 class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
// CSS
.container {
width: 500px;
height: 500px;
border: 4px solid;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
justify-items: normal;
align-items: normal;
}
.container .item {
width: 100px;
height: 100px;
border: 2px solid;
font-size: 30px;
background-color: skyblue;
}
.container .item:nth-child(1) {
background-color : orange;
justify-self: center;
}
.container .item:nth-child(2) {
background-color : white;
align-self: center;
}
.container .item:nth-child(3) {
background-color : yellow;
justify-self: end;
align-self: center
}
.container .item:nth-child(4) {
background-color : green;
justify-self: start;
align-self: end;
}
.container .item:nth-child(8) {
background-color : pink;
order: 1
}
grid-container의 여러 cell 내부의 item의 크기가 cell 보다 작은 경우에만 사용할 수 있다. grid-container에서 각 item에 지정하던 justify-content와 align-content 속성을 개별 item에 직접 지정할 수 있는 속성이다.
- normal : 기본 값으로 stretch와 동일하다
- start : 축의 시작점으로부터 정렬된다.
- center : 축의 가운데 정렬된다.
- end : 축의 끝으로부터 정렬된다.
- order : 숫자가 작을수록 앞으로, 클수록 뒤로 정렬된다.
grid 함수
grid container에서 사용하는 함수이다.
repeat(횟수, 너비)
첫 번째 요소로 몇 번 반복할지 지정하고, 두 번째 요소로 너비를 지정할 수 있다. (위에 있는 grid 기본 구조에서 사용)
minmax(최소 너비, 최대 너비)
행과 열의 최소 너비와 최대 너비를 지정할 수 있다. 화면의 변화가 있을 때, 최소 너비보다 줄어들지 않고, 최대 너비보다 커지지 않는다.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
// CSS
.container {
border: 4px solid;
display: grid;
grid-template-rows: repeat(2, 100px);
grid-template-columns: minmax(100px, 1fr) minmax(300px, 1fr)
}
.container .item {
border: 2px solid;
background-color: green;
font-size: 20px;
}
암시적 row/column 속성에도 minmax를 지정할 수 있다. 암시적으로 생성된 item의 크기가 지정한 행의 크기보다 큰 경우 레이아웃 구조에서 오류가 생기는 것을 볼 수 있다. 새로운 5번 item을 추가하고, css를 다음과 같이 바꾼 후 확인하면 다음과 같다.
// CSS
.container {
border: 4px solid;
display: grid;
grid-template-rows: repeat(2, 100px);
grid-template-columns: 100px 200px;
grid-auto-rows: 100px;
}
.container .item {
border: 2px solid;
background-color: skyblue;
font-size: 20px;
}
.container .item:nth-child(3) {
height: 200px;
grid-row: 3;
}
암시적으로 생성된 행보다 item의 height가 커서 레이아웃에 오류가 있는 것을 확인할 수 있다. 이때 암시적 행에 minmax 값으로 최소 너비로 100px를 지정하고 최대 너비를 auto로 지정해주면 다음과 같다.
.container {
border: 4px solid;
display: grid;
grid-template-rows: repeat(2, 100px);
grid-template-columns: 100px 200px;
grid-auto-rows: minmax(100px, auto);
}
.container .item {
border: 2px solid;
background-color: skyblue;
font-size: 20px;
}
.container .item:nth-child(3) {
height: 200px;
grid-row: 3;
}
min-content / max-content
<div class="container">
<div class="item">something else!</div>
<div class="item">great cat</div>
<div class="item">한글은 어때?</div>
<div class="item">Everydaytonkatsu</div>
</div>
// CSS
.container {
border: 4px solid;
display: grid;
grid-template-rows: 100px;
grid-template-columns: repeat(4, 100px);
}
.container .item {
border: 2px solid;
background-color: skyblue;
font-size: 30px;
}
column의 크기를 100px로 지정하고 결과를 확인하면 위와 같다. something else나 great cat의 column의 크기보다 큰 경우 단어를 기준으로 줄 바꿈을 하고 있다. 띄어쓰기를 하지 않은 경우 단어 구분이 안되어 한 줄에 초과하여 출력되는 것을 확인할 수 있다. 이때 min-content로 column의 크기를 지정하면 다음과 같다.
// CSS
.container {
border: 4px solid;
display: grid;
grid-template-rows: 100px;
grid-template-columns: repeat(4, min-content);
}
.container .item {
border: 2px solid;
background-color: skyblue;
font-size: 30px;
}
column의 너비가 content의 최솟값만큼 지정된다. 한글의 경우 단어 구분이 아닌 글자를 기준으로 구분하고, 영어는 단어를 기준으로 구분하여 최소한의 크기만큼 지정된다. min-content를 사용할 때, 한글도 단어를 기준으로 구분하고 싶다면 gird-items에 word-break: keep-all 속성을 추가해 주면 된다.
// CSS
.container .item {
border: 2px solid;
background-color: skyblue;
font-size: 30px;
word-break: keep-all;
}
min-content와 반대로 max-content는 content의 최대 너비만큼 너비가 지정된다.
auto-fit/ auto-fill
auto-fill과 auto-fit은 repeat() 함수와 같이 사용한다. repeat(횟수, 너비) 함수에서 반복할 횟수를 지정하는 곳에 사용한다. 행, 열의 개수를 grid-container에 맞게 최적화하여 자동으로 개수를 지정한다.
<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 class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
// CSS
.container {
border: 4px solid;
display: grid;
grid-auto-rows: 100px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
.container .item {
border: 2px solid;
background-color: pink;
font-size: 20px;
}
// CSS
.container {
border: 4px solid;
display: grid;
grid-auto-rows: 100px;
/* grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); */
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
.container .item {
border: 2px solid;
background-color: pink;
font-size: 20px;
}
얼핏 보기에 동일해 보이지만 둘의 차이는 다음과 같다.
- auto-fit : 지정할 수 있는 최대 너비를 우선해서 적용 / minmax() 값의 최대 너비를 우선 적용(1fr)
- auto-fill : 지정할 수 있는 최소 너비를 우선해서 적용 / minmax() 값의 최소 너비를 우선 적용(100px)
auto-fit과 auto-fill을 통해 명시적으로 행과 열의 개수를 지정하지 않고 지정할 수 있다.
부족한 점 & 느낀 점
그동안 CSS를 많이 다룰 일이 없었다. 필요한 경우 codepen이나 chrome 확장 툴을 이용해 대충 끼워 맞췄다. 그래서 매번 헷갈리고 적용이 어려웠었다. 가장 헷갈렸던 것이 center로 정렬하기 위해 justify-content를 사용하는지, align-items나 align-content를 사용하는지 몰랐고, display flex를 사용할 때 방향이 바뀌는 이유를 잘 몰랐었는데 이번에 감을 찾은 것 같다. 이번 강의를 통해 가장 중요하다고 느낀 것은 "주 축과 교차 축에 대한 이해"이다. 주 축의 방향이 어디로 설정되어 있는지 파악해야 정렬된 레이아웃을 짤 수 있다고 생각된다. 주 축은 행으로 되어 있는데, 이를 파악하지 못하고 정렬을 지정하면 원하는 결과와 반대로 나오게 되니까 주축에 대한 파악이 우선인 것 같다. 주 축을 잘 파악하기 위해 container와 item이 어떻게 관계를 갖고 있는지 파악하는 것도 중요하다고 생각된다.
'프로그래머스 > 데브코스 프론트엔드' 카테고리의 다른 글
[TIL] 2022-05-27 / 50일차(React - Hook 1) (0) | 2022.05.28 |
---|---|
[TIL] 2022-05-25 / 48일차(React) (0) | 2022.05.25 |
[TIL] 2022-04-28 / 28일차 (0) | 2022.04.29 |
[TIL] 2022-04-26 / 27일차 (0) | 2022.04.26 |
[회고] 노션 클론 프로젝트 회고 / 2022-04-21 / 25일차 (0) | 2022.04.24 |