Back
ESSAY비개발자를 위한 바이브코딩 안내서
DEC 02, 2025

Part 3.1 바이브코딩에 필요한 최소한의 HTML/CSS/JS

제가 교육을 할 때, 최소한의 코딩 지식은 알면 좋다, 알아야 한다 식의 말씀을 많이 드립니다. 대게는 수긍하는 분위긴데, 몇몇 분은 근본적인 질문을 던지십니다.

"AI가 다 해주는데 왜 알아야 해요?"

네..맞습니다. ai가 다 해주긴하죠. 근데 결국 ai가 해주는 거는 '프로덕트를 만들어 준다' 가 아니라, '코드를 만든다' 가 먼저입니다. 즉, 코드가 만들어지고 프로덕트가 만들어지는거죠. 수학으로 치면 '기초'가 될까요?

우린 이 기초를 어느 정도는 알고 있어야 합니다. 물론, 바이브코딩 세계에선 '기초' 가 없더라도 프로덕트를 만드는 것도 가능은 합니다. 하지만, 앞으로 시행착오를 줄이려면, 이번 기회에 배우시는 걸 추천드립니다. 배우라고 하는 범위는 '직접 작성' 하라는게 아니라, '눈코딩' 정도는 할 줄 아는 정도입니다

왜냐하면 이런 상황이 반드시 오기 때문입니다:

  • AI가 만든 버튼 색깔이 마음에 안 드는데, 어디를 고쳐달라고 해야 할지 모르겠음

  • "이 텍스트 위치를 조금만 왼쪽으로"라고 했는데 AI가 엉뚱한 걸 수정함

  • 에러가 났는데 "App.tsx 파일의 onClick 핸들러에서 문제가 발생했습니다"라는 메시지를 이해 못함

HTML, CSS, JS의 역할만 알아도 AI에게 정확한 위치를 짚어줄 수 있고, AI의 작업을 검증할 수 있습니다. 이게 바이브코딩의 효율을 3-5배 높여주는 핵심 역량입니다.

( 혹시 몰라서 말씀드리면, 요새 나오는 대부분의 AI 툴은 사용자가 별다른 요청을 하지 않는 이상 프론트엔드를 React, TypeScript 기반으로 작성해요. TypeScript를 설명하기엔 정말 밤을 새도 모자라지만, 짧게 말하면 JavaScript의 superset으로 '타입'을 사용할 수 있다 정도로만 알고 계시면 됩니다. )


웹의 3가지 언어

웹페이지는 세 가지 언어로 만들어집니다. 각각의 역할이 명확히 다릅니다.

한 줄 요약

언어역할비유
HTML구조 (뭐가 있는지)건물의 뼈대, 방 배치
CSS스타일 (어떻게 보이는지)인테리어, 페인트, 가구
JavaScript동작 (어떻게 작동하는지)전기, 수도, 엘리베이터

Cursor에서 프로젝트를 열면 .html, .css, .js (또는 .jsx, .tsx) 파일들이 보일 겁니다. 이제 각각이 무슨 역할인지 알아보겠습니다.


HTML: 구조를 담당합니다

HTML은 "여기에 버튼이 있고, 저기에 텍스트가 있고, 그 아래 이미지가 있다"를 정의합니다.

<div>
  <h1>환영합니다</h1>
  <p>이것은 설명 텍스트입니다.</p>
  <button>클릭하세요</button>
  <img src="photo.jpg" />
</div>

핵심 개념: 태그(Tag)

HTML은 <태그이름>내용</태그이름> 형태로 작성됩니다.

자주 보게 될 태그들:

  • <div>: 구역을 나누는 상자 (가장 많이 씀)

  • <h1>, <h2>, <h3>: 제목 (숫자가 작을수록 큼)

  • <p>: 문단 (paragraph)

  • <button>: 버튼

  • <input>: 입력창

  • <img>: 이미지

  • <a>: 링크

바이브코딩에서 활용법:

AI에게 요청할 때 태그 이름을 언급하면 훨씬 정확합니다.

❌ "위에 있는 그 글자 크기 좀 키워줘"
✅ "h1 태그의 글자 크기를 키워줘"

CSS: 스타일을 담당합니다

CSS는 "그 버튼을 파란색으로, 둥글게, 가운데 정렬로" 같은 시각적 모양을 정의합니다.

.main-button {
  background-color: blue;
  color: white;
  border-radius: 8px;
  padding: 12px 24px;
}

핵심 개념: 클래스(Class)와 선택자(Selector)

CSS는 "누구를 꾸밀지" 선택하고, "어떻게 꾸밀지" 지정합니다.

/* 선택자 { 속성: 값; } */

