[Java 풀스택 개발자] HTML과 CSS의 구성에 대해

부트캠프 일지/멀티캠퍼스 TIL
2026.01.06

0. 들어가기에 앞서

본 포스트에서는 12월 29일부터 1월 6일까지 Java 풀스택 개발자 과정에서 교육 받았던 내용에 대해서 정리 및 복습을 한다. 웹페이지 개발의 기본적인 이론과 함께, 지금까지 배워왔던 웹페이지의 각 구성 요소에 대해서 돌아볼 예정이다. JS의 경우 다음 주차에서 이어서 다뤄보겠다.
 
 

1. 웹페이지 개발! 프론트엔드와 백엔드, 그리고 퍼블리싱?

이런 말을 들어본 적 있을까? HTML은 개발 언어가 아니다. 프로그래밍이 아니며 개발언어라고 하지 않는다. 그렇다면 이런 의문도 들 것이다. 그렇다면 웹페이지를 만드는 사람들은 개발자가 아닐까? 하지만 프론트엔드 개발자, 백엔드 개발자라는 단어를 자주 사용한다. 그러면 대체 웹페이지는 어떤 구성으로 되어 있는 걸까? 어떻게 되어 있길래 무엇은 개발 언어라고 하고, 무엇은 개발언어라고 하지 않을까? 그리고 웹 퍼블리셔라는 호칭은 무엇일까?
 

프론트엔드? 백엔드? HTMl은 개발언어가 아닌데 JS는 개발 언어? 웹은 왜 이렇게 복잡할까?

 
 
하나의 웹 페이지가 우리에게 도달하기 위해서는 수 많은 과정이 필요하다. 아무 웹 페이지를 켜서 들어가보자. 그들은 각자의 주소를 가지고 있다. 네이버라면 www.naver.com,  구글이라면 google.com 등. 이 주소를 바로 URL(Uniform Resource Locator)이라고 한다. 이 주소를 치지 않으면 그 페이지로 들어갈 수 없다. 그리고 그 주소를 통하여 그 페이지의 서버에게 페이지를 보여달라고 요청하는 것이다.
우리를 우체부라고 생각해보자. 주소를 알지 못하면 편지를 전달해줄 수 없다. 주소를 찾아갔다고 해도 집이 존재하지 않아 받을 사람이 없으면 편지를 마찬가지로 전달해줄 수 없다. 즉, 주소는 URL이고 집은 서버라고 할 수 있다. 우리가 집을 찾아 초인종을 누른다. 이것이 요청이다. 그 초인종을 듣고 수취인이 나와 우리에게 수취확인을 해준다. 이게 서버에서의 응답이다. 그러한 생각보다 복잡하고 긴 과정을 거쳐야 지금 우리가 보고 있는 이 페이지를 볼 수 있다.
 

이 과정은 사용자가 매번 요청할 때마다 반복된다.


 
그 "집"을 만드는 목공들이 바로 백엔드(Back-end) 개발자라고 할 수 있다. 서버를 구축하고, 서버에 담겨야할 정보들(데이터베이스)을 만드는 게 백엔드의 역할이다. 프론트엔드를 존재할 수 있게 하는, 일단 사용자로 하여금 주소에 접속은 할 수 있게 하는 것이 백엔드의 역할이다. 집이 없으면 주소 자체가 존재한다 해도 없는 거나 다름없다. 아무 영어나 숫자를 적어서 접속을 해보면, 그 주소는 있지만 그 주소를 이루는 서버는 존재하지 않아 접속할 수가 없다.
 
그러면 프론트엔드(Front-End)는 무엇일까? 수취인이라고 할 수 있다. 편지를 받을 수취인이 없으면 우체부는 집 앞에서 전전긍긍하거나, 다시 돌아갈 수밖에 없다. 접속을 했지만 하얀 페이지만 나오게 되는 것이다. 우체부와 직접 만나 대화를 나누고 편지를 받는, 즉, 사용자(user)와 상호작용하는 것이 바로 프론트엔드이다. 프론트엔드는 HTML, CSS, JS의 세 가지로 이루어져 있다. 수취인의 태도가 친절할 수도(해당 페이지가 사용경험이 좋을 수도) 불친절할 수도(경험이 나쁠 수도) 있다. 그래도 우리는 일단 편지를 전달했다. 이 수취인에 대해서 좋다고 할지, 싫다고 할지, 이 집에 편지배달을 앞서 맡을지는 그 이후의 문제다.

우리가 준 집하물(요청)을 프론트엔드라는 수취인이 나와서 받아주고 있다. 우리는 수취인이 어떤 사람인지 알 수 있다.



