[P1_S1] CSS 레이아웃

보리·2024년 3월 12일
0

codeit-sprint

목록 보기
4/22

position 속성

  • 글의 흐름에서 벗어나서 요소를 자유롭게 배치할 때 쓰는 속성
  • 기본 값은 static이고, static인 경우 원래 있어야 할 위치에 배치

📘위치 정하기

위치를 정하는 기준에 대해서 top, right, bottom, left 속성으로 위치를 정할 수 있다.

값이 모두 똑같은 경우 inset 속성.

📘 relative 포지션

요소의 원래 위치를 기준으로 배치


.green {
  position: relative;
  top: 15px;
  left: 10px;
}

📘 absolute 포지션

가장 가까운 포지셔닝이 된 조상 요소를 기준으로 배치.


.red {
  position: relative;
  top: 0;
  left: 10px;
}

.blue {
  position: absolute;
  right: 10px;
  bottom: 15px;
}

📘 fixed 포지션

브라우저 화면을 기준으로 고정된 배치

⚠️fixed는 자리를 차지하지 않는다. 스크롤시 본문과 내용이 겹치면 본문에 margin을 넣는게 좋다.

📘 sticky 포지션

static처럼 원래 위치에 배치되어 있다가, 정해진 위치에 브라우저가 스크롤되면 그때부터 fixed처럼 고정되어 배치

📘 z-index

  • 앞뒤 순서를 정할 때 쓰는 값.
  • 순서기 때문에 단위 없이 씀.
  • 값이 높을수록 화면에서 앞쪽.
  • 값이 같으면 코드에서 아래 줄에 있는 요소가 앞쪽.

⚠️z-index: 9999로도 해결이 안 되는 이유


<div class="red">
  <div class="green"></div>
</div>
<div class="blue"></div>

.red {
  background-color: #e46e80;
  position: absolute;
  width: 100px;
  height: 100px;
  top: 100px;
  left: 100px;
  z-index: 1;
}

.green {
  background-color: #32b9c1;
  position: absolute;
  width: 50px;
  height: 50px;
  top: 25px;
  left: 25px;
  z-index: 3;
}

.blue {
  background-color: #5195ee;
  position: absolute;
  width: 100px;
  height: 100px;
  top: 150px;
  left: 150px;
  z-index: 2;
}

z-index: 2.bluez-index: 3.green 보다 앞 쪽에 보인다.

📕쌓임 맥락

쌓임 맥락은 z-index를 묶어서 생각하는 범위

.red 태그에서 쌓임 맥락이 만들어졌기 때문에 .red의 모든 자손 태그들은 .red와 마찬가지로 z-index: 1로 묶어서 생각할 수 있다. 그래서 항상 .blue 뒤쪽에 배치되는 것.

심지어 .green에서 z-index: 9999라고 하더라도, 바깥에서 보면 쌓임 맥락 때문에 z-index: 1과 마찬가지로 처리해서, 아무런 효과가 없는 것.

📕쌓임 맥락 만들기

  • 문서의 루트 요소(<html>)
  • position이 absolute이거나 relative이고, z-index가 auto가 아닌 경우
  • position이 fixed이거나 sticky인 경우
  • 플렉스박스나 그리드 자식 중 z-index가 auto가 아닌 경우
  • opacity가 1보다 작은 요소

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

⚠️ z-index가 원하는 대로 동작하지 않을 때

해당 요소를 쌓임 맥락 바깥으로 옮긴다.

.green<div>를 상위 태그로 옮기기


<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>

.green {
  background-color: #32b9c1;
  position: absolute;
  width: 50px;
  height: 50px;
  top: 125px;
  left: 125px;
  z-index: 3;
}

📕 z-index 값이 너무 많아지고 복잡해질 때

(relative 포지션)을 이용하면 간단하게 쌓임 맥락을 만들 수 있다.

