CodeState

2021. 08 .03 CSS 그 두번째 시간

리용쓰 2021. 8. 4. 01:23

CSS 

이번 시간엔 layout 그리고 flex-box 에 대해 공부해보았다.

물론 어렵고 심오하며 어떻게 하면 되는 지 아직 감이 오진 않지만 이번 블로그를 작성하며 정리해보고자 한다.

저번 시간엔  css selector 와 절대단위 , 상대단위 그리고 box-size ,box model 을 배웠다.

이번엔 그것들을 이용해 layout을 만들고 거기에 새롭게 배우는 flex-box를 적용시켜 moke up 을 만들어보자.

 

CSS selector의 다양한 규칙들

layout을 만들어 보기 앞서 selector의 규칙들을 좀 더 살펴보고 가자.

꼭 기억해 둬야 할점은 바로 후손 셀렉터와 자식 셀렉터의 차이점이다.

셀렉터에는 부모 셀렉터, 자손 셀렉터, 후손 셀렉터, 형제 셀렉터 등등이 존재 하는데 이 차이점을 아는 것은 css에서 굉장히 중요하다.

[그림 1] 자손 셀렉터 (출처 : https://www.nextree.co.kr/p8468/)

지금 보는 그림은 자손 셀렉터를 보여주는 그림이다. 부모 셀렉터인 section 밑에 소속된 ul 과 p 태그가 자식 셀렉터이다.

그렇다면 후손 셀렉터는 무엇일까. section 아래 모든 태그가 후손 셀렉터 이다. 후손 셀렉터는 다른 말로 자손 혹은 하위 셀렉터 

라고도 불린다. 

[그림 2]후손 셀렉터 (출처 : https://www.nextree.co.kr/p8468/)

예제를 살펴보자

/* 자식 셀렉터 */
section > ul { }

/*후손 셀렉터*/
section li { }

형제 셀렉터는 같은 부모를 가지는 셀렉터를 말한다. 형제 셀렉터는 인접 형제 셀렉터와 일반 형제 셀렉터로 나뉜다.

먼저 나오는 요소가 형 요소 그리고 나중에 나오는 그러니까 뒤에 나오는 요소부터는 동생 요소들이다.

인접 형제 셀렉터는 형제중 첫번째 동생 요소가 조건을 충족시킬때에만 스타일을 적용시킨다. 일반 형제 셀렉터는 모든 동생 셀렉터에

스타일을 적용시킨다

[그림 3] 인접 형제 셀렉터 (출처 : https://www.nextree.co.kr/p8468/)
[그림 4] 일반 형제 셀렉터 (출처 : https://www.nextree.co.kr/p8468/)

예제로 보자

/*인접 형제 셀렉터*/
h1 + ul { } 

/*일반 형제 셀렉터*/
h1 ~ ul { }

 

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

HTML은 위에서 아래로 , 좌에서 우로 진행된다. CSS에서는 수직 분할과 수평 분할로 나뉜다.

수직 분할은 화면을 수직으로 분할하여, 콘텐츠가 가로로 배치 될 수 있도록 요소를 배치한다.

수평 분할은 수직 분할과 반대로 분할된 각각의 요소를 수평으로 구분하여, 내부의 요소가 세로로 배치 될 수 있도록 요소를 배치한다.

  • 수평으로 구분된 요소에 height 속성을 추가하면, 수평분할을 보다 직관적으로 할 수 있습니다.

레이아웃 리섯

HTML 문서는 기본적인 스타일을 가지고 있다. 때때로 그 스타일 때문에 레이아웃을 만드는데 방해가 되고는 한다.

그러면 어떠한 점들이 방해를 하는걸까

  • 박스의 시작을 정확히 (0,0)에서 시작하고 싶은데, <body> 태그가 가지는 기본적인 여백이 존재한다.
  • width, hight가 여백을 가지지 않아 계산을 하는데 어려움이 있다
  • 브라우져 마다 여백이나 글꼴과 같은 기본적인 스타일이 다르다.

이렇게 방해되는 요소들이 있을때 해결 하기 위해 라이브러리들이 존재하지만 굳이 라이브러리를 쓰지 않고 몇줄의 코드면 해결 할 수 있다.

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

이렇게 몇줄의 코드로 기본적인 스타일을 제거하고 디자인 한 레이아웃 그대로 사용이 가능하다.

 

 

Flexbox

flex는 "잘구부러지는 " ,"유연한" 이란 뜻이 있다. flexbox도 마찬가지로 유연하고 잘 구부러지게 만들 수 있다. flexbox로 레이아웃을 만들면 유연하고 잘 늘어나고 줄어드는 레이아웃을 만들 수 있다.

flexbox로 레이아웃을 만드는 첫째는

display : flex

display : flex 를 적용하는 것이다. display : flex는 부모요소에 적용 시켜 자식 박스의 방향과 크기를 결정하는 레이아웃 구성이다.

기본적으로 display : flex 가 적용된 부모 박스의 자식들은 왼쪽에서 차례대로 이어 배치된다.

 

flex-direction : flex 박스의 방향 지정하기

flexbox는 수직으로 분할 되는 것이 기본 값이다. 그렇지만 방향을 설정해주면 수평으로도 분할이 가능하다. flex-direction 는 부모 요소에 적용한다. 자식 요소에 특별한 값을 주지 않아도 부모 요소로 flex-direction 를 설정해 주면 자식 요소에도 적용 된다.

flex-direction 는 

  • row(기본값) : 수직 분할
  • column :  수평 분할

참고로

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

grow (팽창 지수), shrink(수축 지수), basis(기본 크기)

자식 박스에 어떠한 설정도 해주지 않는다면 왼쪽부터 오른쪽으로 콘텐츠의 크기 만큼 배치된다. 

자식의 flex 요소를 설정해 주지 않는다면 flex : 0 1 auto 라는 값이 디폴트로 설정된다.

flex : 0 1 auto 는 어떤 값일까.

flex의 세가지 요소는 margin 이나 padding 처럼 띄어쓰기 기준으로 의미를 구분 할 수 있다.

그러나 margin 이나 padding 과는 다르게 flex는 기본값을 바탕으로 줄이거나 늘리거나 하는 것으로 박스의 크기를 만들 수 있다.

  • flex : <grow> <shrink> <basis> -> flex : 0 1 auto

이렇게 첫번째로는 grow 두번째는 shrink 세번째는 기본값인 basis가 있다.

grow , shrink는 단위가 없고 비율에 따라 크기가 결정된다.

 

grow  : 늘어나라 자식아

만약 자식 박스이 값을 flex : 1 1 auto 라고 설정해 줬다면 박스 크기는 어떻게 될까

먼저 target 이라는 자식 클래스에 flex : 1 1 auto 를 설정해준다. 다른 box 클래스는 grow 값이 0 이므로

1+0+0 = 1 이다. 이말은 1/1 그러니까 100% 라는 의미와 같다. 그러나 이미 box 클래스엔 콘텐츠가 있으므로 그것을 제외한

나머지 공간을 모두 차지 한다.

.target .box .box

그렇다면 이번엔 box 클래스에도 grow 값을 1을 준다면 어떻게 될까? target 에 1 box 에 각각 1이 있으므로 1+1+1 =3 이다.

고로 1/3 씩 공간을 차지 하게 된다.

그렇다면 이번엔 targe에 2를 준다면? 2+1+1 =4 이다. 그래서 target은 2/4 나머지는 1/4씩 공간을 차지한다.

이렇게 grow와 shrink는 비율로서 공간이 결정된다

 

shrink : 줄어들어라 자식아

shrink는 grow와 반대로 박스를 비율만큼 줄어들게 만든다. 하지만 grow와 shrink는 동시에 사용하는걸 권장 하지 않는다.

비율로 박스를 만들때 grow를 쓰거나 flex : <grow> 1 auto 와 같이 grow 속성을 변화 시키는 방법이 권장된다.

그 이유는 width 나 basis의 따른 비율이므로 실제 크기를 예측 하기 어렵기 때문이다.

박스를 grow로 비율에 따라 늘려주려고 한다면 shrink 값을 1로 두어도 무방하다.

 

basis : 자식의 기본값

grow 나 shink 가 설정되기 전 박스가 가지는 기본적인 크기를 말한다. grow가 0일때 박스는 basis의 값대로 크기가 결정된다.

기억해야 할점은 grow 가 0일때만 basis의 값이 유지가 된다. flex-grow 속성의 값이 1 이상인 경우, flex-basis 속성에 적용한 값보다 커질 수도 있다. 실제 레이아웃을 구현하면서 막히는경우는 다음 원리를 보고 참고 할 수 있다.

 

참고

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

 

콘텐츠를 정렬하자.

콘텐츠를 정렬 하는 방법에 앞서서 axis(축)에 대한 이해가 필요하다. axis는 main axis 와 cross axis 로 구분된다.

만약 flex-direction 이 row 기본값이라면 main axis은 가로축이 될 것이다.

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

axis를 기준으로 정렬 할 수 있는 속성으로는 justify-content align-items 가 있다.

justify-content는 main axis 를 기준으로 하고 align-items 는 cross-axis를 기준으로 한다.

  • 만약 flex-direction이 column 이라면 수평 분할 이므로 main axis는 세로축 cross axis 는 가로축이 된다.

justify-content : 콘텐츠의 수평 정렬

부모 박스에 justify-content를 주면 자식 박스에 적용된다. 다음은 정렬을 위한 옵션들이다.

  • flex-start :요소들을 컨테이너의 왼쪽으로 정렬 (기본값)
  • flex-end : 요소들을 컨테이너의 우측으로 정렬
  • center : 요소들을 컨테이너의 중앙으로 정렬
  • space-between : 요소들 사이에 동일한 간격을 둡니다.
  • space-around : 요소들 주위에 동일한 간격을 둡니다.

align-items : 콘턴츠의 수직 정렬

부모박스에 align-items를 주면 자식 박스에 수직으로 적용된다. 다음은 정렬을 위한 옵션이다.

  • flex-start :  컨테이너의 최상단으로 정렬 합니다.
  • flex-end : 컨테이너의 최하단으로 정렬합니다.
  • center : 컨테이너의 세로 축의 중앙으로 정렬 합니다.
  • stretch : 컨테이너의 맞게  늘립니다.(기본값)
  • baseline : 컨테이너의 시작위치에 정렬 합니다.

공부를 위한 사이트 하나를 추천한다.

https://flexboxfroggy.com/#ko