이번 주차에서는 크게 Flex-box에 대한 내용을 다뤘다.
수업을 시작하기에 앞서, 과제에 대한 피드백을 받았고 그 내용은 다음과 같다.
과제 피드백
- 전반적으로 디자인에 대한 해석(임의 판단)이 과하게 진행된 것 같다.
- 브라우저 환경에 대한 유동성이 너무 커서, 주어진 디자인 시안과 크게 달라지는 문제가 있다.
- 학습하는 과정에서, 다양한 관점으로 디자인을 바라보고 구현해보는 것은 매우 바람직해보인다.
이번 과제는 내가 코드를 구현하면서 고민했던 부분과 콘텐츠 확장 시 어떤 방향으로 구현을 하려 했는 등을 정리해서 함께 제출했다.
물론 그 과정을 기록하고 문서화하는 과정에서 조금 매끄럽지 못한 부분도 있었지만, 이런 과정들을 기록하고 전달하는 습관을 유지했으면 좋겠다는 의견을 들었다.
동일한 시안에 대해서, 몇 가지 제약사항을 둔 후에 다시 구현하는 것이 이번 주차 첫 번째 과제이다.
제약사항은 아래와 같다.
- grid 사용 금지
- position : absolute 금지 (제목 밑줄 부분 제외)
- border-radius가 들어간 text-decoration (보기에) box-shadow로 구현해보기
- width 사용 금지
flex-box 세상에서 width는 사용하지 않아도 된다고 하셨는데... 과제를 해보면서 많은 것들을 고민하고 또 배울 수 있을 것 같다.
걱정되면서도 또 기대가 된다.
그럼 왜 flex-box 세상에서 width가 없어도 되는지, 본격적으로 이번 주차 수업을 돌아보자.
display : flex
flex 속성을 통해 아이템을 배치하고 싶다면, 배치하고 싶은 대상의 직계 부모에 display : flex를 주면 된다.
이때 직계 부모는 flex-container이 되고, 배치되는 자식 요소는 flex-items가 된다.
기본적으로 특별히 속성을 지정해주지 않는 경우, jutify-content의 초기값(flex-start)에 의해 왼쪽에서 시작하게 된다.
flex-start와 start의 차이점
justify-content나 align-items 등에서 사용하는 속성 값 중 하나인, flex-start와 그냥 start의 차이는 무엇일까?
flex-start
1) 정렬 기준
flex 컨테이너의 시작점으로 아이템들을 정렬한다. 만약, 주 축이 수평(row)일때, flex-start는 왼쪽 끝을 의미하고, 주 축이 수직(column)일 때는 위쪽 끝을 의미한다.
2) 사용 속성
주로 ' justify-content '나 ' align-items ', ' align-content ' 속성에서 사용한다.
start
1) 정렬 기준
flex 컨테이너의 시작점을 기준으로 정렬하는데, 이는 방향성(글쓰기 모드 등)에 따라 달라질 수 있다. writing-mode에 따라 왼쪽-오른쪽이나 오른쪽-왼쪽으로 변경될 수 있다.
2) 사용 속성
주로 ' align-self ', ' align-items ', ' justify-self ', ' justify-items ' 속성에서 사용한다.
flex-start : flex 컨테이너의 고정된 시작점 (기본 왼쪽 상단)을 기준으로 정렬
start : 컨테이너의 방향성에 따라 시작점이 달라질 수 있으며, 보다 유연한 정렬 옵션
지금부터는 flex를 이해하기 위해서 가장 중요한 세 가지 속성에 대해 정리해보려고 한다.
그 세 가지는 flex 단축 속성이 어떤 것들로 이루어져 있는지 보면 알 수 있다.
.element {
flex : (grow) (shrink) (basis);
flex : 1 ;
/** flex : grow 1 shrink 1 basis auto*/
}
이처럼 flex는 ' flex-grow ', ' flex-shrink ' , ' flex-basis '를 축약해놓은 단축 속성이다.
본격적으로 이 속성들이 어떻게 동작하는지 알아보자.
flex-basis : auto (initial value)
: 기본이 되는 값, 기준이 되는 값으로 flex-items의 width를 결정한다.
-> 특별히 값을 입력하지 않으면 내부 콘텐츠 크기 만큼으로 자동 계산되어 진다.
body {
background-color: brown;
}
.playground {
border: 10px solid maroon;
width: 980px;
margin: 0 auto;
border-radius: 20px;
background-color: skyblue;
padding: 10px;
display: flex; /** 직계 부모 요소에 flex 속성 부여 */
}
.frog {
background-color: mediumseagreen;
color: lime;
font-size: 40px;
border: 6px solid green;
border-radius: 10px;
flex-basis: 200px; /** 200px로 flex-items의 width 설정 */
}
이렇게, flex-items에 flex-basis를 통해서 200px을 주자, 그 요소가 200px만큼 커진 것을 볼 수 있다.
하지만, flex-basis에 0은 물론이고, 현재 콘텐츠 너비인 93px보다 작은 값을 넣어주면 적용되지 않는다.
그 이유는 flex-items의 min-width : auto가 내부 콘텐츠 요소 만큼으로 계산되기 때문이다. flex-basis로 값을 지정해주려고 해도, 그 이하로 내려가지 않는 것이다.
그렇기 때문에 flex-basis와 함께 min-width를 0으로 만들어주면 우리의 생각대로 적용이 된다.
작은 너비를 가지게 해주는 또 다른 방법은 그냥 width로 값을 입력해주는 것이다. width는 min-width까지 바꿔주기 때문에 바로 적용시킬 수 있다.
❗ 주의할 점
- flex-basis와 width를 모두 주면, flex-basis가 적용된다. => flex-basis의 우선순위가 더 높다.
- flex-basis를 주지 않고, width만 주면 flex-basis가 width의 값을 가져와서 가지고 있게 된다.
flex-items의 공간 활용
위에서 언급했듯, 배치되는 자식 요소들을 flex-items라고 한다. 이때 flex-items들은 기존에 inline 요소였건, block 요소였건 상관없이 모두 flex-box 안에 들어오게 된다.
그리고 이 요소들은 자신들의 콘텐츠 영역 외의 남는 영역을 서로 공유하게 되는데, 이를 이용하여 콘텐츠의 크기를 유동적으로 지정해줄 수 있다.
그리고 이때 활용되는 것이 바로, flex-grow와 flex-shrink이다.
flex-grow : 0 (initial value)
: flex-basis에 중심 축 방향의 공간을 그 비율에 맞게 채우는 것 = flex-basis + a
** 이때 여기서 말하는 공간은 부모요소의 콘텐츠 영역을 기준으로 계산된 사용 가능한 공간 (padding, margin을 제외한 공간)이다.
그럼에도 잘 이해가 되지 않는다면,
아래의 코드와 이미지를 보고 제대로 이해해보자.
<!DOCTYPE html>
<html>
<head>
<title>Flexing</title>
<style>
body {
background-color: brown;
}
.playground {
border: 10px solid maroon;
width: 980px;
margin: 0 auto;
border-radius: 20px;
background-color: skyblue;
padding: 10px;
display: flex;
}
.frog {
background-color: mediumseagreen;
color: lime;
font-size: 40px;
border: 6px solid green;
border-radius: 10px;
flex-grow: 1; /** 사용 가능한 공간을 frog들이 1 : 1 : 1의 비율로 채워지게 된다. */
}
</style>
</head>
<body>
<div class="playground">
<div class="frog">Frog</div>
<div class="frog">Frog</div>
<div class="frog">Frog</div>
</div>
</body>
</html>
playground 클래스를 가진 부모 요소에 flex 속성을 준 후, frog라는 클래스 요소들을 제어해주고 있다.
flex-grow를 1로 주었고, flex-items는 3개이기 때문에 1: 1: 1의 비율로 공간을 채워주게 될 것이다.
여기서 한 가지 더, 내부 콘텐츠의 크기가 제각각이라면 어떻게 될까?
그래도 위와 동일하게 적용될 것 같은가?
안타깝게도 그렇지 않다. 왜 그런 것인지 정의를 다시 한 번 읽어보면서 생각해보자.
flex-basis에 중심 축 방향의 공간을 그 비율에 맞게 채우는 것
지금 flex-basis는 어떻게 되어 있을까? 자동으로 설정된 min-width (콘텐츠의 크기)와 같을 것이다.
그럼 어떻게 해야할 것 같은가? 한 번 생각해보고 아래의 글을 확인해보자
정답은 flex-basis를 0으로 주는 것이다.
답을 맞췄다면 축하한다 !! flex-basis와 flex-grow의 원리에 대해 이해하게 된 것이다 !!
그럼 flex-basis : 0을 추가한 결과를 확인해보자
우리가 생각한 대로, 1 : 1 : 1의 비율을 갖게 되었다.
편안하다
이렇게 flex-basis와 flex-grow에 대해서 알아보았는데 마지막으로 flex-shrink에 대해서 알아보자.
flex-shrink : 1 (initial value)
: 요소의 너비가 결정되었지만, 사용할 수 있는 공간의 부족으로 불가피하게 줄어들어야할 때 줄어드는 비율
flex-basis : 200px인 요소 6개가 1000px인 flex-container에 들어가기 위해서는 1000 / 6으로 너비가 줄어들어야 한다. 그 때, 각 각의 요소가 줄어드는 비율이 flex-shrink이다.
그래도 이해가 되지 않으면, 아래의 과정을 따라가보자.
flex-basis가 200px인 frog 클래스 세 개가 있다. 처음의 모습은 아래와 같을 것이다.
하지만, 여기서 flex-items의 개수가 여섯 개로 늘어난다면 어떻게 될까?
width가 flex-basis로 지정한 200px(+padding)에서 163px로(padding이 더해진) 줄어든 것을 볼 수 있다.
flex-shrink의 초기값인 1에 의해서 넘쳐진 245px이 각 각 49px 49px 49px 49px 49px씩 공평하게 줄어든 것이다.
만약, 두 번째 요소는 공간이 부족해도 지정한 flex-basis를 지키도록 해주고 싶다면, 해당 flex-item에 flex-shrink : 0; 을 추가해주면 된다.
마무리하며
이렇게, flex에 대한 중요한 개념 세 가지를 정리하면서 이번 주차 강의 내용에 대한 회고를 진행해보았다.
글로만 정리하기엔, 이해하기 쉽지 않을 개념들이었기 때문에 사용 예시와 함께 설명했다.
그럼에도 이 내용이 이해가 잘 되지 않는 부분이 있다면 댓글로 질문을 마구마구 남겨주길 바란다.
그럼 오늘은 이만
안뇽 ~!
'💘CSS' 카테고리의 다른 글
[VimCamp] 빔 캠프를 마치며 (0) | 2024.07.07 |
---|---|
[Vim Camp] 2주차 수업 회고 (0) | 2024.06.10 |
[CSS] CSS 필수 개념을 알아보자 :) (0) | 2024.05.20 |