이런 프론트와 백을 모두 담당하는 사람들을 풀스택 개발자라고 한다. 전체 개발을 담당하면 백과 프론트 양쪽을 한꺼번에 관리할 수 있다. 프론트에서 필요한 것, 백에서 필요한 것을 직접 확인하고 수정할 수 있다는 지점에서 이점이 크다.

그러면 이들은 개발자라할 수 있을까? 웹 페이지를 구성하는 서버와 데이터베이스 언어(백엔드), HTML이나 CSS, JS에서 HTML과 CSS는 개발 언어로 취급하지 않는다. 개발 언어의 기준에 대한 조건은 미세하게 다르지만, 다음과 같다할 수 있다.



즉, 이 때문에 HTML과 CSS는 개발 언어가 아니다. 하지만 JS, 그리고 백엔드에서 사용하는 Java 등의 언어는 개발 언어이기 때문에 웹 개발자 또한 개발자라 불리고 있다.

웹 퍼블리셔가 웹 개발자가 아니라 퍼블리셔라 불리는 이유또한 그러하다. 그들은  HTML과
CSS를 통하여 홈페이지를 구현한다. JS를 사용하기도 하지만 한계적으로 사용하기 때문에, 개발자라는 명칭으론 잘 불리지 않는 것이다.
 

사용자에게 하나의 홈페이지를 보여주려면 여러 사람의 힘이 필요하다


 

2. HTML과 CSS, JS는 무엇인가?

각 개념에 들어가기에 앞서, 웹페이지를 하나의 집- 홈페이지(Homepage)라는 이름에 걸맞는 비유로-이라고 정의해보자. 그렇다면 HTML은 집 그 자체, CSS는 인테리어, JS는 도면이라고 할 수 있다.
그런 의미에서 HTML(HyperText Markup Language)이 가장 중요하다. 인테리어 자재가 있든, 방의 계획을 어떻게 잡았든, 집 그자체가 완성되지 않으면 그것을 집이라고 할 수는 없다. CSS가 있어도, JS가 있어도 이 요소들(Element) 자체가 존재하지 않으면 볼 수가 없다.
CSS(Cascading Style Sheets)는 인테리어다. HTML만 만들어졌다 치자. 집이 있기 때문에, 얼마든지 지낼 수 있다. 하지만 아무런 칠도 없는 콘크리트에서 몸을 눕히고 싶은 사람은 그다지 없다. 벽지는 무슨 패턴으로 할 건지, 벽은 무엇으로 할 건지 정하여 집을 보기 좋게, 편하게 만드는 것. 그것이 CSS의 역할이다.
JS(JavaScript)는 도면이다. 당장 도면이라고 이야기하면 그다지 와닿지 않는 비유일 것이다. 이 집, 그리고 방의 기능을 지정하는 것이 바로 JS의 역할이다. 어떤 방을 화장실로 사용할 것인지, 어느 방이 침실이 될 것인지, 발코니는 어디인지를 지정하는 게 JS다. 현실에서의 원룸처럼, 따로 지정하지 않아도(아예 사용하지 않더라도) 사는 것에는 문제가 없지만, 더 쾌적하게, 집의 기능을 최적화하는 게 JS의 역할이라 할 수 있다.
 

이 셋의 구조에 대해서는 인체로도 자주 비유된다.


 
기본 축이 되는 HTML을 CSS로 꾸미고, JS로 기능을 살려 구축하는 게 우리가 보고 있는 웹페이지의 구성 삼요소라고 할 수 있다. 당장 구글이나 네이버 같은 우리에게 친숙한 웹사이트도 HTML, CSS, JS 세 가지로 이루어져 돌아간다.
 
 
 

3. HTML이란?

HTML은 HyperText Markup Language의 약자로서, 마크업 언어이다. 마크업 언어(Markup language)란? 위키에서는 문서의 구조와 서식, 그리고 잠재적으로 각 부분 간의 관계를 지정하는 텍스트 인코딩 시스템이라고 소개하고 있다. 이게 무슨 소리냐하면, HTML은 태그(tag)라는 것을 사용하여 웹 페이지를 젠가 쌓듯이 쌓아서 보여주는, 일종의 뼈대 역할과 비슷하다. 위에서는 집 자체에 비유를 했는데, 정확히는 그저 집일 뿐이고 아무것도 없는 텅 빈 공간을 HTML이라고 할 수 있다. 안에는 가구 같아보이는 게 있을지도 모르지만, 그것들을 가구라고 하기 위해서는 JS와 CSS의 도움이 필요하다. 우리가 기본적인 것이라고 생각하는 것들도, 사실은 CSS와 JS의 도움을 받아 브라우저 내에서 그 형태로 출력하고 있다.
 