.container라는 <div> 안에 쌓임 맥락을 만들고 싶으면 아래처럼 position 속성과 z-index를 추가해 준다.


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

.container {
  position: relative;
  z-index: 0;
}

<header> 태그와 <main> 태그로 일단 영역을 크게 두 개로 나누고, <main>에 쌓임 맥락을 만들어 놓으면 <header> 태그는 무슨 일이 있어도 <main> 태그 안에 있는 것들 보다 앞쪽에 보일 겁니다.


<header>
  ...내비게이션
</header>
<main>
  ...본문 내용
</main>

header {
  position: sticky;
  top: 0;
  z-index: 1;
}

main {
  position: relative;
  z-index: 0;
}

✨ Flexbox

플렉스박스 만들기


display: flex;

📘기본 축과 교차 축

📘배치 방향

flex-direction을 사용하면 기본 축의 방향을 정할 수 있다. 이때 기본 값은 row

📘기본 축 정렬: justify-content

justify-content를 사용하면 기본 축 방향으로 정렬

기본 값은 flex-start입니다.

📘교차 축 정렬: align-items

교차 축 방향으로 정렬할 때는 align-items

기본 값은 stretch(늘려서 배치하기)

📘요소가 넘칠 때: flex-wrap

요소가 넘치는 경우 flex-wrap: wrap을 지정해주면 교차 축 방향으로 넘어가서 배치

간격: gap

숫자를 하나만 쓰면, 모든 방향의 간격을 지정할 수 있다.

📘요소 늘려서 채우기: flex-grow

기본 값은 0

flex-grow 값이 클수록 많이 늘어남.

📘요소 줄여서 채우기: flex-shrink

만약 요소들의 크기가 커서 넘치는 경우, 요소의 크기를 줄여서 플렉스박스 안에 가득 채운다.

flex-shrink의 기본 값이 1이기 때문에 기본적으로 요소를 줄여서 배치하고, 0으로 지정하면 크기가 줄어들지 않는다.

flex-shrink 값이 클수록 상대적으로 많이 줄어든다.

📘 flex-basis 속성

앞에서 flex-growflex-shrink를 쓰면서 요소들의 크기를 정할 때 widthheight 값으로 크기가 결정되는 게 아니다. 플렉스박스에서는 요소들의 크기가 유연하게 늘어나거나 줄어들었다.

기본 축에서는 시작 크기를 정해 놓으면 플렉스박스 안에서 유연하게 최종 크기가 결정된다.

플렉스박스에서 요소의 시작 크기는 flex-basis라는 속성으로 지정할 수 있다.

flex-basis 값을 따로 정해 주지 않으면 기본값은 auto. 그럼 widthheight를 참고해서 시작 크기를 정한다.

기본 축의 방향이 가로 방향이면 width를, 세로 방향이면 height를 참고해서 시작 크기를 정한다. !

! 플렉스박스에서 크기를 정하고 싶을 때는 flex-basis를 사용하기.

📘flex 속성

flex-basis를 사용하면 좋은 점 → flex라는 속성으로 코드를 짧게 쓸 수 있다.

width 속성으로 시작 크기를 지정하기


flex-grow: 1;
flex-shrink: 0;
width: 100px;

flex-basis 속성으로 시작 크기를 지정하기


flex-grow: 1;
flex-shrink: 0;
flex-basis: 100px;

flex 속성으로 짧게 쓰기


flex: 1 0 100px;

⚠️인라인 안에서 세로 정렬을 하고 싶을 때


<p>
  코딩, 쉬워질 때도 됐다.
  <a class="new-window-link" href="https://codeit.kr">
    코드잇
    <img class="icon" src="new-window-link.svg" alt="새 창 열기" width="13" height="13">
  </a>
  에서 지금 바로 시작해보세요.
</p>

.logo {
  width: 13px;
  height: 13px;
}

.new-window-link {
}

<a> 태그에 적용된 .new-window-link 클래스에다가 display: flex로 플렉스박스를 만들고, 여기다 정렬이랑 간격을 넣는다.