.button {           /* 클래스가 "button"인 요소 */
  color: red;
}

#header {           /* id가 "header"인 요소 */
  font-size: 24px;
}

h1 {                /* 모든 h1 태그 */
  font-weight: bold;
}

선택자 앞의 기호 의미:

  • . (점): 클래스 선택 (가장 많이 씀)

  • # (샵): 아이디 선택

  • 기호 없음: 태그 자체 선택

자주 쓰는 CSS 속성들:

/* 색상 */
color: red;                /* 글자 색 */
background-color: blue;    /* 배경 색 */

/* 크기 */
width: 100px;              /* 너비 */
height: 50px;              /* 높이 */
font-size: 16px;           /* 글자 크기 */

/* 여백 */
margin: 10px;              /* 바깥 여백 */
padding: 10px;             /* 안쪽 여백 */

/* 정렬 */
text-align: center;        /* 텍스트 가운데 정렬 */
display: flex;             /* 플렉스 박스 (정렬용) */
justify-content: center;   /* 가로 가운데 */
align-items: center;       /* 세로 가운데 */

/* 테두리 */
border: 1px solid black;   /* 테두리 */
border-radius: 8px;        /* 둥근 모서리 */

바이브코딩에서 활용법:

스타일 수정을 요청할 때 CSS 속성명을 언급하면 정확합니다.

❌ "버튼 좀 더 둥글게 해줘"
✅ "버튼의 border-radius를 16px로 늘려줘"

❌ "여백 좀 줘"
✅ "이 div에 padding을 20px 추가해줘"

JavaScript: 동작을 담당합니다

JavaScript(JS)는 "버튼을 클릭하면 팝업이 뜬다", "데이터를 서버에서 가져온다" 같은 동적인 기능을 담당합니다.

function handleClick() {
  alert("버튼이 클릭되었습니다!");
}

핵심 개념 1: 변수(Variable)

변수는 데이터를 담아두는 상자입니다.

// 변수 선언
const userName = "김철수";      // 바뀌지 않는 값
let count = 0;                  // 바뀔 수 있는 값

// 사용
console.log(userName);          // "김철수" 출력
count = count + 1;              // count가 1이 됨

const vs let:

  • const: 한 번 정하면 안 바뀜 (상수)

  • let: 나중에 바꿀 수 있음

핵심 개념 2: 함수(Function)

함수는 특정 작업을 수행하는 코드 묶음입니다.

// 함수 정의
function greet(name) {
  return "안녕하세요, " + name + "님!";
}

// 함수 호출
greet("철수");  // "안녕하세요, 철수님!" 반환

React 에서는 이런 형태도 자주 봅니다:

// 화살표 함수 (같은 기능, 다른 문법)
const greet = (name) => {
  return "안녕하세요, " + name + "님!";
};

핵심 개념 3: 이벤트 리스너(Event Listener)

"사용자가 뭔가를 하면 → 이 코드를 실행해라"를 정의합니다.

// 버튼 클릭하면 handleClick 함수 실행
<button onClick={handleClick}>클릭</button>

// 입력값이 바뀌면 handleChange 함수 실행
<input onChange={handleChange} />

// 폼 제출하면 handleSubmit 함수 실행
<form onSubmit={handleSubmit}>

자주 보는 이벤트들:

  • onClick: 클릭했을 때

  • onChange: 값이 바뀌었을 때

  • onSubmit: 폼 제출했을 때

  • onMouseEnter: 마우스 올렸을 때

  • onKeyDown: 키보드 눌렀을 때

바이브코딩에서 활용법:

기능 관련 요청을 할 때 이벤트와 함수 개념을 활용하세요.

❌ "버튼 누르면 뭔가 되게 해줘"
✅ "버튼의 onClick에서 handleSubmit 함수를 호출하게 해줘"

❌ "입력하면 저장되게"
✅ "input의 onChange에서 상태(state)를 업데이트하게 해줘"

실제 Cursor 프로젝트에서 보는 예시

Cursor에서 React 프로젝트를 열면 .tsx 파일에서 HTML, CSS, JS가 섞여 있는 걸 볼 수 있습니다:

// 실제 구조는 프롬프트에 따라, 모델에 따라 다를 수 있습니다!
// App.tsx
import "./App.css";  // CSS 파일 불러오기

function App() {
  // JavaScript 영역 - 변수와 함수
  const [count, setCount] = useState(0);
  
  const handleClick = () => {
    setCount(count + 1);
  };

  // return 안 - HTML 구조 (JSX)
  return (
    <div className="container">
      <h1 className="title">카운터 앱</h1>
      <p>현재 값: {count}</p>
      <button onClick={handleClick}>증가</button>
    </div>
  );
}