예를 들어 <p>라는 태그가 있다 치자. 이 <p>의 기본적인 속성은 "블록 형태"라는 것이다. 그러나 그것 또한 브라우저 등에서 처리하여 "블록 형태"로 보일 뿐, 사실 이 <p> 태그 자체는 아무것도 아니다. 그저 꺾쇠 두 개와 p라는 문자로 이루어진 것일뿐, 그게 <p>라는 문단 블록이라고 얘기할 수 있게 된 건 그런 '약속'을 가지고 스타일로 출력하기 때문이다.
 

<p>의 고백. 존재만으로는 아무것도 성립되지 않는다.


 
그렇다면 약속되어 있는, 이 마크업 규칙들-이라고 하겠다-에는 무엇이 있을까? 태그(Tag)라는 이름을 붙이지만 요소(Element)라는 이름으로도 자주 사용된다. 그 태그들에 대한 설명을 하고자 한다.
태그들은 기본적으로 여는 태그와 닫는 태그를 가지고 있다. <요소>로 열고 </요소>로 닫는다. img, br, hr 같은 소수의 예외만이 닫는 태그 없이도 사용할 수 있다.
 

HTML의 태그들

문서구조 태그들

  • <html></html>
    • HTML을 여는 태그다. 생략하여도 문제는 없다.
  • <head></head>
    • 화면에는 보이지 않지만 웹에서 알거나 확인해야할 정보를 포함한다. 대표적으로 meta, link, title 태그가 있다.
  • <body></body>
    • 화면 본문에 보이는 태그다. 이 태그가 대부분을 차지한다고 볼 수 있다.

 
head는 css나 js 파일 등 외부 파일을 불러올 때도 사용한다. 요즘은 head 태그 안에 넣지 않아도 불러올 수는 있지만, 기본적인 것은 전부 head에서 사용한다. head는 머리라는 그 직접적인 뜻과 비슷한 일종의 얼굴이다. 화면에는 보이지 않는데 어째서 얼굴이라고 할 수 있을까? 그것은 head는 이것이 어떤 웹페이지인지 알 수 있는 태그들을 사용하기 때문이다. title 태그는 그야말로 페이지의 제목을 나타낸다. meta 태그는 이 페이지가 어떤 언어로 쓰였는가를 정하기도 하고, 이게 어떤 페이지인가를 보여주는 용도에서도 사용한다.
구글이나 다른 포털의 검색창에서 검색을 하면 보이는 수많은 페이지들을 본 적이 있을 것이다. 이 페이지들을 표기하는 것 또한 head의 역할이다.
 

사이트의 '제목', 그리고 아래에 적혀있는 이 사이트가 무슨 사이트인지 나타내는 '요약'을 보여주는 것도 head의 일이다.

 
 
body는 그야말로 몸이다. 아래부터 대부분은 body에서 사용되는 태그일 정도로, html에서 body의 비중은 크다고 할 수 있다. 
 

텍스트 태그 - p, span, br, b, s...

웹페이지는 이미지로만 이루어지지 않는다. 우리가 인터넷으로 유튜브를 볼지언정 반드시 그 동영상을 설명하는 글, 즉 '텍스트'는 존재한다. 특히 도스 시대부터 웹 페이지는 텍스트와 함께 해왔다고 해도 과언이 아니다. 이러한 텍스트의 태그들 또한 많다. 텍스트 태그는 <p>나 <span> 같은 것도 있지만, <b>, <i> 같은 장식용 태그도 존재한다.
 

하이퍼링크 태그 - a

<a> 태그를 흔히 하이퍼링크 태그라고 한다. a는 앵커(anchor)의 약자이다. 하이퍼링크란, 다른 문서(다른 웹페이지)로 가기 위한 하나의 통로이다. 링크라는 이름 그대로 연결해주기 위해서 존재한다. 이 태그가 없다면 주소를 복사 및 붙여넣기 하는 번거로운 방식을 사용해야 할 것이다.
 

목록 태그 - ul,ol,li...

리스트 태그라고도 하는 이것은, <ul>과 그 부속인 <ol>와 <li> 태그를 의미한다. <dl>이나 <dd>, <dt> 같은 태그도 사용하지만 대부분은 <ul> 태그를 사용한다. 지금 이 화면 오른쪽에 있는 목차 또한 목록 태그를 통해서 만들어진 것이다. 
 

테이블 태그 - table

