본문 바로가기

HTML, CSS, 자바스크립트 소개

HTML은 구조, CSS는 표현, JavaScript는 동작을 맡는다는 책임 경계를 첫 코드로 비교해 익힙니다.

웹 개발을 처음 배울 때 자주 하는 질문 가운데 하나는 HTML, CSS, 자바스크립트 중 무엇이 가장 중요하냐는 것입니다. 셋을 따로 배우다 보면 역할이 겹쳐 보이고, 어느새 모두 비슷한 것처럼 느껴지기도 합니다. 하지만 실제 프로젝트에서는 세 언어가 맡는 일을 분명히 나눌수록 코드를 고치기 쉽고 여러 사람이 함께 작업하기도 수월합니다. 구조를 만드는 코드, 모양을 정하는 코드, 동작을 만드는 코드가 뒤섞이면 작은 변경에도 여러 곳을 고쳐야 하기 때문입니다.

이 글에서는 같은 페이지에 HTML, CSS, 자바스크립트를 차례로 더해 보면서 세 언어가 각각 무엇을 맡는지 확인합니다. 다 읽고 나면 어떤 변경 요청을 받았을 때 세 언어 중 어디를 고쳐야 하는지 스스로 판단할 수 있습니다.

같은 제목에서 구조·표현·동작의 책임을 나눕니다

HTML · CSS · JAVASCRIPT

같은 제목에서 구조·표현·동작의 책임을 나눕니다

HTML의 제목, CSS의 색과 크기, JS의 텍스트 변경이 함께 하나의 화면을 만듭니다.

세 언어가 같은 제목에 기여하는 관계HTML이 제목 요소와 처음 내용을 만들고 CSS가 같은 요소의 색과 크기를 정한다. JavaScript는 클릭 뒤 그 요소의 textContent를 바꾼다. 화살표는 기여 관계이며 실행 순서를 뜻하지 않는다.구조스타일클릭 뒤HTML제목·id·처음 문구CSS제목의 색·크기같은 제목 요소id: mainTitle처음: 환영합니다!클릭: 감사 문구JavaScript클릭 함수 등록textContent 변경
세 언어와 같은 제목의 모바일 관계HTML에서 같은 제목 요소로 구조가 이어지고 CSS에서 그 요소로 스타일이 적용된다. 아래 JavaScript에서 위 제목 요소로 향한 화살표는 클릭 뒤 textContent 변경이다. 데스크톱과 같은 세 관계다.스타일 적용클릭 뒤변경구조HTML제목·id·처음 문구CSS제목의 색·크기같은 제목 요소id: mainTitle처음: 환영합니다!클릭: 감사 문구JavaScript클릭 함수 등록textContent 변경

세 화살표는 같은 요소에 대한 기여 관계입니다. HTML→CSS→JavaScript의 순차 실행을 뜻하지 않습니다. 아래 코드는 각 관계를 만드는 발췌입니다.

HTML · 구조와 의미

<h1 id="mainTitle">
  환영합니다!
</h1>

제목이라는 의미와 텍스트를 제공합니다. DOM의 요소를 id로 찾을 수 있도록 연결합니다.

CSS · 표현과 배치

h1 {
  color: #0056b3;
  font-size: 3em;
}

같은 제목을 원하는 색상과 크기로 표시합니다. 구조와 내용을 지우지 않고 표현을 바꿉니다.

JavaScript · 이벤트와 변경

titleElement.textContent =
  "클릭해 주셔서 감사합니다!";

교재 click 핸들러의 일부입니다. 이벤트에 반응해 기존 제목 노드의 텍스트를 바꿉니다. DOM이나 스타일을 변경할 수도 있습니다.

한 화면에서 세 책임이 함께 작동

HTML로 의미를 만들고, CSS로 표현하고, JS로 이벤트 이후 내용을 바꿉니다. HTML→CSS→JS를 반드시 끝낸 뒤 DOM을 만드는 단일 처리 순서가 아닙니다.

변경 요청을 어디에 둘까?

“문서를 제목과 본문으로 나누기”는 HTML, “제목 크기 바꾸기”는 CSS, “조작 뒤 다른 내용을 보여주기”는 JS 책임부터 검토합니다.

기본 HTML 조작도 활용

링크 이동·폼 입력·버튼의 기본 활성화처럼 HTML이 제공하는 동작도 있습니다. 교재 제목 클릭은 마우스 예이며, 사용자 조작을 제공할 때는 네이티브 button 등과 키보드 동작을 함께 설계합니다.