.new-window-link {
  display: flex;
  align-items: center;
  gap: 4px;
}

그러면 이런 식으로 아예 줄이 넘어간다.

.new-window-link 클래스에서 <a> 태그의 display: inline이라는 기본 값을 display: flex로 바꿔 줬기 때문.

display: flex라고 하면 그 안에서는 플렉스박스의 규칙에 따라 배치되고, 그 바깥에서 플렉스박스 전체에 대해서는 마치 display: block처럼 위에서 아래로 배치되기 때문.

이럴 때는 display: inline-flex → 플렉스박스를 만들면서 동시에 플렉스박스 전체를 마치 display: inline처럼 배치하는 방식.


.new-window-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

인라인 안에서 플렉스박스를 만들고 싶을 때는 display: inline-flex

⚠️플렉스박스와 포지션을 함께 쓸 때

자기 자신의 원래 위치를 기준으로 배치되는 static(기본값), relative, sticky를 제외하고는 플렉스박스의 흐름에서 벗어나서 배치된다.

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

📕플렉스박스에 배치되는 경우: relativesticky


<div class="container">
  <div class="red box">RED</div>
  <div class="green box">GREEN</div>
  <div class="blue box">BLUE</div>
</div>

.container {
  border: 5px dashed #cacfd9;
  width: 100%;
  height: 500px;
  display: flex;
  position: relative;
  align-items: flex-start;
}

.box {
  border-radius: 15px;
  color: #f9fafc;
  padding: 10px;
}

.red {
  background-color: #e46e80;
}

.green {
  background-color: #32b9c1;
  flex-grow: 1;
  position: relative;
  top: 100px;
  left: 100px;
}

.blue {
  background-color: #5195ee;
}

relative 포지션은 요소의 원래 위치를 기준으로 배치하는 것.

일단 플렉스박스 안에서 다른 요소들처럼 배치된 다음에 그 위치를 기준으로 배치된다. 즉, 원래 자리를 차지하고 있다.

sticky 포지션은 기본적으로 static처럼 원래 위치에 있다가, 지정한 위치에 스크롤되면 fixed처럼 화면에 고정된다. 그렇기 때문에 일단은 플렉스박스 안에서 배치되고 그다음에 sticky로 배치된다.


.green {
  background-color: #32b9c1;
  flex-grow: 1;
  position: sticky;
  top: 0;
}

(스크롤 하는 경우 sticky로 동작.)

📕플렉스박스에서 벗어나는 경우: absolutefixed


<div class="container">
  <div class="red box">RED</div>
  <div class="green box">GREEN</div>
  <div class="blue box">BLUE</div>
</div>

.container {
  border: 5px dashed #cacfd9;
  width: 100%;
  height: 500px;
  display: flex;
  position: relative;
  align-items: flex-start;
}

.box {
  border-radius: 15px;
  color: #f9fafc;
  padding: 10px;
}

.red {
  background-color: #e46e80;
}

.green {
  background-color: #32b9c1;
  flex-grow: 1;
  position: absolute;
  top: 100px;
  left: 100px;
}

.blue {
  background-color: #5195ee;
}


.green {
  background-color: #32b9c1;
  flex-grow: 1;
  position: fixed;
  top: 100px;
  left: 100px;
}

(스크롤 했을 때)

fixed는 브라우저 화면을 기준으로 배치되기 때문에 마찬가지로 플렉스박스와 상관없이 배치된다. 보시면 나머지 요소들은 마치 .green <div>가 없는 것처럼 배치됐고, flex-grow도 적용이 안 됐다.

정리

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

✨ Grid

📘그리드 나누기

display 속성을 grid

grid-template-columns 속성으로 컬럼을

grid-template-rows 속성으로 로우를 나눌 수 있다.

예를 들어서 3 x 2 그리드를 만드는데, 컬럼 너비는 각각 100px, 200px 100px이고 로우 너비는 150px 200px이라면 아래와 같이 쓸 수 있다.


