CSS_레이아웃

송민혁·2023년 9월 9일
1

CSS3

목록 보기
3/3
post-thumbnail

✅ 목차

  • position
  • flexbox
  • grid

position

글의 흐름이랑 상관없이 원하는 위치에 배치하고 싶을 때 사용한다.
포지션으로 위치 기준을 정한 다음에 top, bottom, left, right 속성을 사용하여 원하는 위치에 둔다.

  • static : HTML 요소 원래 흐름, 배치 불가능
  • relative : static에서 배치 조절 가능
  • absolute : 가장 가까운 포지셔닝이 된 조상 요소 기준에서 배치 조절 가능 (포지션닝: 부모 요소가 relative여야 한다.)
  • fixed : 뷰포트 기준
  • sticky : 뷰포트 기준, 임계점 도달하면 변한다.

<position: relative 사용>

.green {
	position: relative;
    top: 30px;
    left: 30px;
}

<position: absolute>

absolute 하면 무조건 포지셔닝 설정 ~~ 원하는 부모 relative!

.red {
	...
	position: relative;
}
.blue {
	...
    position: absolute;
    right: -10px;
    bottom: 20px;
}

✏️ 꿀팁
만약에 부모 요소에 꽉 차게 설정하고 싶다면
1. position: absolute하고 top, bottom, left, right를 0으로 설정하면 된다.
2. 더 쉬운 방법으로는 position: absolute하고 inset: 0;으로 하면 된다.

<응용>

글씨체를 영상 위에 얹고 싶다면
영상 영역을 position: relative 한 뒤에
글씨 묶음 영역을 position: absolute inset: 0으로 설정하면 된다.

뷰포트 기준으로 설정한다.
스크롤을 해도 뷰포트 기준 요소 위치는 변하지 않습니다.

<position: fixed>

그렇다면 fixed는 언제 사용할까?
-> nav bar, ads

.header {
	width: 100%
	position: fixed;
    top: 0px;
    left: 0px;
}

nav를 만들고 body에 nav만큼 margin-top 크기를 설정해줘야 한다.

<position: sticky>

앞서 sticky와 fixed의 차이를 생각해보세요~

지정한 위치로 스크롤되기 전까지는 마치 static 포지션처럼 있다가
지정한 위치에 닿으면 fixed 위치처럼 고정된다.

(즉, 임계 지점이 있다.)

여기서 또 중요한 점!
바로 sticky 포지션은 부모 요소 안에 갇혀 있다.

(이유는 static 속성이 있어서 부모 요소에 소속되어 있다고 이해하면 편하다)

그래서 섹션별로 sticky한 요소를 만들기 위해서 부모 요소로 구분지으면 된다.

<div>
  sticky요소
</div>

z-index

누가 앞으로 튀어나오게 할지 하는 정도의 숫자라고 이해하면 좋다

그래서 z-index가 높을수록 더 앞에 보이는 순서이다.

그렇다면 red가 z-index가 높을까나 blue가 z-index가 높을라나~~~

red가 더 앞으로 튀어나왔으니 z-index가 높겠네!

그림으로 한 번 더 요약해 ~

Flexbox

flexbox는 가로 방향이나 세로 방향으로 배치하고 싶을 때 사용한다.
우리가 수학에서 배우는 2차원 평행이동이라고 생각하면 좋을 것 같다.
그리고 배치 방향도 정할 수 있다.

flexbox로 뭐할 수 있어?

  • 배치 방향 - flex-direction
  • 정렬 - justify-content(주축), align-items(반대축)
  • 요소가 넘칠 때 - flex-wrap
  • 요소 간격 - gap
  • 크기 늘이거나 줄이기 - flex-glow, flex-shrink, flex-basis

(더 자세한 설명을 원한다면 코드잇 flexbox 정리를 살펴보자!)

배치 방향

  • flex-direction: row
  • flex-direction: column
  • reverse도 가능하다!

정렬

main-axioscross-axis를 우선적으로 인지해야 한다.

justify-content 속성

  • center
  • flex-start
  • flex-end
  • space-around
  • space-between
  • space-evenly

align-items 속성