위 그림은 화면의 제목 하나에 세 언어가 어떻게 기여하는지 보여 줍니다. HTML은 제목 요소와 mainTitle이라는 id, 처음 문구인 환영합니다!를 만들고, CSS는 같은 제목의 색과 크기를 정하며, 자바스크립트는 클릭한 뒤 그 제목의 textContent를 바꿉니다. 그림 아래의 설명처럼 세 화살표는 같은 요소에 대한 기여 관계일 뿐, HTML, CSS, 자바스크립트 순으로 하나씩 끝낸 뒤 다음으로 넘어간다는 실행 순서가 아닙니다.

그림 오른쪽의 질문은 이 글의 목표와 같습니다. 문서를 제목과 본문으로 나누는 일은 HTML에서, 제목 크기를 바꾸는 일은 CSS에서, 조작한 뒤 다른 내용을 보여 주는 일은 자바스크립트에서 먼저 검토합니다. 또 링크 이동, 폼 입력, 버튼처럼 HTML이 기본으로 제공하는 동작도 있으므로 모든 상호작용에 자바스크립트가 필요한 것은 아닙니다.


HTML: 웹 페이지의 뼈대

HTML(HyperText Markup Language)은 웹 페이지의 구조와 내용을 정하는 언어입니다. 마크업(markup)이라는 이름처럼 정보에 표시를 붙여 구조를 만들며, 웹 페이지에 보이는 글, 이미지, 버튼, 링크는 모두 HTML이 정한 자리에 놓입니다. 건물에 비유하면 HTML은 골조와 벽을 세워 방을 나누고 문의 위치를 정하는 단계입니다. 그래서 HTML에서는 화면의 모양보다 먼저 의미 있는 구조를 만드는 것이 중요합니다.

HTML의 주요 특징은 다음과 같습니다.

  • 태그(tag)로 표시합니다: <p>단락</p>, <h1>제목</h1>, <img src="logo.png" alt="로고">처럼 꺾쇠 괄호로 둘러싼 태그로 문서의 구조와 의미를 정합니다. p와 h1은 시작 태그와 종료 태그 사이에 내용을 넣지만, img는 내용을 감싸지 않는 빈 요소(void element)이므로 </img>를 쓰지 않습니다. 이 차이는 HTML 표준의 빈 요소 규칙에도 적혀 있습니다.
  • 의미에 맞는 요소를 씁니다: <header>, <nav>, <article>, <footer>처럼 영역의 역할을 나타내는 요소를 쓰면, 사람과 프로그램 모두 문서의 구조를 쉽게 이해할 수 있고 검색 엔진도 내용을 더 잘 해석합니다.
  • 접근성의 바탕이 됩니다: 화면을 보기 어려운 사용자는 스크린 리더 같은 보조 기술로 웹을 이용합니다. 올바른 HTML 구조는 이런 보조 기술이 페이지의 내용을 정확히 읽어 주는 바탕이 됩니다.

간단한 HTML 문서를 만들어 보겠습니다. 로고까지 확인하려면 index.html과 같은 폴더에 logo.png 파일을 준비하세요. 이미지가 없다면 제목, 문단, 링크부터 확인하고, 이미지는 파일을 준비한 뒤에 확인합니다.

index.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>나 혼자 웹 개발</title>
</head>
<body>
    <h1>환영합니다!</h1>
    <p>이것은 첫 번째 HTML 페이지입니다.</p>
    <img src="logo.png" alt="로고 이미지">
    <a href="https://www.google.com">구글로 이동</a>
</body>
</html>

이 파일을 브라우저에서 열면 환영합니다!라는 큰 제목과 그 아래의 문단, 로고 이미지, 구글로 이동 링크가 차례로 보입니다. 아직 스타일이 없으므로 브라우저의 기본 모양 그대로이며, 건물로 치면 뼈대만 세운 상태입니다.

보기에는 단순해도 이 단계에서 의미 구조는 이미 갖춰져 있어야 합니다. 제목은 h1, 문단은 p, 링크는 a처럼 의미에 맞는 요소를 썼기 때문에, 나중에 모양을 바꾸거나 동작을 붙여도 구조는 그대로 둘 수 있습니다. 처음부터 의미 없는 div만 쓰면 접근성과 검색, 유지 보수에서 나중에 더 많은 비용을 치르게 됩니다.


CSS: 웹 페이지의 모양

