LogoSEO Jing
  • All Posts
  • SEO Jing
  • okayJing
  • KD Team
  • CLab CoreTeam
  • Study

Contact Me

© 2026 SEOJing. All rights reserved.

프론트엔드스터디CSS박스모델PositionFlexbox

프론트엔드 스터디 대면 3주차: 박스 모델 실전, Position과 Flexbox

2026년 4월 10일·21분 읽기

1. 저번 주 복습

지난주에는 CSS의 본격적인 스타일링에 들어갔습니다. 글꼴과 색상을 제어하고, 인라인과 블록 요소의 차이, 그리고 프론트엔드 초심자가 가장 먼저 부딪히는 벽인 박스 모델을 배웠습니다. 핵심만 빠르게 짚어보겠습니다.

폰트와 색상

  • font-family: 쉼표로 여러 폰트를 나열하면 앞에서부터 순서대로 사용 가능한 폰트를 적용합니다. 마지막에 sans-serif 같은 일반 패밀리를 넣는 것이 관례입니다.
  • 색상 표기법: 키워드(red), Hex(#FF5733), RGB(rgb(255, 87, 51)), HSL(hsl(11, 100%, 60%)) 등 다양한 방식으로 표현합니다.

인라인 vs 블록 vs 인라인 블록

  • 인라인(Inline): 콘텐츠 크기만큼만 차지, width/height 무시, 상하 margin 무시
  • 블록(Block): 한 줄 전체를 차지, width/height/margin 모두 적용
  • 인라인 블록(Inline-block): 나란히 배치되면서 width/height/margin 모두 적용

박스 모델

  • 안쪽부터: Content → Padding → Border → Margin
  • box-sizing: content-box(기본값): width는 콘텐츠 영역만 의미, padding과 border가 추가로 더해짐
  • box-sizing: border-box: width 안에 padding과 border까지 포함, 현대 CSS의 필수 설정
css
/* content-box: width(200) + padding×2(40) + border×2(10) = 실제 250px */
.box {
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}

/* border-box: 실제 너비 200px 고정, 콘텐츠 영역 = 200 - 40 - 10 = 150px */
.box {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}

학습 자료에서 다룬 추가 개념

3주차 학습 자료에서 강의 외 개념들을 꽤 많이 다뤘습니다. 중요한 것들을 다시 짚어보겠습니다.

px, em, rem 단위

세 단위의 차이는 "무엇을 기준으로 크기를 계산하느냐"입니다.

  • px: 고정값. 화면 해상도와 무관하게 항상 같은 크기.
  • em: 부모 요소의 font-size 기준. 부모가 16px이면 1em = 16px, 2em = 32px.
  • rem: 루트(<html>)의 font-size 기준. 기본값은 16px이므로 1rem = 16px. 부모가 누구든 기준이 변하지 않습니다.
css
html {
  font-size: 16px; /* rem의 기준 */
}

.parent {
  font-size: 20px;
}

.child-em {
  font-size: 1.5em; /* 부모(20px) × 1.5 = 30px */
}

.child-rem {
  font-size: 1.5rem; /* 루트(16px) × 1.5 = 24px */
}

em의 함정: 중첩이 깊어지면 계산이 복잡해집니다. 손자 요소에서 1.5em을 쓰면 부모가 이미 1.5em인 경우 1.5 × 1.5 = 2.25em이 되어 예상보다 커집니다. 실무에서는 rem을 기본 단위로 쓰고, px은 1~2px 같은 아주 작은 값(테두리, 그림자)에만 사용합니다.

마진 겹침(Margin Collapsing)

수직으로 인접한 두 블록 요소의 마진은 합산되지 않고, 더 큰 값 하나만 적용됩니다.

css
/* 두 p 태그 사이 간격: 30 + 20 = 50px이 아닌 30px (큰 쪽만) */
.box-a {
  margin-bottom: 30px;
}
.box-b {
  margin-top: 20px;
}

/* 방지법: 부모에 overflow: hidden 또는 padding/border 추가 */
.parent {
  overflow: hidden; /* 새 BFC 생성 → 자식 마진 겹침 차단 */
}

/* 방지법 2: Flexbox 컨테이너 안에서는 마진 겹침 없음 */
.flex-parent {
  display: flex;
  flex-direction: column;
}

겹침이 발생하는 세 가지 상황: ① 인접 형제 요소, ② 부모-자식(padding/border 없을 때 자식 마진이 부모 밖으로 새어 나감), ③ 빈 블록 요소(자신의 위아래 마진끼리 겹침).

CSS 리셋과 Normalize

브라우저마다 기본 스타일이 다릅니다. Chrome과 Firefox에서 <h1> 크기나 <ul> 들여쓰기가 조금씩 다릅니다. 이를 해결하는 두 가지 방법이 있습니다.

  • CSS Reset: 브라우저 기본 스타일을 전부 제거하고 백지에서 시작. margin: 0, padding: 0을 전체 요소에 적용.
  • Normalize.css: 브라우저 간 차이만 통일. 유용한 기본 스타일은 유지.
css
/* 거의 모든 프로젝트의 첫 줄 — 전체 box-sizing 일괄 설정 */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* 기본 마진 제거 */
body,
h1,
h2,
h3,
p,
ul,
ol {
  margin: 0;
  padding: 0;
}

가상 요소 (::before, ::after)

HTML에 태그를 추가하지 않고 CSS만으로 시각적 요소를 삽입합니다. content 속성이 필수이며, 빈 장식이라도 content: ""를 반드시 써야 합니다.

css
/* 링크 앞에 아이콘 추가 */
.link::before {
  content: "→ ";
  color: blue;
}

/* 카드에 장식용 라인 추가 */
.card::after {
  content: ""; /* 빈 문자열 필수 */
  display: block;
  width: 40px;
  height: 3px;
  background: coral;
  margin-top: 8px;
}

/* 활용: 툴팁 말풍선 꼬리 */
.tooltip::before {
  content: 

중요한 콘텐츠(접근성에 필요한 텍스트)는 HTML에, 순수 장식은 가상 요소에 작성합니다. 스크린 리더는 ::before/::after의 content를 읽을 수도 있어서 빈 문자열로 두는 것이 안전합니다.

BFC (Block Formatting Context)

BFC는 "마진 겹침과 float가 영향을 미치는 독립된 레이아웃 구역"입니다. 새 BFC를 만들면 그 안에서는 외부 마진 겹침이 차단됩니다.

css
/* BFC를 만드는 방법들 */
.bfc-1 {
  overflow: hidden; /* 가장 오래된 방법 */
}
.bfc-2 {
  display: flow-root; /* 부작용 없이 BFC만 생성 — 권장 */
}
.bfc-3 {
  display: flex; /* flex/grid 컨테이너는 자동으로 BFC */
}

/* 활용 예: 부모-자식 마진 겹침 방지 */
.card {
  display: flow-root; /* 자식의 margin-top이 부모 밖으로 새지 않음 */
  padding: 16px;
}

CSS 상속

CSS 속성은 두 종류로 나뉩니다. 상속되는 속성은 부모에 한 번만 써도 자식 전체에 적용되고, 상속되지 않는 속성은 각 요소마다 별도로 지정해야 합니다.

분류상속 여부대표 속성
텍스트 관련상속됨color, font-family, font-size, line-height
레이아웃 관련상속 안됨margin, padding, border, width,
css
/* 부모에 color 지정 → 자식 전체에 적용 */
body {
  color: #333;
  font-family: "Pretendard", sans-serif;
}

/* 상속 동작 제어 키워드 */
.child {
  color: inherit; /* 부모 값 강제 상속 */
  color: initial; /* 브라우저 기본값으로 초기화 */
  color: unset; /* 상속되는 속성이면 inherit, 아니면 initial */
}

overflow와 텍스트 말줄임

콘텐츠가 요소 크기를 넘칠 때 어떻게 처리할지 결정합니다.
css
/* overflow 기본 동작 */
.box-visible {
  overflow: visible; /* 기본값: 넘쳐도 그냥 표시 */
}
.box-hidden {
  overflow: hidden; /* 넘치는 부분 잘라냄 */
}
.box-scroll {
  overflow: auto; /* 넘칠 때만 스크롤바 표시 */
}

/* 한 줄 텍스트 말줄임 — 세 속성 세트로 사용 */
.ellipsis {
  white-space: nowrap; /* 줄바꿈 금지 */
  overflow: hidden; /* 넘치는 텍스트 숨김 */
  text-overflow: ellipsis; /* 잘린 자리에 ... 표시 */
}
html
<!-- Tailwind: truncate 클래스 하나로 동일하게 적용 -->
<p class="truncate w-48">이 텍스트는 너무 길어서 잘립니다...</p>

요소 숨기기 세 가지

세 방법은 "공간을 차지하는가", "클릭이 되는가"에서 차이가 납니다.

속성공간 차지클릭 가능대표 사용처
display: none✗ 없음✗완전 제거, 조건부 렌더링
visibility: hidden✓ 있음✗레이아웃 유지하면서 숨기기
css
/* 모달 오버레이 페이드 애니메이션 예시 */
.overlay {
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none; /* opacity: 0이어도 클릭 차단 */
}
.overlay.active {
  opacity: 1;
  pointer-events: auto;
}

cursor와 pointer-events

사용자에게 "이 요소가 클릭 가능한가"를 시각적·기능적으로 제어합니다.

css
/* cursor: 마우스 포인터 모양 변경 */
.button {
  cursor: pointer; /* 손가락 모양 → 클릭 가능 암시 */
}
.disabled-button {
  cursor: not-allowed; /* 금지 아이콘 → 비활성 상태 암시 */
  opacity: 0.5;
}
.loading {
  cursor: wait; /* 로딩 중 */
}

/* pointer-events: 클릭 이벤트 자체를 차단 */
.overlay {
  pointer-events: none; /* 이 요소 위에서 클릭해도 아래 요소에 전달 */
}
.interactive {
  pointer-events: auto; /* 기본값 — 클릭 가능 */
}
html
<!-- Tailwind 예시 -->
<button class="cursor-pointer hover:bg-blue-600">클릭 버튼</button>
<button class="cursor-not-allowed opacity-50" disabled>비활성 버튼</button>
<div class="pointer-events-none">클릭 통과 레이어</div>

2. 저번 주 과제 정답 및 풀이

인증 미션 과제

Q1. box-sizing: content-box(기본값) 상태에서 width: 300px, padding: 20px, border: 10px solid black을 준 요소의 실제 화면 너비는 몇 px인가요? 직접 계산 과정을 쓰세요.

정답: 360px

content-box에서는 width가 콘텐츠 영역만을 의미합니다. padding과 border가 바깥쪽으로 추가됩니다.

  • 콘텐츠 영역: 300px
  • 좌우 패딩: 20px × 2 = 40px
  • 좌우 보더: 10px × 2 = 20px
  • 실제 화면 너비: 300 + 40 + 20 = 360px

흔한 오답 패턴

padding이나 border 중 하나만 더하거나, 한쪽 방향만 계산해 320px, 340px로 답하는 경우가 많습니다. 좌우 양쪽을 모두 더해야 한다는 점을 기억하세요.


Q2. 같은 요소에 box-sizing: border-box를 적용하면 실제 화면 너비와 콘텐츠 영역 너비는 각각 몇 px가 되나요? 직접 계산하세요.

정답: 실제 화면 너비 300px, 콘텐츠 영역 240px

border-box에서는 width: 300px 안에 padding과 border가 포함됩니다.

  • 실제 화면 너비: 300px (그대로)
  • 좌우 패딩: 20px × 2 = 40px
  • 좌우 보더: 10px × 2 = 20px
  • 콘텐츠 영역: 300 - 40 - 20 = 240px

이것이 border-box가 편리한 이유입니다. "내가 300px이라고 썼으니 화면에서도 300px"이라는 직관적인 결과를 얻을 수 있습니다. content-box에서는 padding이나 border를 변경할 때마다 전체 크기가 바뀌어 레이아웃이 깨지기 쉽습니다.


Q3. margin-bottom: 30px인 요소와 margin-top: 20px인 요소가 수직으로 붙어있을 때, 두 요소 사이의 실제 간격은 몇 px인가요? 이 현상의 이름과 방지 방법을 설명하세요.

정답: 30px — 마진 겹침(Margin Collapsing)

수직으로 인접한 블록 요소의 마진은 합산(50px)되지 않고, 더 큰 값(30px)만 남습니다. 이를 마진 겹침(Margin Collapsing)이라 합니다.

방지 방법

  • 부모 요소에 overflow: hidden 적용
  • 부모 요소에 padding 또는 border 추가
  • display: flex 또는 display: grid 컨테이너 사용: Flexbox·Grid 안에서는 마진 겹침이 발생하지 않습니다.

흔한 오답 패턴

"30 + 20 = 50px"라고 합산하는 경우가 가장 많습니다. 수직 마진은 더 큰 쪽이 이긴다는 규칙을 기억하세요. 수평 마진은 겹치지 않으니 혼동하지 마세요.


3. 면접 질문

이번 주 범위와 관련된 실제 면접 질문들을 함께 생각해봅시다. 정답을 외우기보다는 자신만의 말로 설명하는 연습을 해보세요.

Q1. 마진 겹침(Margin Collapsing) 현상을 설명해주세요.

수직 방향으로 인접한 두 요소의 마진이 만나면, 합산되지 않고 둘 중 큰 값만 적용되는 CSS의 의도적인 동작입니다.

  • 인접 형제: 위 요소의 margin-bottom과 아래 요소의 margin-top이 겹침
  • 부모와 자식: 부모에 padding이나 border가 없으면, 자식의 margin이 부모 밖으로 새어 나감
  • 해결법: 부모에 padding, border, 또는 overflow: hidden을 적용하면 겹침을 방지할 수 있습니다.

면접 팁: "왜 이런 동작이 존재하느냐"는 질문이 이어질 수 있습니다. 문단(p) 태그의 상하 마진이 겹침 없이 합산되면 간격이 두 배로 벌어지기 때문에, 자연스러운 여백을 유지하기 위한 설계라고 답하면 됩니다.

Q2. position: absolute와 position: fixed의 차이를 설명해주세요.

둘 다 문서의 정상 흐름에서 빠진다는 공통점이 있지만, 기준점이 다릅니다.

  • absolute: 가장 가까운 position이 static이 아닌 조상 요소를 기준으로 배치됩니다. 그런 조상이 없으면 뷰포트가 기준이 됩니다. 스크롤하면 함께 움직입니다.
  • fixed: 항상 뷰포트(브라우저 화면)를 기준으로 배치됩니다. 스크롤해도 화면의 같은 위치에 고정됩니다. 고정 헤더, 플로팅 버튼 등에 사용합니다.

absolute를 쓸 때 가장 흔한 실수는 부모에 position: relative를 빼먹는 것입니다. 기준이 될 조상 요소에 position: relative를 줘야 합니다.

Q3. Flexbox의 justify-content와 align-items의 차이를 설명해주세요.

둘 다 Flex 컨테이너 안에서 자식 요소들을 정렬하는 속성이지만, 정렬하는 축이 다릅니다.

  • justify-content: 주축(Main Axis) 방향으로 정렬합니다. flex-direction: row일 때는 가로 정렬, column일 때는 세로 정렬이 됩니다.
  • align-items: 교차축(Cross Axis) 방향으로 정렬합니다. flex-direction: row일 때는 세로 정렬, column일 때는 가로 정렬이 됩니다.

"주축은 justify, 교차축은 align"이라는 규칙만 외우면, flex-direction이 바뀌어도 헷갈리지 않습니다.


4. 관련 포스팅

  • 프론트엔드 스터디 3주차 학습 자료: 프론트엔드의 첫 번째 벽, 박스 모델과 스타일링

  • 프론트엔드 스터디 4주차 학습 자료: 자유자재 레이아웃 (포지션과 플렉스박스)


5. 다음 주 안내

다음 주에는 4주차 학습 자료에서 다룬 반응형 웹 디자인, 미디어 쿼리, CSS Grid를 복습하고, CSS 파트를 마무리합니다. HTML/CSS 전체를 아우르는 면접 질문도 함께 준비합니다.

다음 주 영상 예습

다음 주는 강의 영상의 마지막 구간(05:28:02 이후)을 다루며 CSS 파트를 마무리합니다. 동시에 4주차 학습 자료의 후반부(미디어 쿼리, Grid, 반응형 단위)도 함께 복습하니, 학습 자료를 꼭 읽어오세요.

  • 미디어 쿼리 (@media): 강의에서 화면 크기에 따라 다른 스타일을 적용하는 법을 배웁니다. @media (min-width: 768px) { ... } 형태로 작성하며, 데스크톱/태블릿/모바일에 따라 레이아웃을 바꿀 수 있습니다.
  • CSS Grid: 강의 마지막에 Grid가 등장할 수 있습니다. Flexbox가 가로 또는 세로 한 방향이라면, Grid는 행과 열을 동시에 다루는 2차원 레이아웃입니다.
  • 반응형 단위 (vw, vh): 뷰포트(화면) 크기를 기준으로 하는 단위입니다. 100vw는 화면 전체 너비, 100vh는 화면 전체 높이입니다.

사전 과제

아래 영상의 4주차 진도 구간(04:28:10 ~ 05:28:02)을 시청해주세요. 배경 이미지 제어부터 Flexbox 레이아웃까지의 내용입니다.

  • 영상: 제대로 파는 HTML & CSS
  • 구간: 04:28:10 ~ 05:28:02 (약 1시간)
  • 링크:

    제대로 파는 HTML & CSS - 4주차 진도 시청하기

포스트 목록

/study/clab-26-1/in-person
파일 11개, 폴더 0개
프론트엔드 스터디 대면 0주차: 프론트엔드 개발자란? 그리고 우리가 배울 것들프론트엔드 스터디 대면 1주차: HTML 마크업과 폼, 그리고 CSS의 시작프론트엔드 스터디 대면 2주차: 폼(Form), CSS 선택자, 그리고 박스 모델프론트엔드 스터디 대면 3주차: 박스 모델 실전, Position과 Flexbox프론트엔드 스터디 대면 6주차(1): HTML/CSS/JS 리마인드와 브라우저 렌더링프론트엔드 스터디 대면 6주차(2): AI 시대의 개발 방식과 프론트엔드 개발자의 위치프론트엔드 스터디 대면 7주차: React 입문과 프로젝트 구조프론트엔드 스터디 대면 8주차: API와 통신 — 프론트엔드와 백엔드의 계약프론트엔드 스터디 대면 9주차: Next.js 렌더링 진화와 웹 퍼포먼스프론트엔드 스터디 대면 10주차: 팀 협업 — Git, PR, 컨벤션, 리뷰 문화프론트엔드 스터디 대면 11주차: 배포와 운영 — localhost 밖의 세계
""
;
position: absolute;
bottom: -6px;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: black;
}
display
opacity: 0
✓ 있음
✓
페이드 인/아웃 애니메이션