justify-content와 유사

감싸기

요소가 부모 컨테이너에 넘칠 수도 있다. 그래서 요소가 넘친다면 부모 요소 안에 다 넣기 위해서 flexbox의 flex-wrap을 사용하면 좋다.

.parent{
	display: flex;
    flex-wrap: wrap;
    flex-direction: column;
}

간격

플렉스 박스로 납두면 요소들이 나열된다. 근데 요소 마다 일일이 간격을 margin으로 준다면 맨끝 여백은 따로 코드를 작성하는 번거로움이 발생한다. 그래서 우리는 gap을 사용하면 편리함을 얻을 수 있다.

..parent{
	display: flex;
    flex-wrap: wrap;
    gap: 2rem 2rem; 
}

gapgrid와 연관이 있기 때문에 gap: 가로 세로입니다.

요소 채우기

요소를 얼마나 늘릴지 정하려면 flex-grow:0에서 값을 수정하면 된다.
그리고 요소를 얼마나 줄일지 정하려면 flex-shrink:0에서 값을 수정하면 된다.

대부분 두 가지 경우를 많이 사용한다.

  • 요소를 플렉스에 꽉 채우고 싶은 경우
    -> flex-grow:1 (기본값이 0이기 때문에 1로 수정)
  • 요소의 크기를 고정하고 싶은 경우
    -> flex-shrink:0 (기본값이 1이기 때문에 0으로 수정)


flex-grow, flex-shrink, widthflex: 1 0 100px 처럼 한꺼번에 쓸 수 있다!!

그리고 요소의 시작 크기를 정하기 위해서 flex-basis: ()을 이용하면 된다.

예시) 노래 번호가 들어간 박스 요소 width 정하기

.track-number {
  flex-basis: 24px;
}

.track-title {
  flex-grow: 1;
}

.track-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

기타

인라인 플렉스

링크와 버튼을 플렉스박스에 넣어 간격과 정렬을 설정하려고 한다.
근데 display:flex를 하면 블록 요소의 성질을 가지게 되어 의도치 않게 줄바꿈 처리가 된다. (왜냐하면 블록은 한줄만큼 너비를 갖기 때문이다.)

그렇다면 줄바꿈 처리를 안하면서 인라인 안에서 플렉스 박스를 사용하고 싶다면 display: inline-flex라고 설정하면 된다!

position과 flexbox

자기 자신의 원래 위치를 기준으로 배치되는 static(기본값), relative, sticky를 제외하고는 플렉스박스의 흐름에서 벗어나서 배치됩니다. 흐름에서 벗어난다는 건, 플렉스박스 바깥에 있는 요소처럼 동작한다는 건데요.

앞에서 absolutefixed는 원래 자리를 차지하지 않고, 글의 흐름에서 아예 빠졌었죠? 플렉스박스에서도 마찬가지로 플렉스박스의 영향을 받지 않습니다.

플렉스박스에서 벗어나는 경우: absolute, fixed

absolute 포지션은 포지셔닝된 가장 가까운 조상을 기준으로 배치되고, fixed는 브라우저 화면을 기준으로 배치된다.

이 둘의 공통점은 요소의 원래 자리를 차지하지 않는다는 겁니다.
즉, 글의 흐름에서 벗어나는 건데요. 마찬가지로 플렉스박스 안에서도 아예 벗어납니다. 그래서 이런 경우에는 마치 플렉스박스와 상관없는 요소처럼 배치됩니다.

플렉스박스에 배치되는 경우: relative, sticky

relative 포지션은 요소의 원래 위치를 기준으로 배치하는 거라고 했습니다. 일단 플렉스박스 안에서 다른 요소들처럼 배치된 다음에 그 위치를 기준으로 배치됩니다. 즉, 원래 자리를 차지하고 있습니다.

sticky로 바꿔도 마찬가지입니다. sticky 포지션은 기본적으로 static처럼 원래 위치에 있다가, 지정한 위치에 스크롤되면 fixed처럼 화면에 고정되는데요. 그렇기 때문에 일단은 플렉스박스 안에서 배치되고 그다음에 sticky로 배치됩니다.