HTML이 뼈대를 세웠다면, CSS(Cascading Style Sheets)는 그 뼈대의 모양을 정합니다. 글자의 색과 크기, 글꼴, 배경, 여백, 요소의 배치처럼 눈에 보이는 모든 것이 CSS의 일입니다. 건물에 비유하면 벽지를 바르고 페인트를 칠하고 가구를 배치하는 인테리어에 해당하며, 같은 구조의 건물도 인테리어에 따라 분위기가 완전히 달라지듯이 같은 HTML도 CSS에 따라 전혀 다른 인상을 줍니다.

CSS의 주요 특징은 다음과 같습니다.

  • 선택자와 속성으로 씁니다: 선택자(selector)로 HTML 요소를 고르고, 그 요소에 적용할 속성(property)과 값(value)을 적습니다. 예를 들어 p { color: blue; font-size: 16px; }는 모든 <p> 요소의 글자색을 파란색으로, 글자 크기를 16px로 정합니다.
  • 화면 크기에 맞출 수 있습니다: 데스크톱, 태블릿, 스마트폰처럼 화면 크기가 다른 기기에서 배치와 스타일을 바꾸는 반응형 웹 디자인도 CSS로 만듭니다.

앞의 HTML에 CSS를 더해 보겠습니다. <head> 안에 <style> 요소를 넣고 그 안에 CSS를 씁니다.

index.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>나 혼자 웹 개발</title>
    <style> /* 여기에 CSS 코드를 작성합니다 */
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f4f4;
            color: #333;
            text-align: center;
            padding-top: 50px;
        }
        h1 {
            color: #0056b3;
            font-size: 3em;
            margin-bottom: 20px;
        }
        p {
            font-size: 1.2em;
            line-height: 1.6;
            margin-bottom: 30px;
        }
        img {
            max-width: 200px;
            height: auto;
            border-radius: 10px;
            box-shadow: 5px 5px 15px rgba(0,0,0,0.2);
            margin-bottom: 20px;
        }
        a {
            color: #28a745;
            text-decoration: none;
            font-weight: bold;
        }
        a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <h1>환영합니다!</h1>
    <p>이것은 첫 번째 HTML 페이지입니다.</p>
    <img src="logo.png" alt="로고 이미지">
    <a href="https://www.google.com">구글로 이동</a>
</body>
</html>

이제 배경이 연한 회색으로 바뀌고, 글꼴과 글자 크기가 달라지며, 제목은 파란색, 링크는 밑줄 없는 초록색 굵은 글씨가 됩니다. 이미지는 너비가 200px을 넘지 않도록 줄어들고 모서리가 둥글어지며 그림자가 생깁니다. HTML의 요소와 내용은 하나도 바꾸지 않았다는 점에 주목하세요. CSS는 구조를 건드리지 않고 표현만 바꿉니다.


자바스크립트: 웹 페이지의 동작

HTML과 CSS가 구조와 모양을 정했다면, 자바스크립트(JavaScript)는 페이지에 동작을 더합니다. 사용자의 행동에 반응해 내용을 바꾸거나, 서버와 데이터를 주고받거나, 계산을 하는 일이 자바스크립트의 몫입니다. 건물에 비유하면 엘리베이터, 자동문, 조명 스위치처럼 사람이 조작했을 때 반응하는 장치를 다는 일입니다.

자바스크립트의 주요 특징은 다음과 같습니다.

  • 이벤트에 반응합니다: 클릭, 마우스 움직임, 키보드 입력 같은 이벤트가 일어났을 때 실행할 코드를 등록합니다.
  • DOM을 바꿉니다: 브라우저가 HTML을 읽어 만든 DOM(Document Object Model)에서 요소를 찾고, 내용을 바꾸거나 요소를 추가하고 지웁니다.
  • 서버와 통신합니다: fetch() 같은 API로 페이지를 새로고침하지 않고 서버와 데이터를 주고받아 화면의 일부만 갱신합니다. 예전에는 이런 방식을 AJAX(Asynchronous JavaScript and XML)라고 불렀습니다.
  • 브라우저 밖에서도 씁니다: Node.js로 서버를, React Native로 모바일 앱을, Electron으로 데스크톱 앱을 만드는 등 여러 분야에서 쓰입니다.

앞의 페이지에 자바스크립트를 더해, 환영합니다! 제목을 클릭하면 문구가 바뀌게 만들어 보겠습니다.