<table> 태그, 흔히 말하는 표를 작성해주는 태그이다. 이전 개발일지에도 밝혔듯이, 테이블 태그는 처리 과정에서 미지원하는 곳도 생겨 사장 되어가는 추세다.
하지만 회사의 데이터 처리를 엑셀이 맡듯이, HTML의 데이터 처리에 table만큼 직관적인 것은 없다.
 

이미지 태그 - img

 말 그대로 이미지 파일을 삽입시켜주는 태그다. SRC라고 하는, 외부에서 파일 등을 불러올 때 사용하는 속성과 주로 같이 쓴다.

다른 문서 태그

iframe이라고 하는, 외부 문서를 불러올 때 사용한다. 요즘은 frame의 개념이 약해져(아래 div의 개발과도 관련이 있다.) 자주 사용하진 않는다.
 

입력 양식 태그 - form, input, textarea, select

구글 설문지나 네이버 폼, 아니면 회원가입 창에서 사용하는 양식 태그다. input은 짧은 글(혹은 숫자 등을)을 넣고, textarea는 줄바꿈이 가능한 긴 글을 넣을 수 있다.
input에는 다수 선택형(checkbox)나 단일 선택형(radio) 등도 있어 네, 아니오 같은 단순한 질문도 편하게 쓸 수 있다.
 

공간 분할 태그

 대체로 div이나 span을 지칭한다. HTML5에 들어서서 div은 아주 큰 비중을 차지하는 태그가 되었다. div은 divider의 약자다. 아무 페이지만 열어봐도 div으로 대부분 구성이 되어있다는 걸 알 수 있다.
span은 p와 같은 block형 요소에서 inline 요소로서 자리를 차지한다.

div의 발전과 별개로 div으로만 모든 태그가 구성되면, HTML만으로는 구조를 알기가 어려워진다. 그래서 HTML5에서는 header, nav, aside, section, footer와 같은 공간분할 태그들이 추가되었다. 추가된 분할태그들은 다음과 같은 위치를 나타낸다.

article이 보통은 메인의 형태로 나타나지만, 작성자에 따라서 구조가 조금씩 다를 때도 있다.



 

4. CSS란?

CSS는 Cascading Style Sheets의 약자이다. 스타일 시트 언어라고도 한다. HTML을 꾸며주는 역할을 한다. 만약 CSS를 따로 작성하지 않아도 스타일이 지정되어 있는 걸 볼 수 있는데, 이것은 브라우저 등에서 자체 지원을 하는 스타일이다. 즉, 그것마저 없으면 HTML의 태그는 그 자체로서는 별 기능이 없다고 할 수 있다.
 

이 a 태그의 색상마저 사실 스타일이 입혀져 있는 것이다.

 
여기서 Cascading이라는 단어의 뜻은 폭포처럼 위에서 아래로 떨어진다는 의미인데, 이것은 바로 CSS의 처리 방식 때문에 정해졌다. 같은 것이어도 우선순위에 따라서 차등적으로 적용된다. 더 높은 우선순위의 규칙이 낮은 규칙을 덮어쓰는, 점층적(Cascading) 방식이기 때문에 Cascading이라는 수식어가 붙여졌다.
우연인지 혹은 의도한 것인지 '위에서 아래로'라는 규칙 또한 적용된다. 위에서 아래로! 기억해두자. 이 때문에 같은 선택자로 지정해도 아래에 있는 것이 최종적으로 나타난다.

폭포처럼 위에서 아래로 정해지는 게 기본이다.

 
스타일 적용 순서에 대해서는 개발일지 포스트에서 따로 리스트로 정리해둔 적이 있다. 이번에는 좀 더 이미지로 깔끔하게 정리해보았다.
 

위에서 아래로! head에서 body로! 넓은 곳에서 좁은 곳으로! 물론 예외처리는 있지만 그래도 보통의 경우 이렇게 흘러간다.


 
 

CSS에서 중요한 '선택자'

선택자라는 건 '선택'한다는 의미이다. CSS의 스타일 규칙을 이 요소에게 적용하겠다는 지명과도 같다. 사회자가 대회 참가자를 지명해서 퍼포먼스를 보려는 것과 같다. 하지만 모든 것에 하나하나 요소를 지명하는 건 그야말로 힘들다. 그렇기 때문에 선택자에도 종류가 존재하고, 그 종류에 따라서 범위도 달라진다.
 
대학생들이 술자리에서 흔히 하는 손병호 게임을 생각해보자. 손병호 게임은 특정 속성(attribute)을 가지고 있는 사람들에게 손가락을 접으라고 한다. 그러다가 자신이 벌칙을 주고 싶은 단 한 명의 사람이 생기면 그 사람만 가지고 있는 속성(이름에 OO가 들어가는 사람~!)만을 부르기도 한다. 선택자라는 것은 마치 이런 손병호 게임과도 같다.
 

