← 메인 페이지로
index.html 완전 해부
태그 · 속성 · 스타일 · 스크립트 전체 설명
대상 독자: HTML, CSS, JavaScript의 "역할"은 알지만, 문법은 전혀 모르는 사람
- HTML = 페이지의 뼈대(구조)를 만든다
- CSS = 뼈대에 살을 입힌다 (색상, 크기, 배치 등 시각적 꾸밈)
- JavaScript = 사용자의 행동에 반응하는 동적 기능을 만든다
0. 문서 전체를 감싸는 껍데기
<!doctype html>
- "이 파일은 HTML5 문서입니다"라고 브라우저에게 알려주는 선언문.
- 이것이 없으면 브라우저가 오래된 방식으로 해석할 수 있다.
<html lang="ko"> ... </html>
- 문서 전체를 감싸는 최상위 태그.
lang="ko" → 이 문서의 언어가 한국어(ko)임을 선언. 검색엔진과 스크린 리더(시각장애인용 읽기 프로그램)가 활용한다.
1. <head> — 눈에 보이지 않는 문서 설정 영역
<head> 안에 있는 내용은 화면에 직접 표시되지 않는다.
브라우저·검색엔진·SNS 등이 참고하는 메타(부가) 정보를 담는다.
1-1. <meta charset="utf-8" />
- charset = character set(문자 집합).
utf-8은 한글, 영어, 이모지 등 전 세계 모든 문자를 표현할 수 있는 인코딩 방식.
- 이걸 빠뜨리면 한글이 깨질 수 있다.
1-2. <meta name="viewport" content="width=device-width, initial-scale=1" />
- viewport = 사용자가 보는 화면 영역.
width=device-width → 화면 너비를 기기의 실제 너비에 맞춘다 (모바일 대응의 핵심).
initial-scale=1 → 처음 열었을 때 확대/축소 없이 원래 크기(100%)로 보여준다.
1-3. <title>songdaegeun 소개 | 즐겁게 배우는 코딩</title>
- 브라우저 탭에 표시되는 제목.
- 검색 결과에서도 이 제목이 노출된다.
1-4. <meta name="description" content="...">
- 검색엔진 결과에서 제목 아래에 보이는 설명 문구를 지정한다.
- 직접 화면에 보이지는 않지만, SEO(검색엔진 최적화)에 중요하다.
1-5. <style> ... </style> — CSS 영역
<style> 태그 안에 CSS 코드를 직접 작성한다. 외부 파일로 분리할 수도 있지만, 여기서는 HTML 안에 함께 작성한 형태(인라인 스타일시트)이다.
CSS 기초 문법 빠른 정리
선택자 {
속성: 값;
}
- 선택자(selector) — "누구를 꾸밀 것인가" (예:
body, .card, #themeToggle)
- 속성(property) — "무엇을 바꿀 것인가" (예:
color, font-size)
- 값(value) — "어떻게 바꿀 것인가" (예:
red, 16px)
선택자 종류:
| 선택자 | 의미 | 예시 |
태그명 | 해당 태그 전부 | body { } → 모든 <body> |
.클래스명 | 해당 class를 가진 요소 | .card { } → class="card"인 요소 |
#아이디명 | 해당 id를 가진 요소 | #themeToggle { } → id="themeToggle"인 요소 |
부모 자식 | 부모 안에 있는 자식 | .hero h1 { } → .hero 안의 <h1> |
선택자:상태 | 특정 상태일 때 | a:hover { } → 마우스를 올렸을 때 |
* | 모든 요소 | * { } → 페이지의 모든 요소 |
:root — CSS 변수(커스텀 프로퍼티) 정의
:root {
--bg: #0b0f1a;
--primary: #7c5cff;
...
}
:root는 문서의 최상위 요소(<html>)를 가리키는 특수 선택자.
--이름: 값; 형태로 CSS 변수를 선언한다.
- 한 번 선언해 두면 어디서든
var(--bg) 처럼 꺼내 쓸 수 있다.
- 색상을 일괄 변경할 때 변수만 바꾸면 되므로 유지보수가 쉽다.
| 변수 | 역할 |
--bg | 배경색 (짙은 남색) |
--bg-soft | 약간 밝은 배경색 |
--card | 카드 컴포넌트 배경색 |
--text | 기본 글자색 |
--muted | 덜 중요한 글자색 (회색 계열) |
--primary | 주요 강조색 (보라색) |
--primary-strong | 더 진한 보라색 |
--accent | 포인트 색상 (청록색) |
--border | 테두리 색상 |
--bg-grad-1, --bg-grad-2 | 배경 그라데이션용 반투명 색상 |
#0b0f1a 같은 값은 HEX 색상 코드이다. 6자리 16진수로 빨강/초록/파랑(RGB)을 표현한다.
rgba(124, 92, 255, 0.35)는 RGBA — 빨강 124, 초록 92, 파랑 255, 투명도 0.35(35% 불투명).
html[data-theme="light"] — 라이트 모드 변수 재정의
html[data-theme="light"] {
--bg: #f4f6fb;
...
}
html[data-theme="light"] → <html> 태그에 data-theme="light"라는 속성이 붙어 있을 때만 적용.
- 같은 변수 이름(
--bg 등)에 밝은 색상 값을 덮어씌운다.
- JavaScript가
data-theme 값을 토글(전환)하면 자동으로 다크/라이트가 바뀌는 원리.
* { box-sizing: border-box; }
* → 모든 요소에 적용.
box-sizing: border-box → 요소의 너비/높이를 계산할 때, padding(안쪽 여백)과 border(테두리)를 포함해서 계산한다.
- 이 설정이 없으면 padding을 줄 때마다 요소가 원래 크기보다 커져서 레이아웃이 깨지기 쉽다.
body { ... }
body {
margin: 0;
font-family: "Apple SD Gothic Neo", "Noto Sans KR", system-ui, -apple-system, sans-serif;
color: var(--text);
background: radial-gradient(...), radial-gradient(...), var(--bg);
line-height: 1.6;
transition: background 0.3s ease, color 0.3s ease;
}
| 속성 | 설명 |
margin: 0 | 브라우저 기본 바깥 여백 제거 |
font-family | 글꼴 우선순위. 왼쪽부터 시도하고, 없으면 다음 글꼴 사용 |
color: var(--text) | 글자색을 CSS 변수 --text에서 가져옴 |
background | 배경. radial-gradient(원형 그라데이션) 2개를 겹치고, 맨 뒤에 단색 배경(--bg)을 깔았다 |
line-height: 1.6 | 줄 간격. 글자 크기의 1.6배 |
transition | 배경색·글자색이 바뀔 때 0.3초 동안 부드럽게 전환 (다크/라이트 전환 애니메이션) |
a { color: inherit; text-decoration: none; }
a → <a> 링크 태그 전부.
color: inherit → 부모 요소의 글자색을 그대로 물려받는다 (기본 파란색 제거).
text-decoration: none → 밑줄 제거.
.container { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.container → class="container"인 요소.
max-width: 1120px → 최대 너비 1120px. 화면이 넓어도 이 이상 늘어나지 않는다.
margin: 0 auto → 위아래 여백 0, 좌우는 auto(자동)으로 → 가운데 정렬.
padding: 0 24px → 위아래 안쪽 여백 0, 좌우 24px.
header { padding: 28px 0 0; }
.nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
- Flexbox 레이아웃 사용 (요소를 가로/세로로 유연하게 배치하는 CSS 기법).
display: flex → 이 요소의 자식들을 가로로 나란히 배치.
align-items: center → 세로(교차축) 방향 가운데 정렬.
justify-content: space-between → 첫 번째 자식은 왼쪽 끝, 마지막은 오른쪽 끝, 나머지는 균등 분배.
gap: 16px → 자식 요소들 사이 간격 16px.
.logo
| 속성 | 설명 |
font-weight: 700 | 글자 굵기. 700 = bold(굵게) |
font-size: 1.2rem | 글자 크기. rem은 루트 요소 기본 크기(보통 16px) 기준 배수 → 약 19.2px |
letter-spacing: 0.3px | 글자 사이 간격을 0.3px 벌림 |
.nav-links
- 네비게이션 링크들을 가로로 나열. 간격 18px. 글자는 흐린 색.
.nav-links a:hover { color: var(--text); }
- 링크 위에 마우스를 올리면(
hover) 글자색이 기본 텍스트 색으로 변한다.
.theme-toggle { ... }
- 다크/라이트 전환 버튼 스타일.
border-radius: 999px → 아주 큰 둥근 모서리 → 완전한 알약(pill) 모양.
cursor: pointer → 마우스를 올리면 손가락 모양 커서.
.hero { ... }
- 메인 히어로(첫 화면 대형 소개) 영역.
display: grid → Grid 레이아웃 사용 (격자 형태로 배치).
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) → 각 열의 최소 너비 280px, 최대 1fr(남은 공간 균등 분배). 화면이 좁으면 자동으로 1열, 넓으면 2열.
gap: 48px → 격자 칸 사이 간격.
align-items: center → 세로 가운데 정렬.
.badge { ... }
- "🚀 코딩을 즐겁게" 라벨 스타일.
display: inline-flex → 인라인 요소이면서 내부는 flex 배치.
border-radius: 999px → 알약 모양.
.hero h1 { font-size: clamp(2.2rem, 4vw, 3.6rem); ... }
clamp(최소값, 선호값, 최대값) → 반응형 글자 크기. 화면 너비에 따라 2.2rem ~ 3.6rem 사이에서 자동 조절.
4vw → 뷰포트(화면) 너비의 4%.
.hero p
- 히어로 영역의 설명 문단. 흐린 색. 최대 너비 520px (너무 길어지지 않도록).
.hero-actions
- 버튼들을 가로로 배치.
flex-wrap: wrap → 공간이 부족하면 다음 줄로 넘김.
.btn { ... }
- 모든 버튼의 공통 스타일.
transition: transform 0.2s ease, box-shadow 0.2s ease → 변형(이동)과 그림자가 바뀔 때 0.2초 부드럽게.
.btn-primary { ... }
- 주요 버튼.
linear-gradient(135deg, ...) → 135도 각도의 직선 그라데이션 배경.
box-shadow → 아래에 보라색 그림자.
.btn-secondary { ... }
.btn:hover { transform: translateY(-2px); }
- 마우스를 올리면 위로 2px 살짝 올라가는 효과.
.btn-lotto / .btn-lotto:hover
.lotto-result { ... }
- 로또 결과 표시 영역.
border: 1px dashed var(--border) → 1px 두께, 점선(dashed) 테두리.
color-mix(in srgb, var(--bg-soft) 80%, transparent) → --bg-soft 색에 투명도를 섞은 배경색.
.lotto-ball { ... }
- 로또 공 하나하나의 스타일.
width: 34px; height: 34px; border-radius: 999px → 34×34 원형.
.hero-card { ... }
- 오른쪽 카드. 반투명 배경 + 테두리 + 큰 둥근 모서리(20px) + 그림자.
.hero-card ul { list-style: none; padding: 0; }
list-style: none → 목록 기호(•) 제거.
padding: 0 → 기본 들여쓰기 제거.
section { padding: 48px 0; }
.section-title / .section-desc
- 섹션 제목: 글자 크기 1.8rem.
- 섹션 설명: 흐린 색, 최대 너비 720px.
.grid
- 카드들을 격자로 배치. 최소 230px, 화면 크기에 따라 자동 열 수 조절.
.card
- 각 카드 스타일. 배경색, 실선 테두리, 둥근 모서리, 안쪽 여백.
.stats { ... }
- 통계(숫자) 영역. 격자 배치 + 배경 + 테두리 + 둥근 모서리.
.stat h3 / .stat span
.cta { ... }
- CTA(Call To Action, 행동 유도) 영역.
display: flex; flex-direction: column → 세로 방향으로 쌓기.
align-items: flex-start → 왼쪽 정렬.
footer
- 하단 푸터. 위 40px, 아래 60px 여백. 흐린 색, 작은 글자.
@media (max-width: 720px) { ... } — 반응형 디자인
@media → 미디어 쿼리. "이 조건일 때만 이 스타일을 적용해라".
max-width: 720px → 화면 너비가 720px 이하일 때 (주로 모바일/태블릿).
.nav-links { display: none; } → 네비게이션 링크를 숨김 (모바일에서는 공간 부족).
.hero { padding-top: 48px; } → 히어로 영역 위 여백 축소.
2. <body> — 눈에 보이는 모든 것
<body> 안의 내용이 실제 화면에 표시된다.
2-1. <header> — 상단 헤더 (네비게이션 바)
<header class="container">
<header> → 페이지 상단 영역을 의미하는 시맨틱(의미론적) 태그.
class="container" → CSS에서 .container 스타일이 적용됨 (최대 너비 1120px, 가운데 정렬).
<nav class="nav">
<nav> → "이 안은 네비게이션(길찾기) 영역이다"라는 의미의 시맨틱 태그.
class="nav" → .nav CSS 스타일 적용 (flexbox로 가로 배치).
<div class="logo">songdaegeun</div>
<div> → 특별한 의미 없이 영역을 묶는 범용 태그.
class="logo" → 로고 스타일(굵은 글씨) 적용.
<div class="nav-links">
<a href="#why">특징</a>
<a> → 앵커(anchor) 태그. 클릭하면 다른 곳으로 이동하는 링크.
href="#why" → 같은 페이지 안에서 id="why"인 요소로 스크롤 이동.
# 뒤의 이름을 해시(hash)라 하며, 페이지 내 특정 위치를 가리킨다.
- 나머지 링크도 동일 원리:
#tracks, #community, #start.
<a href="memo.html" style="color: var(--accent)">코드 해부</a>
href="memo.html" → 같은 폴더에 있는 memo.html 파일로 이동하는 링크. #이 아니라 파일명이므로 새 페이지로 이동한다.
style="color: var(--accent)" → 인라인 스타일. HTML 태그에 직접 CSS를 작성하는 방법. 여기서는 글자색을 포인트 색상(청록색)으로 지정하여 일반 링크와 시각적으로 구분한다.
<a href="memo-raw.html" style="color: var(--accent)">코드해부(raw)</a>
href="memo-raw.html" → memo-raw.html 파일로 이동. 이 페이지는 memo.md 파일의 마크다운 원문을 그대로 보여준다.
style 속성은 위와 동일하게 포인트 색상을 적용.
<button class="theme-toggle" id="themeToggle" type="button">화이트 모드</button>
<button> → 클릭 가능한 버튼.
class="theme-toggle" → 알약 모양 버튼 스타일.
id="themeToggle" → 이 요소의 고유 식별자. JavaScript에서 이 버튼을 찾을 때 사용.
type="button" → 폼 제출 없이 단순 클릭 버튼임을 명시.
- 텍스트 "화이트 모드"는 JavaScript로 동적 변경됨.
2-2. <main> — 본문 콘텐츠 영역
<main class="container">
<main> → "이 안이 페이지의 핵심 내용이다"라는 시맨틱 태그.
- 한 페이지에 하나만 사용하는 것이 원칙.
2-2-1. 히어로 섹션 (<section class="hero">)
<section> → 콘텐츠를 주제별로 묶는 시맨틱 태그.
class="hero" → 히어로(메인 시각) 영역 스타일.
<div class="badge">
- 작은 라벨(뱃지). 알약 모양 + 보라색 배경.
<h1>초보자를 위한<br />가장 친절한 코딩 놀이터</h1>
<h1> → 제목 태그 레벨 1. 페이지에서 가장 중요한 제목. (<h1> ~ <h6> 숫자가 클수록 하위 제목)
<br /> → 줄 바꿈 태그. 텍스트를 강제로 다음 줄로 보낸다.
<p>
<p> → 문단(paragraph) 태그. 하나의 문단을 감싼다.
<div class="hero-actions">
<a class="btn btn-primary" href="#start">무료로 시작하기</a>
- 링크인데 버튼 모양(
.btn .btn-primary)으로 보이게 CSS를 입힌 것.
class에 공백으로 여러 클래스를 동시에 부여할 수 있다 (btn + btn-primary).
href="#start" → 페이지 내 id="start" 영역으로 이동.
히어로 카드 (<div class="hero-card">)
<h3> → 제목 태그 레벨 3.
<ul> → 비순서 목록(Unordered List). 순서가 없는 항목 나열.
<li> → 목록 항목(List Item). <ul> 안의 각 줄.
<span> → 텍스트의 일부분만 감싸는 인라인 태그. 여기서는 "●" 기호에 청록색(--accent)을 입히기 위해 사용.
2-2-2. 특징 섹션 (<section id="why">)
id="why" → 이 섹션의 고유 이름. 상단 메뉴의 <a href="#why">를 클릭하면 여기로 스크롤된다.
<h2> → 제목 태그 레벨 2.
<div class="grid"> → 카드들을 격자(grid)로 배치하는 컨테이너.
카드 구조 (4개 반복)
<div class="card">
<span>🧭</span>
<h4>길잡이형 로드맵</h4>
<p>초보자를 위한 단계별 커리큘럼과 체크리스트를 제공합니다.</p>
</div>
<h4> → 제목 태그 레벨 4.
<span> → 이모지를 감싸서 스타일링 가능하게.
2-2-3. 학습 로드맵 섹션 (<section id="tracks">)
- 구조는 특징 섹션과 동일. 4개의 카드가 grid로 배치됨.
id="tracks" → 메뉴의 "학습 로드맵" 링크가 여기로 연결됨.
2-2-4. 커뮤니티 섹션 (<section id="community">)
<div class="stat">
<h3>1,200+</h3>
<span>활동 중인 러너</span>
</div>
<h3>으로 큰 숫자를, <span>으로 설명 텍스트를 표시.
2-2-5. 시작하기 섹션 (<section id="start">)
<div class="cta"> — 행동 유도 영역
<a class="btn btn-primary" href="mailto:hello@songdaegeun.com">문의하기</a>
href="mailto:..." → 클릭하면 이메일 앱이 열리면서 해당 주소로 메일 작성 화면이 뜬다.
<button class="btn btn-secondary btn-lotto" id="lottoBtn" type="button">로또번호추천</button>
- 로또 번호 생성 버튼. JavaScript가
id="lottoBtn"으로 이 버튼을 찾는다.
<div class="lotto-result" id="lottoResult" aria-live="polite" hidden></div>
- 로또 결과가 표시될 빈 영역.
aria-live="polite" → 스크린 리더(접근성)에게 "이 영역의 내용이 바뀌면 읽어줘, 단 현재 읽기를 끝낸 후에"라고 알린다.
hidden → 처음에는 숨겨져 있다. JavaScript가 결과를 넣을 때 이 속성을 제거한다.
2-3. <footer> — 하단 푸터
<footer class="container">
<div>© 2026 songdaegeun. 함께 배우는 코딩 커뮤니티.</div>
</footer>
<footer> → 페이지 하단 정보(저작권, 연락처 등)를 담는 시맨틱 태그.
© → 저작권 기호(©)를 나타내는 HTML 엔티티. 특수문자를 코드로 표현하는 방법.
2-4. <script> ... </script> — JavaScript 영역
<script> 태그 안에 JavaScript 코드를 작성한다. <body> 닫는 태그 바로 위에 배치하여, HTML이 먼저 로드된 후 실행되게 한다.
JavaScript 기초 문법 빠른 정리
| 문법 | 의미 |
const 이름 = 값 | 상수 선언 (한 번 할당하면 재할당 불가) |
let 이름 = 값 | 변수 선언 (재할당 가능) |
() => { ... } | 화살표 함수. 이름 없는 함수를 짧게 쓰는 방법 |
document.getElementById("id") | HTML에서 해당 id를 가진 요소를 찾아서 가져옴 |
element.addEventListener("이벤트", 함수) | 해당 요소에서 "이벤트"가 발생하면 함수를 실행 |
if (조건) { ... } | 조건이 참이면 실행 |
=== | 두 값이 같은지 비교 (타입까지 일치해야 true) |
|| | 또는(OR). 왼쪽이 falsy이면 오른쪽 값 사용 |
&& | 그리고(AND). 둘 다 참이어야 true |
? : | 삼항 연산자. 조건 ? 참일때값 : 거짓일때값 |
String(값) | 값을 문자열로 변환 |
`텍스트 ${변수}` | 템플릿 리터럴. 문자열 안에 변수를 삽입하는 방법 |
전체를 즉시 실행 함수로 감쌈
(() => {
...
})();
(() => { ... })() → IIFE (Immediately Invoked Function Expression).
- 코드를 즉시 실행하되, 내부 변수가 외부로 새어나가지 않도록 감싸는 패턴.
- 다른 스크립트와 변수명이 충돌하는 것을 방지한다.
테마 토글 기능
const root = document.documentElement;
document.documentElement → <html> 태그를 가리킨다.
const themeToggle = document.getElementById("themeToggle");
id="themeToggle"인 요소(화이트 모드 버튼)를 찾아서 변수에 저장.
const storedTheme = localStorage.getItem("theme");
localStorage → 브라우저에 데이터를 영구 저장하는 저장소.
getItem("theme") → "theme"이라는 키로 저장된 값을 꺼냄. 없으면 null.
const prefersLight = window.matchMedia &&
window.matchMedia("(prefers-color-scheme: light)").matches;
- 사용자의 운영체제(OS)가 라이트 모드로 설정되어 있는지 확인.
const initialTheme = storedTheme || (prefersLight ? "light" : "dark");
- 저장된 테마가 있으면 그것을 쓰고, 없으면 OS 설정에 따라 결정.
root.dataset.theme = initialTheme;
dataset.theme → <html> 태그에 data-theme="값" 속성을 설정.
- 이것이 바뀌면 CSS의
html[data-theme="light"]가 반응하여 색상이 바뀜.
themeToggle.textContent = initialTheme === "light" ? "다크 모드" : "화이트 모드";
- 버튼의 텍스트를 현재 테마에 맞게 설정.
- 라이트 모드면 "다크 모드"로 전환 가능하다는 뜻으로 텍스트 표시.
themeToggle.setAttribute("aria-pressed", String(initialTheme === "light"));
- 접근성 속성. 스크린 리더에게 버튼이 눌린 상태인지 알려줌.
themeToggle.addEventListener("click", () => { ... });
const nextTheme = root.dataset.theme === "light" ? "dark" : "light";
root.dataset.theme = nextTheme;
localStorage.setItem("theme", nextTheme);
- 현재 테마의 반대로 전환하고, localStorage에 저장하여 새로고침해도 유지.
로또 번호 추천 기능
const btn = document.getElementById("lottoBtn");
const result = document.getElementById("lottoResult");
- 로또 버튼과 결과 영역을 찾아서 변수에 저장.
if (!btn || !result) return;
- 버튼이나 결과 영역을 찾지 못하면 함수를 즉시 종료 (에러 방지).
! → 부정 연산자. !btn은 "btn이 없으면(null/undefined이면) true".
return → 함수 실행을 중단하고 빠져나감.
pickLottoNumbers 함수
const pickLottoNumbers = () => {
const set = new Set();
while (set.size < 6) {
set.add(Math.floor(Math.random() * 45) + 1);
}
return Array.from(set).sort((a, b) => a - b);
};
| 코드 | 설명 |
new Set() | Set = 중복을 허용하지 않는 집합 자료구조 |
while (set.size < 6) | Set의 크기가 6이 될 때까지 반복 |
Math.random() | 0 이상 1 미만의 랜덤 소수 생성 (예: 0.7283...) |
Math.random() * 45 | 0 ~ 44.999... 사이의 수 |
Math.floor(...) | 소수점 아래 버림 → 0 ~ 44 |
+ 1 | 1 ~ 45 범위로 조정 |
set.add(값) | Set에 추가. 이미 있으면 무시됨 (중복 방지) |
Array.from(set) | Set을 배열로 변환 |
.sort((a, b) => a - b) | 오름차순 정렬 |
결과: 1~45 중 중복 없는 6개 숫자를 오름차순으로 반환.
render 함수 — 결과를 화면에 그리기
const render = (tickets) => {
result.hidden = false;
result.innerHTML = "";
...
};
| 코드 | 설명 |
result.hidden = false | hidden 속성 제거 → 결과 영역을 보이게 함 |
result.innerHTML = "" | 결과 영역의 기존 내용을 비움 |
const title = document.createElement("div");
title.innerHTML = `<strong>추천 번호</strong> (5세트)`;
result.appendChild(title);
| 코드 | 설명 |
document.createElement("div") | 새로운 <div> 요소를 메모리에 생성 (아직 화면에 안 보임) |
title.innerHTML = ... | 그 요소의 HTML 내용을 설정 |
<strong> | 텍스트를 굵게 표시하는 태그 |
result.appendChild(title) | 결과 영역의 자식으로 추가 → 이제 화면에 보임 |
tickets.forEach((nums, idx) => { ... });
forEach → 배열의 각 항목을 순서대로 하나씩 꺼내서 함수 실행.
nums → 각 세트의 6개 번호 배열, idx → 인덱스(0, 1, 2, 3, 4).
const setWrap = document.createElement("div");
setWrap.className = "lotto-set";
- 새
<div> 생성 후 class="lotto-set" 부여.
className → 요소의 class 속성을 설정하는 JavaScript 속성.
setTitle.textContent = `${idx + 1}세트: ${nums.join(", ")}`;
textContent → 요소의 텍스트 내용을 설정 (HTML 태그 해석 없이 순수 텍스트).
nums.join(", ") → 배열을 ", "로 연결한 문자열로 변환 (예: "3, 12, 23, 31, 38, 42").
nums.forEach((n) => {
const ball = document.createElement("span");
ball.className = "lotto-ball";
ball.textContent = String(n);
balls.appendChild(ball);
});
- 6개 번호 각각에 대해 동그란 공(
lotto-ball) 요소를 생성하여 추가.
버튼 클릭 이벤트 연결
btn.addEventListener("click", () => {
const tickets = Array.from({ length: 5 }, () => pickLottoNumbers());
render(tickets);
});
| 코드 | 설명 |
btn.addEventListener("click", ...) | 로또 버튼 클릭 시 실행 |
Array.from({ length: 5 }, 함수) | 길이 5짜리 배열을 생성하면서, 각 요소를 함수의 반환값으로 채움 |
() => pickLottoNumbers() | 각 자리마다 6개 번호 세트 생성 |
render(tickets) | 5세트의 번호를 화면에 그림 |
| 태그 | 의미 | 이 파일에서의 용도 |
<!doctype html> | HTML5 문서 선언 | 문서 맨 위 |
<html> | 문서 전체를 감쌈 | 최상위 컨테이너 |
<head> | 메타 정보 영역 | 설정, 스타일 |
<meta> | 부가 정보 (인코딩, 뷰포트 등) | 문자셋, 반응형, SEO |
<title> | 탭 제목 | 브라우저 탭 |
<style> | CSS 작성 영역 | 모든 스타일 정의 |
<body> | 화면에 보이는 내용 | 본문 전체 |
<header> | 상단 영역 | 네비게이션 바 |
<nav> | 네비게이션 영역 | 메뉴 링크 |
<main> | 핵심 콘텐츠 영역 | 본문 |
<section> | 주제별 콘텐츠 묶음 | 각 섹션 |
<footer> | 하단 영역 | 저작권 |
<div> | 범용 블록 컨테이너 | 레이아웃 묶음 |
<span> | 범용 인라인 컨테이너 | 텍스트 일부 꾸미기 |
<h1>~<h4> | 제목 (레벨 1~4) | 섹션 제목 |
<p> | 문단 | 설명 텍스트 |
<a> | 링크 | 메뉴, 버튼 |
<button> | 버튼 | 테마 전환, 로또 |
<ul> | 비순서 목록 | 히어로 카드 목록 |
<li> | 목록 항목 | 각 항목 |
<br> | 줄 바꿈 | 제목 내 줄 바꿈 |
<strong> | 강조(굵게) | 로또 결과 제목 |
<script> | JavaScript 작성 영역 | 테마 전환, 로또 기능 |
한눈에 보는 HTML 속성 사전
| 속성 | 설명 | 예시 |
lang | 문서/요소의 언어 | lang="ko" |
charset | 문자 인코딩 | charset="utf-8" |
name | 메타 태그의 이름 | name="viewport" |
content | 메타 태그의 값 | content="width=device-width" |
class | CSS 클래스 (여러 개 가능) | class="btn btn-primary" |
id | 고유 식별자 (페이지 내 유일) | id="themeToggle" |
href | 링크 대상 URL | href="#start", href="mailto:..." |
type | 요소의 타입 | type="button" |
style | 인라인 CSS (태그에 직접 스타일 작성) | style="color: var(--accent)" |
hidden | 요소를 숨김 | hidden |
aria-live | 접근성: 변경 시 읽기 방식 | aria-live="polite" |
aria-pressed | 접근성: 토글 버튼 상태 | aria-pressed="true" |
data-theme | 사용자 정의 데이터 속성 | data-theme="light" |