index.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>나 혼자 웹 개발</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f4f4;
            color: #333;
            text-align: center;
            padding-top: 50px;
        }
        h1 {
            color: #0056b3;
            font-size: 3em;
            margin-bottom: 20px;
            cursor: pointer; /* 클릭할 수 있다는 시각적 힌트 */
        }
        h1:hover {
            opacity: 0.8; /* 마우스를 올리면 약간 투명하게 */
        }
        p {
            font-size: 1.2em;
            line-height: 1.6;
            margin-bottom: 30px;
        }
        img {
            max-width: 200px;
            height: auto;
            border-radius: 10px;
            box-shadow: 5px 5px 15px rgba(0,0,0,0.2);
            margin-bottom: 20px;
        }
        a {
            color: #28a745;
            text-decoration: none;
            font-weight: bold;
        }
        a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <h1 id="mainTitle">환영합니다!</h1>
    <p>이것은 첫 번째 HTML 페이지입니다.</p>
    <img src="logo.png" alt="로고 이미지">
    <a href="https://www.google.com">구글로 이동</a>

    <script>
        // 'mainTitle'이라는 id를 가진 요소를 찾습니다.
        const titleElement = document.getElementById('mainTitle');

        // 찾은 요소에 클릭 이벤트 리스너를 등록합니다.
        titleElement.addEventListener('click', function() {
            // 클릭할 때마다 두 문구를 번갈아 표시합니다.
            if (titleElement.textContent === '환영합니다!') {
                titleElement.textContent = '클릭해 주셔서 감사합니다!';
            } else {
                titleElement.textContent = '환영합니다!';
            }
        });
    </script>
</body>
</html>

제목을 한 번 클릭하면 클릭해 주셔서 감사합니다!로 바뀌고, 다시 클릭하면 환영합니다!로 돌아옵니다. 문구가 바뀌지 않는다면 파일을 저장했는지, 제목의 id="mainTitle"과 getElementById()에 넘긴 이름이 같은지, 개발자 도구의 Console 패널에 오류가 있는지 확인합니다.

getElementById()는 제목 요소를 찾고, addEventListener()는 클릭했을 때 실행할 함수를 등록합니다. 등록만 한 상태에서는 문구가 바뀌지 않으며, 클릭해야 함수가 실행되어 현재 textContent를 비교한 뒤 다음 문구를 정합니다. 이 코드는 저장된 HTML 파일을 고치는 것이 아니라 열려 있는 페이지의 DOM을 바꾸므로, 새로고침하면 처음 문구로 돌아옵니다. <script>를 <body>의 끝에 둔 것은 스크립트가 실행될 때 제목 요소가 이미 만들어져 있어야 하기 때문입니다.

제목 클릭은 세 언어의 관계를 짧게 보여 주기 위한 예제입니다. 실제로 사용자가 조작할 기능을 만들 때는 키보드로도 쓸 수 있는 <button> 같은 요소를 먼저 고릅니다. h1은 마우스로만 클릭할 수 있고, 키보드의 Tab 키로 초점을 옮길 수 없기 때문입니다.

더 깊이: 자바스크립트와 ECMAScript는 무엇이 다를까

자바스크립트의 언어 문법과 내장 객체는 ECMA-262라는 표준 문서가 정하며, 이 표준이 정의하는 언어의 이름이 ECMAScript입니다. 표준은 Ecma International의 TC39 위원회가 만들고, 2015년 6월의 6판부터는 해마다 6월에 새 판을 내면서 ECMAScript 2015처럼 연도를 이름에 붙입니다. 흔히 ES2015나 ES6라고 줄여 부르는 것이 이 6판이며, 2026년 6월에 나온 17판이 ECMAScript 2026입니다.

새 기능은 제안(proposal)으로 시작해 TC39의 단계(stage)를 거칩니다. 아이디어인 0단계부터 해법을 검토하는 1단계, 명세 초안을 쓰는 2단계, 테스트와 구현으로 검증하는 2.7단계, 구현을 권하는 3단계를 지나 4단계에 이르면 완성된 것으로 봅니다. 4단계가 되려면 Test262라는 공식 테스트를 통과하는 호환 구현이 둘 이상 있고 실제로 출시된 구현에서 쓰인 경험도 있어야 하며, 그 뒤에 해마다 나오는 판에 실립니다. 그래서 브라우저는 표준 판이 나오기 전에 그 기능을 먼저 갖추는 것이 보통이고, 어느 판에 들어갔는지와 지금 쓰는 브라우저에서 동작하는지는 따로 확인해야 합니다.