tag 요소가 div인 요소 접어! class 이름이 A인 요소 접어! 하다보면 해당하는 요소는 수많은 스타일을 달게 될 것이다.


 
선택자는 ① 태그 ② 클래스 ③ 아이디 ④ 속성 ⑤ 상태로 분류할 수 있다. 선택자 또한 Cascading 방식이 적용되기 때문에, 우선순위가 따로 정해져 있다. 아이디 > 상태 > 클래스/속성 > 태그 순서로 강하게 적용된다. 각 태그에 대해서는 다음처럼 설명이 가능하다.
 

1. 태그 선택자

div, a, h1 등등을 지정한다. 요소(Element) 선택자라고도 한다. HTML의 태그를 지목하는, 넓은 범위의 선택자다. 위에서 설명했듯이, 우리가 기본적인 것이라 생각하는 것도 이미 CSS가 적용되고 있다. 비유를 하면 하나의 집단이라고 할 수 있다. 고등학생, 사회인, 여자, 남자 등등 … 나를 설명할 수 있는 어떠한 집단을 태그 선택자라고 보면 쉽다.
 

2. class 선택자

일종의 그룹이라고 할 수 있다. 동호회가족과 같은, 태그보다는 조금 더 좁으며 이름을 붙일 수 있는 선택자로, 태그 선택자처럼 각각 다른 집단의 속성을 가질지언정 이 class 로 지정한 것 아래에서는 모두 동일하게 적용된다.
 

3. id 선택자

하나의 개인이라고 할 수 있다. 남들과 구분되는 '나의 이름'이다. 특별하며, 구분 가능한 나다. 그러므로 선택자 중에서 가장 좁다고 할 수 있다.
 

4. 속성/상태 선택자

집단 중에서도 어떠한 상태에 있는 집단을 말할 수 있다. 독감에 걸린 고등학생이나 잠들어 있는 남자와 같이, 언제든 변할 수 있지만 그 상태일 경우, 그 속성을 가지고 있을 경우에는 이 규칙을 적용하라는 것이다.

 

내 가족은 class, 나는 id라는 이름으로 식별된다.

 

부모와 자식, 그리고 자손 선택자

앞서 class를 가족이나 동호회로 비유를 했는데, 정말 가족으로 비유되는 복합 선택자가 존재한다. 부모와 자식, 그리고 자손, 형제가 존재한다. 일반적으로 자신의 여는 태그와 닫는 태그 사이에 있는 존재를 자식이라고 하고, 자신이 어떠한 태그의 여는 태그와 닫는 태그 사이에 있다면 그것을 부모라고 한다. 부모의 속성은 자손에게 보통 승계된다.
 

* 2026년 1월 8일에 이 설명에 대해서 추가 보충합니다.
관습을 물려받는다라는 것은 일부분에서만 적용된다. 상속 속성(inherited properties)인 것은 물려받고, 그렇지 않은 것은 물려받지 않는다. 상속 속성의 대표적인 예는 color나 font 같은 글자 관련 스타일이다. 반면, margin이나 padding, border 같은 것은 물려받지 않는다(관련 링크).


 

나는 할아버지의 손자이며 내 아버지의 자식이고, 내 형제의 형제이다.

 
를 중심으로 생각해보자. 나는 부모로부터 어떠한 관습을 물려받는다고 하자. 그것이 하나의 스타일 규칙이다. 그리고 나는 그것을 내 자식에게 물려주고, 내 자식은 그 자식, 즉 자손에게 물려준다. 그 반대의 경우는 불가능하다. 승계라는 것은 위에서 아래로 이루어지기 때문이다. 이 때문에도 Cascading이라고 할 수 있다. 그리고 나는 내 형제에게도 관습을 전달해줄 수 있다. 물론 관습을 자식이나 내 자손이 깨버릴 수도 있다.
 
이것이 앞서 설명한 선택자와 같이 적용된다고 하면, 내 자손은 나라는 존재의 자손으로 특정이 된다. A라는 class명을 가진 가족의 자식은 A라는 class의 영향을 받으면서도, 동시에 A라는 class명을 가진 가족의 자식이라는 "특정"으로 지목이 될 수 있다. 이 규칙에 관한 문법은 아래 이미지로 정리한다.
 


 
 

5. 정리하며

css에도 다양한 규칙이 있지만, 그것은 다양한 표현법으로 나타나기 때문에 가장 핵심적인 선택자만을 정리해보았다. 다음 주차에서는 JS에 대한 상세한 개념을 다룰 예정이다.