✅ 결론
간단히 정리하자면 relative, sticky요소의 원래 자리를 차지하기 때문에 플렉스박스의 영향을 받고요, absolutefixed요소의 원래 자리에서 쏙 빠져버리기 때문에 글의 흐름에서 빠지는 거랑 마찬가지로, 플렉스박스랑 상관없이 배치됩니다.

Grid

2차원적으로 배치하는 방식을 그리드 형식이라고 한다.
즉, x축 y축을 이동해서 요소를 배치할 수 있다.

용어

  • 그리드 라인
  • 그리드 셀

's m m'
's m h'

그렇다면 우리는 그리드로 무엇을 설정할 수 있을까?

목차

  • 격자 나누기
  • 간격
  • 크기 미리 정하기
  • 원하는 위치에, 여러 칸에 걸쳐서 배치
  • 이름으로 배치

격자 나누기

	display: grid;
    grid-template-columns: 100px 300px 100px;
    grid-template-rows: 200px 200px 100px;
    /*그리드 격자 나누기 (열, 행)*/

더 쉽게 작성하기 (한 번에 작성할 수 있다)

	display: grid;
    grid-template: 
    	200px 200px 100px / 100px 300px 100px;
    /*grid-template: 가로 격자 나누기 / 세로 격자 나누기*/

그리드 컨테이너 크기가 유동적이면 어떻게 설정하면 될까?
(그리드를 플렉스박스처럼 만들기)

fr를 이용하여 비율을 정한다 (ex. 1:2:1)

	display: grid;
    grid-template: 
    	1fr 1fr 1fr / 1fr 2fr 1fr;

최대최소 길이는 어떻게 정할까?

minmax(최소길이, 최대길이)
ex - minmax(200px, 300px), minmax(1fr, 2fr)

열이나 행이 엄청나게 많으면 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ... 이렇게 쓸 텐데 편한 방법이 있나요?

반복함수를 사용하면 된다.

repeat(n, 길이)

ex) repeat(6, 1fr) = 1fr 1fr 1fr 1fr 1fr 1fr

위의 내용들을 다 응용해보자

.stations {
  display: grid;
  grid-template: repeat(3, minmax(200px, 1fr)) / repeat(3, minmax(200px, 1fr));
}

우선적으로 그리드로 설정하고 그리드의 구성을 정하기 위해서 그리드 템플릿을 사용한다고 생각하면 된다.

<코드잇 요약>

간격

이제 셀 간격을 주어보자.

gap: 가로 세로

크기 미리 정해두기

열의 비율을 정해두고 행은 알아서 조절되길 원할 때!

-> 열은 템플릿으로 격자 정하고 행은 grid-auto-rows: value을 통해서 행의 크기를 미리 정해놓으면 된다.

display: grid;
gap: 1em 0.8em;
grid-template-columns : repeat(3, 1fr);
grid-auto-rows: 4rem 

<응용>

.charts {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 160px;
  gap: 32px;
}

원하는 위치에 셀 두기

그리드는 그리드 라인 혹은 이름에 의해 위치가 결정된다.

그리드 라인으로 셀 위치 정하기

grid-row: val;
grid-column: val;

val은 그리다 라인을 의미하며 마이너스 값을 쓸 수 있다.

여러 영역을 선택하고 싶다면?

-> 슬래시 기호를 사용하여 범위를 설정하고 추가적으로 범위 크기는 숫자 또는 span을 이용한다.

grid-row: 3 / 5; = grid-row: 3 / span 2
grid-column: 2 / -2; grid-column: 2 / span 3

이름으로 셀 위치 정하기

이름을 붙이기 위하여 grid-area: name_val를 써야 한다.

레드 grid-area: r;
그린 grid-area: g;
블루 grid-area: b;

그리고 이름을 이용하여 배치해보자.
그러기 위해서는 grid-template-areas: 을 이용해야 한다.


여기서 빈칸으로 원하는 그리드 칸을 만들기 위해서는?

-> 그 위치에 마침표(.)를 쓰면 된다

	grid-template-areas:
    ". g"
    "r b";

0개의 댓글