이 글의 getElementById(), addEventListener(), textContent는 ECMAScript가 아니라 DOM 표준이 정한 웹 API입니다. 같은 자바스크립트 코드라도 Node.js에는 document가 없는 이유가 여기에 있습니다. 언어는 같아도 실행 환경이 제공하는 API가 다르기 때문입니다. 단계별 기준은 TC39의 절차 문서에 정리되어 있습니다.


맡은 일을 나누는 이유

세 언어를 섞어 쓸 수는 있습니다. 자바스크립트로 HTML을 만들고 스타일까지 바꿀 수도 있지만, 모든 것을 스크립트로 처리하면 구조와 모양이 코드 속에 흩어져 어디를 고쳐야 할지 찾기 어려워집니다. 구조는 HTML, 표현은 CSS, 상호작용은 자바스크립트라는 기본 나눔을 지키면, 변경 요청이 들어왔을 때 고칠 곳이 바로 정해지고 테스트와 디버깅도 쉬워집니다.


정리

  • HTML은 내용과 구조를, CSS는 색, 크기, 배치 같은 표현을, 자바스크립트는 이벤트에 반응하는 동작을 맡습니다.
  • HTML에서는 모양보다 먼저 의미에 맞는 요소로 구조를 만들며, 이 구조가 접근성과 검색의 바탕이 됩니다.
  • CSS는 선택자로 요소를 골라 속성과 값을 적용하며, HTML을 바꾸지 않고 표현만 바꿉니다.
  • 자바스크립트는 DOM에서 요소를 찾아 이벤트를 등록하고, 열려 있는 페이지의 내용을 바꿉니다.
  • 변경 요청을 받으면 먼저 그것이 구조, 표현, 동작 중 무엇에 관한 것인지 나눠 고칠 곳을 정합니다.

연습 문제

1. 변경 위치 정하기

마지막 예제를 기준으로 ① 첫 제목을 “내 소개”로 바꾸기, ② 제목 색을 초록색으로 바꾸기, ③ 클릭한 뒤 문구를 “반갑습니다!”로 바꾸기를 요청받았습니다. 각각 어디를 고쳐야 할까요? ③만 바꿨다면 새로고침 직후와 첫 클릭 직후에 어떤 문구가 보일까요?

해설 보기

①은 HTML의 h1 안의 글자를, ②는 CSS의 h1 규칙에 있는 color를, ③은 자바스크립트의 첫 번째 분기에서 textContent에 넣는 문자열을 고칩니다.

③만 바꾸면 새로고침 직후에는 HTML에 적힌 “환영합니다!”가, 첫 클릭 직후에는 “반갑습니다!”가 보입니다. 다음 클릭에서는 textContent가 “환영합니다!”가 아니므로 else로 가서 다시 “환영합니다!”로 돌아옵니다.

2. 둘 다 바꾼 경우

①과 ③을 함께 적용해, HTML의 제목은 “내 소개”로, 첫 번째 분기의 문구는 “반갑습니다!”로 바꿨습니다. 조건문의 '환영합니다!'는 그대로 두었습니다. 새로고침한 뒤 제목을 클릭하면 어떻게 될까요?

해설 보기

처음에는 “내 소개”가 보입니다. 클릭하면 textContent가 '환영합니다!'와 같지 않으므로 else로 가서 “환영합니다!”로 바뀝니다. 다시 클릭하면 이번에는 조건이 참이 되어 “반갑습니다!”가 되고, 그 뒤로는 “환영합니다!”와 “반갑습니다!”가 번갈아 나타납니다.

“내 소개”는 다시 볼 수 없습니다. HTML의 처음 문구를 바꿨다면 조건문에서 비교하는 문자열도 함께 바꿔야 의도대로 동작합니다.

3. 새로고침한 뒤의 문구

제목을 한 번 클릭해 클릭해 주셔서 감사합니다!가 보이는 상태에서 새로고침했습니다. 어떤 문구가 보일까요? 그 이유는 무엇일까요?

해설 보기

환영합니다!가 보입니다. 자바스크립트는 열려 있는 페이지의 DOM만 바꿨을 뿐, 서버나 디스크에 있는 index.html 파일은 바꾸지 않았습니다. 새로고침하면 브라우저가 원래 파일을 다시 읽어 DOM을 처음부터 만들기 때문에 HTML에 적힌 처음 문구가 다시 보입니다.

다음 글 개발 환경 설정에서는 이런 파일을 편하게 만들고 확인할 수 있도록 편집기와 브라우저, 실습 폴더를 준비합니다.