이 파일 하나에 세 가지가 다 들어있습니다:

  • 구조(HTML): <div>, <h1>, <p>, <button> 태그들

  • 스타일(CSS): className="container", className="title" (별도 CSS 파일에서 정의)

  • 동작(JS): useState, handleClick 함수, onClick 이벤트


실전 팁

코드 읽기 vs 작성하기

바이브코딩에서는 **읽기 80%, 작성 20%**입니다.

읽을 줄 알아야 하는 것:

  • 이 파일이 화면의 어느 부분을 담당하는지

  • 에러 메시지가 가리키는 위치가 어디인지

  • AI가 수정한 부분이 내가 원한 곳이 맞는지

직접 작성할 필요 없는 것:

  • 복잡한 로직

  • 새로운 컴포넌트 전체

  • CSS 애니메이션

간단한 수정(텍스트 변경, 숫자 조정)은 직접 해도 되지만, 복잡한 건 AI에게 맡기세요.

Cursor에서 파일 구조 파악하기

일반적인 React 프로젝트 구조:

// 실제 구조는 프롬프트에 따라, 모델에 따라 다를 수 있습니다!
my-project/
├── src/
│   ├── components/        # 공통 UI 컴포넌트
│   │   └── ui/            # Button, Input 등 기본 요소
│   ├── features/          # 기능별 모듈 (feature-based)
│   │   └── auth/
│   │       ├── components/
│   │       ├── hooks/
│   │       └── index.ts
│   ├── hooks/             # 공통 커스텀 훅
│   ├── lib/               # 유틸, API 클라이언트 등
│   ├── types/             # 공통 타입 정의
│   ├── App.tsx
│   └── main.tsx           # Vite 기준 엔트리
├── public/
├── package.json
└── tailwind.config.js     # Tailwind 설정

AI에게 요청할 때 파일 위치를 알려주면 정확도가 올라갑니다:

❌ "헤더 색깔 바꿔줘"
✅ "src/components/Header.tsx에서 헤더 배경색을 파란색으로 바꿔줘"

className vs class

HTML에서는 class를 쓰지만, React(JSX)에서는 className을 씁니다.

<!-- 일반 HTML -->
<div class="container">
<!-- React JSX -->
<div className="container">

이건 JavaScript에서 class가 예약어이기 때문입니다. Cursor에서 React 프로젝트를 다룬다면 className을 쓴다고 기억하세요.


주의사항: 흔한 실수들

실수 1: 스타일 문제인데 JS 파일만 보기

"버튼 위치가 이상해요" → 이건 CSS 문제일 가능성이 높습니다.

  • 위치, 색상, 크기 문제 → CSS 확인

  • 클릭해도 반응이 없음 → JS 확인

  • 요소가 아예 안 보임 → HTML 확인 (또는 조건부 렌더링)

실수 2: 파일 위치를 모르고 수정 요청하기

프로젝트가 커지면 비슷한 이름의 컴포넌트가 여러 개 생깁니다.

❌ "Button 컴포넌트 수정해줘"
✅ "src/components/common/Button.tsx 파일의 Button 컴포넌트 수정해줘"

실수 3: 인라인 스타일과 CSS 파일 혼동

React에서는 스타일을 넣는 방법이 여러 가지입니다:

// 1. 인라인 스타일 (style 속성)
<div style={{ color: "red", fontSize: "16px" }}>

// 2. CSS 파일의 클래스
<div className="my-class">

// 3. Tailwind CSS (클래스 이름으로 스타일링)
<div className="text-red-500 text-lg">

AI에게 어떤 방식으로 스타일이 적용되어 있는지 확인하고, 같은 방식으로 수정을 요청하세요.


마무리

HTML, CSS, JavaScript - 이 세 가지는 웹의 기본 언어입니다.

핵심 정리:

  • HTML: 구조 (뭐가 있는지) - 태그로 구성

  • CSS: 스타일 (어떻게 보이는지) - 선택자와 속성

  • JavaScript: 동작 (어떻게 작동하는지) - 변수, 함수, 이벤트

바이브코딩에서 이 지식이 필요한 이유:

  1. AI에게 정확한 위치를 알려줄 수 있음

  2. AI가 수정한 부분이 맞는지 검증할 수 있음

  3. 간단한 수정은 직접 할 수 있음

  4. 에러 메시지를 이해할 수 있음

직접 코드를 작성할 줄 몰라도 됩니다. 하지만 읽고 이해할 수 있으면, AI와의 협업 효율이 완전히 달라집니다.


Thank you for reading.

Based in Seoul
Since 2024