display: grid;
grid-template-columns: 100px 200px 100px;
grid-template-rows: 150px 200px;

📘유연한 크기 단위

fr 이라는 단위를 사용하면 플렉스박스처럼 전체 크기에 대해 상대적인 값을 지정할 수 있다.

예를 들어서 3 x 2 그리드에서 컬럼의 너비를 1 : 1 : 1로 하고 싶다면 아래처럼 할 수 있다.


display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 150px 200px;

📘반복되는 값을 한 번에 쓰기

repeat()으로 반복할 횟수와 값을 쓴다.


display: grid;
grid-template-columns: repeat(3, 1fr); // 1fr을 3번 반복.
grid-template-rows: 150px 200px;

📘최소, 최대값으로 크기 정하기

최솟값과 최댓값을 지정해두면 이 사이에서 유연하게 크기가 조절되도록 할 수 있다.

예를 들어서 아래 코드는 컬럼의 너비가 최소 200px. 화면 너비가 작아지더라도 컬럼의 너비는 200px보다 작아지지는 않고, 화면 너비가 넓어지면 컬럼의 너비는 1 : 1 : 1 비율로 늘어난다.


display: grid;
grid-template-columns: repeat(3, minmax(200px, 1fr));
grid-template-rows: 150px 200px;

📘간격 넣기

gap 속성으로 간격을 넣는다.

플렉스박스와 마찬가지로 값을 한 개만 쓰면 세로 가로 모두 간격을 지정할 수 있고, 세로 그리고 가로 순으로 숫자를 두 개 쓰면 세로 간격이랑 가로 간격을 지정할 수 있다.

아래 코드는 세로 간격 20px, 가로 간격 10px로 지정한 코드


display: grid;
grid-template-columns: repeat(3, minmax(200px, 1fr));
grid-template-rows: 150px 200px;
gap: 20px 10px;

📘원하는 위치로 배치하기

grid-columngrid-row 속성을 사용하면 원하는 위치에 요소를 배치할 수 있다.

📘그리드 라인 번호

컬럼 라인은 왼쪽에서부터 오른쪽으로 1, 2, 3, … 이렇게 번호를 붙이고, 로우 라인은 위에서부터 아래로 1, 2, 3, … 이렇게 번호를 붙인다. (이때 테두리도 그리드 라인에 포함된다) 테두리부터 1번다.

예를 들어서 3 x 2 그리드에서 컬럼 라인은 1, 2, 3, 4 이렇게 네 개가 있고, 로우 라인은 1, 2, 3 이렇게 세 개가 있다.

📘배치하기

예를 들어서 2번 컬럼 라인에서 시작해서 4번 컬럼 라인에서 끝나고, 1번 로우 라인에서 시작해서 3번 로우 라인에서 끝나는 배치일때.

시작 라인과 끝 라인을 슬래시로 구분해서 적어주면 된다.

음수 값의 라인 넘버를 섞어서 써도 된다.

span 이라는 키워드를 쓰면 시작하는 라인 번호와 차지할 크기를 적어 줄 수 있다.

예를 들어서 아래의 경우 컬럼 2칸, 로우 2칸을 차지하니까 각각 span 2로 써 줌.

📘이름으로 배치하기

grid-area 로 영역에 이름을 붙이고, grid-template-areas 로 이름을 사용해 배치할 수 있다.

아래 코드는 2 x 2 그리드를 만들고 .sidebar.main 그리고 .player 를 배치한 예시. 참고로 셀을 비워놓고 싶다면 이름 대신 마침표(.)를 쓰면 된다.


body {
  grid-template-areas:
    's m'
    'p p';
}

.sidebar {
  grid-area: s;
}

.main {
  grid-area: m;
}

.player {
  grid-area: p;
}
profile
정신차려 이 각박한 세상속에서

0개의 댓글