프론트엔드 스터디 11주차: React 기초 2 —.
useEffect로 사이드 이펙트를 다루고, 이벤트 처리와 폼 상태 관리까지 — React로 실제 동작하는 앱을 만들기 위한 핵심 기술을 배웁니다.
제대로 파는 HTML & CSS - 4주차 진도 시청하기
안녕하세요. 프론트엔드 스터디 4주차에 오신 것을 환영합니다. 이번 주차에서는 CSS의 꽃이라 할 수 있는 레이아웃을 본격적으로 다뤘습니다. 배경 이미지를 자유롭게 제어하는 법, Position으로 요소를 문서 흐름에서 꺼내 원하는 곳에 배치하는 법, 그리고 현대 웹 레이아웃의 핵심인 Flexbox를 배웠습니다. 3주차까지 "칸 하나"를 다뤘다면, 이번 주부터는 "칸들을 어떻게 배열할 것인가"를 다루는 거예요.
아래 10문제를 막힘없이 풀 수 있다면,
이번 주 학습 영상을 생략하거나, 필요한 부분만 선택적으로 시청하셔도 좋습니다.
바로 하단의 제가 추가로 알면 좋은 개념들을 확인해보세요.
배경 이미지를 다룰 때 background-image, background-size,
background-repeat, background-position을 하나씩 쓰다 보면 코드가
길어집니다. CSS는 이것들을 background 하나로 합쳐 쓸 수 있는
단축 속성(Shorthand)을 제공합니다.
/* 하나씩 쓰는 방식 */
.hero {
background-image: url("hero.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* 단축 속성으로 합치기 */
.hero {
background: url("hero.jpg") center / cover no-repeat;
}
단축 속성을 쓸 때 주의할 점이 하나 있습니다. background-size는 반드시
background-position 바로 뒤에 슬래시(/)로 구분해서 써야 합니다. center / cover처럼요. 이 규칙을 모르면 "단축 속성으로 바꿨더니 배경이 안 나와요"라는
상황을 마주하게 됩니다.
2. Position 완벽 정리 — static, relative, absolute, fixed
Position은 처음 배울 때 가장 혼란스러운 속성 중 하나입니다. 핵심은 "기준점이 어디인가"를 이해하는 것입니다.
/* 1. static (기본값): 문서 흐름대로 배치, top/left 등 무시 */
.box-static {
position: static;
}
/* 2. relative: 원래 위치를 기준으로 이동, 원래 자리는 유지 */
.box-relative {
position: relative;
top: 10px; /* 원래 위치에서 아래로 10px */
left: 20px; /* 원래 위치에서 오른쪽으로 20px */
}
/* 3. absolute: positioned 조상을 기준으로 배치, 문서 흐름에서 빠짐 */
.box-absolute {
position: absolute;
top: 0;
right: 0; /* 기준 요소의 우상단에 붙음 */
}
/* 4. fixed: 뷰포트(화면)를 기준으로 고정, 스크롤해도 안 움직임 */
.box-fixed {
position: fixed;
bottom: 20px;
right: 20px; /* 화면 우하단에 고정 */
}
absolute를 사용할 때 가장 흔한 실수는 부모에 position: relative를 빼먹는
것입니다. 기준이 될 조상 요소에 position: relative를 줘야 자식의
absolute가 그 부모를 기준으로 배치됩니다. 이걸 잊으면 요소가 의도치 않게
페이지 끝으로 날아가버립니다.
<!-- absolute의 올바른 사용 패턴 -->
<div style="position: relative;">
<!-- 이 div가 기준점 역할 -->
<span style="position: absolute; top: 5px; right: 5px;"> NEW </span>
</div>
Position을 사용하면 요소들이 서로 겹치는 상황이 생깁니다. 이때
어떤 요소가 위에 보일지 결정하는 것이 z-index입니다. 숫자가
클수록 앞쪽(위쪽)에 보입니다.
.background-layer {
z-index: 1;
}
.content-layer {
z-index: 10;
}
.modal-layer {
z-index: 100;
}
.tooltip-layer {
z-index: 1000;
}
다만 z-index는 position: static(기본값)인 요소에는 작동하지 않습니다.
반드시 position이 relative, absolute, fixed 중 하나로 설정된 요소에만
적용됩니다. 또한 z-index: 9999 같은 터무니없이 큰 값을 남발하면 나중에
관리가 불가능해지니, 위 예시처럼 역할별로 범위를 정해두는 것
이 좋습니다.
Flexbox는 속성이 많아 보이지만, 딱 하나만 이해하면 나머지가 전부 자연스럽게 따라옵니다. 바로 주축(Main Axis)과 교차축(Cross Axis)의 개념입니다.
flex-direction: row(기본값)일 때 → 주축은 가로, 교차축은
세로 - flex-direction: column일 때 → 주축은
세로, 교차축은 가로justify-content: 주축 방향 정렬 (flex-start, center,
space-between 등) - align-items: 교차축 방향 정렬
(flex-start, center, stretch 등)/* 내비게이션 바: 로고는 왼쪽, 메뉴는 오른쪽 */
.navbar {
display: flex;
justify-content: space-between; /* 주축: 양 끝에 배치 */
align-items: center; /* 교차축: 세로 가운데 */
}
/* 카드 목록: 일정 간격으로 가로 배치, 넘치면 줄바꿈 */
.card-list {
display: flex;
flex-wrap: wrap; /* 넘치면 다음 줄로 */
gap: 16px; /* 카드 사이 간격 */
}
/* 완벽한 정중앙 배치 (가장 자주 쓰이는 패턴) */
.center-box {
display: flex;
justify-content: center; /* 가로 가운데 */
align-items: center; /* 세로 가운데 */
height: 100vh; /* 화면 전체 높이 */
}
"주축 정렬은 justify, 교차축 정렬은 align"이라는 규칙만 외우면,
flex-direction이 바뀌어도 헷갈리지 않습니다. direction이 column이면
justify가 세로 정렬이 되고, align이 가로 정렬이 됩니다.
5. flex-grow, flex-shrink, flex-basis — 유연한 크기 제어
Flexbox의 진짜 강력함은 자식 요소들이 남은 공간을 자동으로 나눠 가지는 것에 있습니다. 이것을 제어하는 세 가지 속성이 있습니다.
flex-basis: 아이템의 기본 크기를 지정합니다. width와
비슷하지만, Flex 컨테이너 안에서의 기본 크기입니다. -
flex-grow: 남는 공간을 얼마나 가져갈지 비율을 정합니다.
기본값은 0(안 늘어남)입니다. - flex-shrink: 공간이 부족할
때 얼마나 줄어들지 비율을 정합니다. 기본값은 1(줄어듦)입니다./* 사이드바(고정) + 메인 콘텐츠(나머지 전부) 레이아웃 */
.sidebar {
flex: 0 0 250px; /* 안 늘어남, 안 줄어듦, 250px 고정 */
}
.main-content {
flex: 1; /* 남은 공간 전부 차지 (flex: 1 0 0의 단축) */
}
/* 3등분 레이아웃 */
.column {
flex: 1; /* 세 요소가 균등하게 1:1:1 */
}
flex: 1은 실무에서 가장 많이 쓰이는 패턴입니다. "이 요소가 남은 공간을 전부
가져가라"는 뜻이에요. 사이드바와 메인 콘텐츠 레이아웃, 동일 너비 컬럼 배치
등에서 항상 등장합니다.
6. Reflow와 Repaint — 브라우저가 화면을 다시 그리는 비용
Position이나 Flexbox로 레이아웃을 변경하면, 브라우저 내부에서는 꽤 복잡한 과정이 일어납니다. 브라우저가 화면을 그리는 과정을 크게 세 단계로 나눌 수 있습니다.
transform, opacity 변경은 이 단계만 다시 실행합니다.여기서 중요한 포인트는 비용 차이입니다. Reflow가 가장 비싸고,
Repaint가 그 다음, Composite가 가장 가볍습니다. 그래서 애니메이션을 만들 때
top/left를 변경하면 매 프레임마다 Reflow가 발생해서 버벅이지만,
transform: translate()를 사용하면 Composite만 발생해서 부드럽게 동작합니다.
/* 느린 방법: 매 프레임마다 Reflow 발생 */
.box-slow {
position: relative;
transition: top 0.3s;
}
.box-slow:hover {
top: -10px;
}
/* 빠른 방법: Composite만 발생 */
.box-fast {
transition: transform 0.3s;
}
.box-fast:hover {
transform: translateY(-10px);
}
지금은 "애니메이션에는 transform과 opacity를 사용하는 것이 성능에 좋다"는
것만 기억해두면 됩니다. 참고로 React 같은 프레임워크는 Virtual DOM을 통해 실제
DOM 변경을 최소화해주고, CSS 애니메이션 라이브러리(Framer Motion 등)도
내부적으로 transform을 사용하기 때문에 직접 최적화할 일은 줄어들지만, "왜
부드러운지" 원리를 아는 것과 모르는 것은 디버깅 능력에서 차이가 납니다.
위에서 transition: transform 0.3s를 잠깐 사용했는데, 이 속성을 제대로
이해하면 CSS만으로도 다양한 인터랙션 효과를 만들 수 있습니다. transition은
속성의 값이 변할 때 즉시 바뀌지 않고 일정 시간에 걸쳐 부드럽게 변하도록
만들어줍니다.
/* 기본 문법: transition: 속성 시간 타이밍함수 지연시간; */
.button {
background-color: #3b82f6;
color: white;
padding: 12px 24px;
border-radius: 8px;
transition: background-color 0.2s ease;
}
.button:hover {
background-color: #1d4ed8; /* 0.2초에 걸쳐 부드럽게 변함 */
}
transition을 구성하는 네 가지 값을 알아봅시다.transition-property: 어떤 속성에 전환 효과를 줄지 (all,
background-color, transform 등)transition-duration: 전환에 걸리는 시간 (0.3s, 200ms)transition-timing-function: 전환의 속도 곡선 (ease,
linear, ease-in-out)transition-delay: 전환이 시작되기 전 대기 시간 (0s,
0.1s)/* 여러 속성에 각각 다른 전환 적용 */
.card {
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-4px); /* 위로 살짝 뜨는 효과 */
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15); /* 그림자 추가 */
}
/* 모든 속성에 한 번에 적용 (간편하지만 의도치 않은 속성도 전환될 수 있음) */
.link {
transition: all 0.2s ease;
}
transition: all은 편리하지만, 의도하지 않은 속성(width, height 등)까지
전환되어 성능 문제가 생길 수 있습니다. 가능하면
전환할 속성을 명시적으로 지정하는 것이 좋습니다.
/* 1. 버튼 호버: 배경색 변화 */
.btn {
transition: background-color 0.2s ease;
}
/* 2. 카드 호버: 위로 떠오르는 효과 */
.card {
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
/* 3. 페이드 효과 */
.fade {
transition: opacity 0.3s ease;
opacity: 0;
}
.fade.visible {
opacity: 1;
}
/* 4. 사이드바 슬라이드 */
.sidebar {
transform: translateX(-100%);
transition: transform 0.3s ease;
}
.sidebar.open {
transform: translateX(0);
}
Tailwind CSS에서는 transition-colors, transition-transform,
transition-all 같은 유틸리티와 duration-200, ease-in-out을 조합합니다.
예를 들어 <button className="transition-colors duration-200 hover:bg-blue-700">
처럼 사용합니다. 더 복잡한 애니메이션(마운트/언마운트 시 전환 등)이 필요하면
Framer Motion 같은 라이브러리를 사용합니다.
8. 미디어 쿼리 (@media) — 화면 크기에 따라 레이아웃 바꾸기
지금까지 배운 Flexbox로 유연한 레이아웃을 만들 수 있지만, 데스크톱에서는 가로로 3열 배치하던 카드를 모바일에서는 세로로 1열 배치하고 싶다면 어떻게 할까요? 이때 사용하는 것이 미디어 쿼리(@media)입니다.
/* 기본: 모바일 (작은 화면) */
.card-list {
display: flex;
flex-direction: column;
gap: 16px;
}
/* 태블릿 이상: 768px부터 2열 */
@media (min-width: 768px) {
.card-list {
flex-direction: row;
flex-wrap: wrap;
}
.card-list > .card {
flex: 1 1 calc(50% - 16px);
}
}
/* 데스크톱: 1024px부터 3열 */
@media (min-width: 1024px) {
.card-list > .card {
flex: 1 1 calc(33.333% - 16px);
}
}
위 코드처럼 작은 화면(모바일)을 기본으로 작성하고,
min-width 미디어 쿼리로 점점 큰 화면에 대응하는 방식을
모바일 퍼스트(Mobile First)라고 합니다. 반대로 데스크톱을
기본으로 하고 max-width로 줄여나가는 방식도 있지만, 모바일 퍼스트가 현재
업계 표준입니다.
화면 크기의 기준점을 브레이크포인트(Breakpoint)라고 합니다. 정해진 표준은 없지만, 실무에서 자주 쓰이는 값들이 있습니다.
| 구분 | 브레이크포인트 | 대상 기기 |
|---|---|---|
| sm | 640px | 큰 스마트폰 |
| md | 768px | 태블릿 |
| lg | 1024px | 작은 데스크톱 / 태블릿 가로 |
| xl | 1280px | 데스크톱 |
Tailwind CSS도 위와 거의 동일한 브레이크포인트를 기본으로 사용합니다. 실무에서
Tailwind를 쓴다면 md:flex-row, lg:grid-cols-3처럼 클래스명에
브레이크포인트 접두사를 붙이는 것만으로 반응형이 완성되기 때문에, @media를
직접 작성하는 일은 많지 않습니다. 하지만 Tailwind의 반응형 유틸리티도
내부적으로 미디어 쿼리를 생성하는 것이므로, 원리를 알아야 커스텀이 필요할 때
대응할 수 있습니다.
@media는 화면 너비를 감지하는 것만 가능한 게 아닙니다. 다양한 조건을
감지해서 스타일을 분기할 수 있습니다.
| 미디어 특성 | 용도 | 예시 |
|---|---|---|
prefers-color-scheme | 사용자의 다크/라이트 모드 감지 | @media (prefers-color-scheme: dark) |
prefers-reduced-motion | 애니메이션 줄이기 설정 감지 | @media (prefers-reduced-motion: reduce) |
orientation | 세로/가로 방향 감지 | @media (orientation: landscape) |
hover | 호버가 가능한 기기인지 감지 | @media (hover: hover) |
pointer | 포인팅 장치의 정밀도 감지 | @media (pointer: coarse) |
print | 인쇄 시 스타일 분기 | @media print |
/* 다크 모드일 때 배경색 변경 */
@media (prefers-color-scheme: dark) {
body {
background-color: #1a1a1a;
color: #f0f0f0;
}
}
/* 사용자가 "움직임 줄이기"를 켰을 때 애니메이션 제거 */
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
/* 터치 기기(스마트폰, 태블릿)에서는 호버 효과 제거 */
@media (hover: none) {
.button:hover {
background-color: inherit;
}
}
/* 인쇄할 때 불필요한 요소 숨기기 */
@media print {
.navbar,
.sidebar,
.footer {
display: none;
}
}
특히 prefers-color-scheme은 다크 모드 구현에 필수적이고,
prefers-reduced-motion은 접근성(Accessibility) 측면에서 중요합니다. 일부
사용자는 움직이는 요소가 어지러움을 유발할 수 있기 때문에, 이 설정을 존중하는
것이 좋은 UX입니다.
실전 예시: absolute vs fixed — 맴버스 앱의 게시글 추가 버튼
Position의 차이가 실제 앱에서 어떤 문제를 일으키는지 좋은 예시가 있습니다. 아래는 맴버스 앱의 커뮤니티 페이지입니다. 오른쪽 하단에 게시글을 추가하는 플로팅 액션 버튼(FAB)이 있습니다.

이 버튼은 position: fixed로 구현하면 화면(뷰포트) 기준으로 항상 우하단에
고정됩니다. 스크롤을 하든, 하단 내비게이션 바가 있든 상관없이
항상 같은 위치에 떠 있습니다.
그런데 만약 이 버튼을 position: absolute로 구현하면 어떻게 될까요?
absolute는 가장 가까운 positioned 조상을 기준으로 배치되기 때문에, 페이지의
렌더링 순서나 부모 요소의 높이에 따라 버튼의 위치가 달라집니다.

실제로 맴버스 앱에서 이 문제가 발생했습니다. 렌더링 타이밍에 따라 FAB 버튼이
하단 내비게이션 바에 가려져 버린 것입니다. 해결 방법은 간단했습니다.
position: absolute를 position: fixed로 바꾸는 것만으로 버튼이 항상 올바른
위치에 표시되었습니다.
/* 문제 발생: absolute는 부모 기준이라 위치가 불안정 */
.fab-button {
position: absolute;
bottom: 80px;
right: 20px;
}
/* 해결: fixed로 뷰포트 기준 고정 */
.fab-button {
position: fixed;
bottom: 80px;
right: 20px;
}
이 사례에서 알 수 있듯이,
항상 화면의 같은 위치에 떠 있어야 하는 요소(FAB 버튼, 고정
헤더, 채팅 위젯 등)에는 fixed를,
특정 부모 요소 안에서의 위치를 지정해야 하는 경우(배지, 닫기
버튼 등)에는 absolute를 사용해야 합니다.
Flexbox는 한 방향(가로 또는 세로)으로 요소를 배치하는 1차원 레이아웃입니다. 하지만 가로와 세로를 동시에 제어해야 하는 상황이 있습니다. 예를 들어 대시보드처럼 행과 열이 동시에 중요한 레이아웃을 만들 때는 CSS Grid가 적합합니다.
/* 3열 × 자동 행 그리드 */
.dashboard {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3개의 동일 너비 열 */
gap: 16px; /* 행·열 간격 */
}
/* repeat()으로 간결하게 */
.dashboard {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
1fr은 fraction(비율)의 약자로, 남은 공간을 비율로 나눕니다.
1fr 1fr 1fr은 3등분, 1fr 2fr은 1:2 비율입니다. Flexbox의 flex: 1과
비슷한 개념이지만 열 단위로 적용됩니다.
| 상황 | 추천 | 이유 |
|---|---|---|
| 내비게이션 바 (가로 한 줄) | Flexbox | 한 방향 정렬 |
| 카드 목록 (가로 나열 + 줄바꿈) | 둘 다 가능 | Flex + wrap 또는 Grid |
| 대시보드 (행·열 동시 제어) | Grid | 2차원 배치 |
| 사이드바 + 메인 콘텐츠 | Grid | 열 너비 고정 + 유동 조합 |
| 요소 하나를 정중앙 배치 | 둘 다 가능 | 취향 차이 |
/* 실무에서 자주 보는 Grid 패턴: 사이드바 + 메인 */
.layout {
display: grid;
grid-template-columns: 250px 1fr; /* 사이드바 250px 고정, 나머지 유동 */
min-height: 100vh;
}
핵심 기준은 간단합니다. "한 방향이면 Flex, 두 방향이면 Grid".
실무에서는 둘을 섞어서 쓰는 경우가 대부분입니다. 전체 페이지 레이아웃은
Grid로, 내부 컴포넌트는 Flexbox로 구성하는 패턴이 일반적입니다. Tailwind
CSS에서는 grid grid-cols-3 gap-4처럼 유틸리티 클래스로 Grid를 선언하므로
직접 CSS를 작성할 일은 줄어들지만, 1fr이나 auto-fill 같은 개념을 이해해야
Tailwind의 grid-cols-[repeat(auto-fill,minmax(280px,1fr))] 같은 커스텀 값도
자유롭게 쓸 수 있습니다.
앞서 배운 미디어 쿼리와 Grid를 조합하면 화면 크기에 따라 열 수가 자동으로 바뀌는 반응형 레이아웃을 쉽게 만들 수 있습니다.
/* 모바일: 1열, 태블릿: 2열, 데스크톱: 3열 */
.card-grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
또는 미디어 쿼리 없이도 auto-fill과 minmax()를 사용하면
브라우저가 알아서 열 수를 조절합니다.
/* 자동 반응형: 최소 280px, 남는 공간은 균등 분배 */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
이 한 줄이면 화면 너비에 따라 카드가 자동으로 1열, 2열, 3열로 재배치됩니다. 미디어 쿼리를 직접 쓰는 것보다 코드가 훨씬 간결하면서도 유연합니다.
10. CSS calc() 함수 — 서로 다른 단위를 섞어 계산하기
Grid에서 1fr이나 %를 사용해 유연한 레이아웃을 만들 수 있지만, 때로는
"전체 너비에서 사이드바 250px을 뺀 나머지"처럼 서로 다른
단위를 섞어서 계산해야 할 때가 있습니다. calc() 함수가 바로 이 역할을
합니다.
/* 기본 문법: calc(계산식) */
.main-content {
/* 전체 너비에서 사이드바 250px을 뺀 나머지 */
width: calc(100% - 250px);
}
.container {
/* 뷰포트 높이에서 헤더(60px)와 푸터(80px)를 뺀 영역 */
min-height: calc(100vh - 60px - 80px);
}
.grid-item {
/* 3등분에서 gap(16px * 2개)을 뺀 너비 */
width: calc((100% - 32px) / 3);
}
calc() 사용 시 주의할 점이 하나 있습니다.
연산자(+, -, *, /) 앞뒤에 반드시 공백이 있어야 합니다.
calc(100%-250px)은 작동하지 않고, calc(100% - 250px)이라고 써야 합니다.
/* 올바른 사용 */
width: calc(100% - 250px); /* ✅ 연산자 앞뒤에 공백 */
/* 잘못된 사용 */
width: calc(100%-250px); /* ❌ 공백 없으면 작동 안 함 */
/* 중첩도 가능 */
width: calc(100% - calc(250px + 16px)); /* 중첩 calc */
calc()의 강력한 점은
%, px, rem, vw 등 서로 다른 단위를 자유롭게 섞을 수 있다
는 것입니다. 이전에는 JavaScript로 계산해야 했던 것을 CSS만으로 해결할 수 있습니다.
/* 1. 고정 헤더 아래 남은 영역 전체 사용 */
.page-content {
height: calc(100vh - 64px); /* 헤더 높이 64px */
}
/* 2. 패딩을 고려한 전체 너비 */
.full-width-with-padding {
width: calc(100% - 40px); /* 좌우 20px씩 여백 */
margin: 0 auto;
}
/* 3. CSS 변수와 함께 사용 */
:root {
--header-height: 64px;
--footer-height: 80px;
}
.main {
min-height: calc(100vh - var(--header-height) - var(--footer-height));
}
Tailwind CSS에서는 대괄호 표기법으로 calc()를 사용할 수 있습니다.
h-[calc(100vh-64px)]처럼 작성합니다. 다만 Tailwind의 spacing
시스템(h-screen, min-h-full 등)으로 해결되는 경우가 많아서, calc()를
직접 쓸 일은 비교적 적습니다. CSS 변수와 조합하면
h-[calc(100vh-var(--header-height))]처럼 동적 값도 처리할 수 있습니다.
반응형 레이아웃에서 자주 쓰이는 뷰포트 단위도 알아두면 좋습니다.
vw (viewport width): 뷰포트 너비의 1%. 100vw는 화면 전체
너비입니다.vh (viewport height): 뷰포트 높이의 1%. 100vh는 화면 전체
높이입니다.dvh (dynamic viewport height): 모바일 브라우저에서 주소창이
숨겨지거나 나타날 때 높이가 동적으로 변합니다. 100vh는 주소창을 무시하고
고정 높이를 잡지만, 100dvh는 실제 보이는 영역에 맞춰 변합니다.모바일에서 height: 100vh를 쓰면 주소창에 가려져 콘텐츠가 잘리는 문제가 자주
발생합니다. 이때 100dvh를 사용하면 해결됩니다. 최신 브라우저에서 모두
지원하므로, 모바일 전체 화면 레이아웃에는 dvh를 사용하는 것이 좋습니다.
<div id="A" style="position: relative;">
<div id="B" style="position: static;">
<div id="C" style="position: absolute; top: 0; left: 0;"></div>
</div>
</div>Post Q&A
프론트엔드 스터디 4주차: 자유자재 레이아웃 (포지션과 플렉스박스) 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!
useEffect로 사이드 이펙트를 다루고, 이벤트 처리와 폼 상태 관리까지 — React로 실제 동작하는 앱을 만들기 위한 핵심 기술을 배웁니다.
지금 당장 읽지 않아도 됩니다. React를 배우면서 에러 처리가 필요해지거나 면접 대비가 필요할 때 참고하세요.
React를 처음 시작합니다. 컴포넌트, JSX, props, useState까지 — React 앱을 만들기 위한 핵심 네 가지를 한 번에 배웁니다.
React를 배우면서 this가 헷갈리거나, 면접 대비가 필요할 때 참고하는 JS 심화 자료입니다. 이 내용을 지금 당장 완벽히 이해하지 않아도 React를 배우는 데 지장이 없습니다.
Next.js가 무엇이고 왜 필요한지 React와 비교해 이해한 뒤, CSR부터 SSR, SSG, ISR, PPR까지 렌더링 전략과 Web Vitals를 정리하며 스터디를 마무리합니다.
다음 주부터 React를 시작합니다. React 코드에서 매 줄 등장하는 map/filter, 구조 분해, 스프레드, 옵셔널 체이닝, 모듈까지 — React 코드를 막힘없이 읽기 위한 JS 문법을 한 번에 정리합니다.
비동기와 async/await를 배운 뒤, 대면에서는 API를 단순 호출 방법이 아니라 프론트엔드와 백엔드 사이의 계약으로 바라봅니다. HTTP, REST, CORS, 프록시, API 클라이언트 구조, TanStack Query와 파일 배치까지 연결합니다.
JS 비동기 처리의 흐름을 배웁니다. 클로저가 왜 중요한지, 콜백 지옥을 해결한 Promise, 그리고 현대 JS의 표준인 async/await까지 이어지는 흐름을 이해합니다.
바닐라 JS의 한계에서 React가 등장한 이유까지, 컴포넌트와 렌더링 방식을 이해하고 프로젝트 구조 감각을 만들어가는 대면입니다.
JS에서 가장 낯선 개념 중 하나인 프로토타입 기반 상속을 다룹니다. const가 왜 불변을 보장하지 않는지, 타입을 런타임에 정확히 확인하는 방법까지 함께 배웁니다.
JavaScript에서 거의 모든 것은 객체입니다. 함수가 일급 객체라는 의미, var와 let의 스코프 차이, 그리고 렉시컬 스코프까지 다룹니다.
4~6주차 공백 이후 진행하는 첫 번째 대면입니다. HTML/CSS/JS 핵심을 가볍게 다시 연결하고, 브라우저가 코드를 실제 화면으로 바꾸는 과정을 통해 렌더링 파이프라인과 성능 감각을 잡습니다.
길어진 6주차 대면의 두 번째 차시입니다. AI 시대에 개발자가 실제로 어떻게 일하는지, 그리고 프론트엔드 개발자가 디자이너·백엔드·PM 사이에서 어떤 연결과 리딩 역할을 하는지 다룹니다.
JavaScript를 처음 제대로 배우는 주차입니다. var/let/const의 차이, JS만의 독특한 타입 시스템, 그리고 호이스팅·TDZ까지 다룹니다.
배경 이미지를 제어하고, Position으로 요소를 원하는 위치에 배치하며, Flexbox로 유연한 가로·세로 레이아웃을 구성합니다. 요소를 화면 정중앙에 띄우거나, 내비게이션 바처럼 가로로 예쁘게 정렬하는 것이 이번 주 목표입니다.
3주차 박스 모델과 스타일링 복습, 과제 풀이, 4주차 Position과 Flexbox 레이아웃까지 다룬 대면 스터디 정리입니다. 면접에서 자주 나오는 마진 겹침, box-sizing, Flexbox 관련 질문도 함께 준비합니다.
폰트와 색상을 다루고, 인라인과 블록 요소의 차이를 이해하며, 마진·패딩으로 구성되는 박스 모델을 완벽하게 익힙니다. 요소들 사이의 여백을 자유자재로 제어하고 화면이 찌그러지지 않게 박스 크기를 다루는 것이 이번 주 목표입니다.
2주차 폼과 CSS 선택자 복습, 과제 풀이, 3주차 박스 모델과 스타일링까지 다룬 대면 스터디 정리입니다. 면접에서 자주 나오는 GET vs POST, CSS 우선순위, 박스 모델 관련 질문도 함께 준비합니다.
사용자 입력을 받는 폼(Form)을 만들고, CSS를 HTML에 연결하는 방법과 원하는 요소를 정확히 선택하는 CSS 선택자 규칙을 배웁니다. 로그인·회원가입 폼을 직접 만들고, CSS로 원하는 요소를 콕 집어내는 것이 이번 주 목표입니다.
1주차 HTML 핵심 복습과 과제 풀이, 2주차 폼(Form)과 CSS 선택자까지 다룬 대면 스터디 정리입니다. 면접에서 자주 나오는 시맨틱 HTML, img alt 속성 관련 질문도 함께 준비합니다.
기초 태그 강의에서 한 걸음 더 나아갑니다. 카카오톡 공유 썸네일, 모바일 데이터 절약, 스크린 리더기를 위한 숨은 정보 등 실무에서 마주하게 될 중급 HTML 개념들을 가볍게 훑어봅니다.
프론트엔드 개발자가 실무에서 하는 일, 2025-2026 기술 스택, 현실적인 연봉과 채용 트렌드를 정리했습니다. 스터디 자료 구조와 앞으로의 방향도 함께 안내합니다.
스터디 커리큘럼 방향을 정하기 위한 세 번째 사전 진단 퀴즈입니다. 자바스크립트의 스코프, 참조 타입의 메모리 할당, DOM 제어와 이벤트 흐름 등 React 실무의 근간이 되는 CS 지식을 점검합니다.
스터디 커리큘럼 방향을 정하기 위한 마지막 사전 진단 퀴즈입니다. React 컴포넌트를 다루기 위해 필수적인 배열 고차 함수(map, filter)와 비동기 통신(async/await) 능력을 점검합니다.
스터디 커리큘럼 방향을 정하기 위한 마지막 사전 진단 퀴즈입니다. 선언적 UI, 상태(State), 단방향 데이터 흐름, 부수 효과(Side Effect) 등 React 생태계 진입을 위한 필수 개념을 점검합니다.
스터디 커리큘럼 방향을 정하기 위한 첫 번째 사전 진단 퀴즈입니다. HTML 태그 구조부터 CSS 박스 모델까지, 실무와 React 환경에서 이 기초들이 왜 중요한지 점검합니다.
스터디 커리큘럼 방향을 정하기 위한 두 번째 사전 진단 퀴즈입니다. 시맨틱 마크업, 폼 이벤트 제어, CSS 우선순위, Flexbox 레이아웃 등 실전 활용 능력을 점검합니다.