๐Ÿ“Œ 1๏ธโƒฃ ์‹œ๋งจํ‹ฑ ํƒœ๊ทธ ์‹ฌํ™” ํ™•์žฅ

ํƒœ๊ทธ ์„ค๋ช… ๋น„์œ  ๐ŸŒŸ ์‹ค๋ฌด ํฌ์ธํŠธ ๐Ÿš€
<header> ๋ฌธ์„œ or ์„น์…˜์˜ ๋จธ๋ฆฟ๋ง (๋กœ๊ณ , ๋‚ด๋น„ ํฌํ•จ ๊ฐ€๋Šฅ) ๐Ÿ  ์ง‘ ํ˜„๊ด€, ๊ฐ„ํŒ ์ „์ฒด๋ฟ ์•„๋‹ˆ๋ผ ๊ฐ <section> ์•ˆ์—๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
<footer> ๊ผฌ๋ฆฌ๋ง (์ €์ž‘๊ถŒ, ์—ฐ๋ฝ์ฒ˜ ๋“ฑ) ๐Ÿก ์ง‘ ๋’ท๋งˆ๋‹น, ๋ช…ํ•จ ์‚ฌ์ดํŠธ ์ „์ฒด & ๊ฐœ๋ณ„ ์„น์…˜ ๋‚ด์—์„œ๋„ ์‚ฌ์šฉ
<nav> ๋‚ด๋น„๊ฒŒ์ด์…˜ ๋งํฌ ๋ชจ์Œ ๐Ÿš— ๊ธธ ์•ˆ๋‚ด ํ‘œ์ง€ํŒ ARIA role=โ€navigationโ€ ๋ณ‘ํ–‰ ์ถ”์ฒœ
<section> ์ฃผ์ œ๋ณ„ ๊ตฌํš ๐Ÿ“š ์ฑ•ํ„ฐ ๊ตฌ๋ถ„ ๋ฐ˜๋“œ์‹œ ์ œ๋ชฉ(h1~h6) ํฌํ•จ!
<article> ๋…๋ฆฝ ์ฝ˜ํ…์ธ  ๐Ÿ“ฐ ์‹ ๋ฌธ๊ธฐ์‚ฌ RSS๋กœ ํผ๊ฐ€๋„ ์˜๋ฏธ ์œ ์ง€
<aside> ๋ณด์กฐ ์ •๋ณด (๊ด‘๊ณ , ๋งํฌ) ๐Ÿ“Ž ์ฐธ๊ณ ์ž๋ฃŒ, ์‚ฌ์ด๋“œ๋ฐ” ๊ฒ€์ƒ‰์—”์ง„์€ ๋ณธ๋ฌธ๊ณผ ๊ตฌ๋ถ„

โœ… ์‹ฌํ™” ์˜ˆ์ œ + ์ฃผ์„

<body>
  <header>
    <h1>๐ŸŒ My Website</h1>
    <nav> <!-- ๋‚ด๋น„๊ฒŒ์ด์…˜ -->
      <a href="#home">Home</a>
      <a href="#about">About</a>
    </nav>
  </header>

  <main>
    <section>
      <h2>๐Ÿ“š About Us</h2>
      <article>
        <h3>๐Ÿ“ฐ Company Story</h3>
        <p>๋…๋ฆฝ์  ๊ธฐ์‚ฌ ๋‚ด์šฉ...</p>
      </article>
      <aside>
        ๐Ÿ“Ž ๊ด€๋ จ ๋งํฌ, ๊ด‘๊ณ  ๋ฐฐ๋„ˆ
      </aside>
    </section>
  </main>

  <footer>
    <p>ยฉ 2025 My Company</p>
  </footer>
</body>

โœ… ๋ฉด์ ‘ ํฌ์ธํŠธ:


๐Ÿ“ฆ 2๏ธโƒฃ Web Storage ์‹ฌํ™”

์ €์žฅ์†Œ ํŠน์ง• ๋น„์œ  ๐ŸŒŸ ์‹ค๋ฌด ํฌ์ธํŠธ ๐Ÿš€
localStorage ๋ธŒ๋ผ์šฐ์ €์— ์˜๊ตฌ ์ €์žฅ (ํƒญ/๋ธŒ๋ผ์šฐ์ € ์ข…๋ฃŒํ•ด๋„ ์œ ์ง€) ๐Ÿ“ฆ ์žฅ๊ธฐ ๋ณด๊ด€ ์ฐฝ๊ณ  ์ตœ๋Œ€ 5~10MB, ๋ฏผ๊ฐ ์ •๋ณด ์ €์žฅ ๊ธˆ์ง€
sessionStorage ํƒญ ๋‹ซํžˆ๋ฉด ์‚ญ์ œ๋จ ๐Ÿ›’ ์ž„์‹œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋กœ๊ทธ์ธ ์„ธ์…˜, ์ž„์‹œ ๋ฐ์ดํ„ฐ
์ฟ ํ‚ค ์„œ๋ฒ„์™€ ๋งค ์š”์ฒญ ํ•จ๊ป˜ ์ „์†ก (4KB ์ œํ•œ) ๐Ÿช ํ•ญ์ƒ ๋“ค๊ณ  ๋‹ค๋‹ˆ๋Š” ๋ฉ”๋ชจ์žฅ ์„ธ์…˜ ๊ด€๋ฆฌ, ์„œ๋ฒ„ ์ธ์ฆ

โœ… ์‹ค์ „ ์˜ˆ์ œ + ์ฃผ์„

// localStorage - ์˜๊ตฌ ๋ฐ์ดํ„ฐ ์ €์žฅ
localStorage.setItem('theme', 'dark'); // ์ €์žฅ
console.log(localStorage.getItem('theme')); // ์ฝ๊ธฐ

// sessionStorage - ํƒญ ๋‹ซ์œผ๋ฉด ์‚ญ์ œ
sessionStorage.setItem('user', 'ํ™๊ธธ๋™');

// ์ฟ ํ‚ค ์˜ˆ์‹œ
document.cookie = "username=hong; path=/; max-age=86400"; // ํ•˜๋ฃจ ๋™์•ˆ ์œ ์ง€

โœ… ๋ณด์•ˆ ํฌ์ธํŠธ:


๐ŸŽต 3๏ธโƒฃ ์˜ค๋””์˜ค & ๋น„๋””์˜ค ์‹ฌํ™”

ํƒœ๊ทธ ์„ค๋ช… ๋น„์œ  ๐ŸŒŸ ์‹ค๋ฌด ํฌ์ธํŠธ ๐Ÿš€
<audio>, <video> ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ์‚ฝ์ž… ๐ŸŽต, ๐ŸŽฅ ๋ฏธ๋””์–ด ํ”Œ๋ ˆ์ด์–ด controls ํ•„์ˆ˜, autoplay+muted ์ฃผ์˜
controls ์žฌ์ƒ, ์ •์ง€, ๋ณผ๋ฅจ ๋“ฑ ์กฐ์ž‘ ๋ฒ„ํŠผ ํ‘œ์‹œ ๐ŸŽฎ ๋ฆฌ๋ชจ์ปจ UX ํ–ฅ์ƒ
autoplay, loop ์ž๋™ ์žฌ์ƒ, ๋ฐ˜๋ณต ์žฌ์ƒ ๐Ÿ”„ ์ž๋™ ํ”Œ๋ ˆ์ด SEO/์ ‘๊ทผ์„ฑ ๊ณ ๋ คํ•ด ์‚ฌ์šฉ

โœ… ์‹ฌํ™” ์˜ˆ์ œ + ์ฃผ์„

<video width="320" controls autoplay muted loop poster="thumbnail.jpg">
  <source src="video.mp4" type="video/mp4">
  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋น„๋””์˜ค๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•„์š”!
</video>

๐Ÿ“Œ ํฌ์ธํŠธ:


๐Ÿ“ 4๏ธโƒฃ HTML5 ํผ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ ์‹ฌํ™”

์†์„ฑ ์„ค๋ช… ๋น„์œ  ๐ŸŒŸ ์‹ค๋ฌด ํฌ์ธํŠธ ๐Ÿš€
input[type="email"] ์ด๋ฉ”์ผ ํ˜•์‹ ์ž๋™ ๊ฒ€์ฆ ๐Ÿ“ง ์ด๋ฉ”์ผ ํ•„ํ„ฐ pattern ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€ ๊ฒ€์ฆ ๊ฐ€๋Šฅ
input[type="date"] ๋‹ฌ๋ ฅ ํŒ์—… ๐Ÿ“… ๋‚ ์งœ ์„ ํƒ๊ธฐ ๋ชจ๋ฐ”์ผ์—์„œ UX ๊ฐœ์„ 
input[type="range"] ์Šฌ๋ผ์ด๋”๋กœ ์ˆซ์ž ์„ ํƒ ๐ŸŽš๏ธ ๋ณผ๋ฅจ ์กฐ์ ˆ ์‹ค์‹œ๊ฐ„ ์‹œ๊ฐ ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต

โœ… ์˜ˆ์ œ + ์ฃผ์„

<form>
  <input type="email" placeholder="์ด๋ฉ”์ผ ์ž…๋ ฅ" required>
  <input type="date">
  <input type="range" min="1" max="100" value="50">
  <button>์ œ์ถœ</button>
</form>

๐Ÿ“Œ ์‹ค๋ฌด ํŒ:


โœ๏ธ 5๏ธโƒฃ ์›น ํฐํŠธ ์‹ฌํ™”

๊ฐœ๋… ์„ค๋ช… ๋น„์œ  ๐ŸŒŸ ์‹ค๋ฌด ํฌ์ธํŠธ ๐Ÿš€
@font-face ์™ธ๋ถ€ ํฐํŠธ ๋ถˆ๋Ÿฌ์™€ ์ปค์Šคํ…€ โœ๏ธ ๊ธ€์”จ์ฒด ๊ฐ€์ ธ์˜ค๊ธฐ woff2 ํฌ๋งท ๊ถŒ์žฅ, ์ตœ์†Œ ํฌ๊ธฐ ์œ ์ง€
Google Fonts ๋ฌด๋ฃŒ ํฐํŠธ CDN ๐ŸŒŽ ํฐํŠธ ๋„์„œ๊ด€ font-display: swap ์ ์šฉ ํ•„์ˆ˜

โœ… ์˜ˆ์ œ + ์ฃผ์„

@font-face {
  font-family: 'CustomFont';
  src: url('font.woff2') format('woff2');
  font-display: swap; /* ํฐํŠธ ๋กœ๋”ฉ ์ „ ๊ธฐ๋ณธ ํฐํŠธ ๋จผ์ € ๋ณด์—ฌ์คŒ */
}

body {
  font-family: 'CustomFont', sans-serif;
}

๐Ÿ“ 6๏ธโƒฃ SVG & Canvas ์‹ฌํ™”

๊ฐœ๋… ํŠน์ง• ๋น„์œ  ๐ŸŒŸ ์‹ค๋ฌด ํฌ์ธํŠธ ๐Ÿš€
<svg> ๋ฒกํ„ฐ ๊ทธ๋ž˜ํ”ฝ, ํ™•๋Œ€ํ•ด๋„ ๊นจ์ง X ๐Ÿ“ ๋„๋ฉด ๊ทธ๋ฆฌ๊ธฐ DOM ์ ‘๊ทผ ๊ฐ€๋Šฅ, ๊ฐ„๋‹จํ•œ UI ์•„์ด์ฝ˜
<canvas> ๋น„ํŠธ๋งต ๊ทธ๋ž˜ํ”ฝ, ๋น ๋ฅธ ์‹ค์‹œ๊ฐ„ ๋ Œ๋”๋ง ๐ŸŽฎ ๊ทธ๋ฆผํŒ, ๊ฒŒ์ž„ ๊ณ ์„ฑ๋Šฅ ๊ฒŒ์ž„, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”

โœ… ์‹ฌํ™” ์˜ˆ์ œ + ์ฃผ์„

<!-- ๐Ÿ“ SVG ์˜ˆ์ œ: ๋ฒกํ„ฐ ๊ทธ๋ž˜ํ”ฝ (ํ™•๋Œ€ํ•ด๋„ ๊นจ์ง€์ง€ ์•Š์Œ) -->
<svg width="100" height="100"> <!-- SVG ์บ”๋ฒ„์Šค ํฌ๊ธฐ: 100x100 -->
  <!-- ์›(circle) ์š”์†Œ
       cx, cy โ†’ ์›์˜ ์ค‘์‹ฌ ์ขŒํ‘œ
       r โ†’ ๋ฐ˜์ง€๋ฆ„
       stroke โ†’ ํ…Œ๋‘๋ฆฌ ์ƒ‰
       fill โ†’ ๋‚ด๋ถ€ ์ƒ‰ -->
  <circle cx="50" cy="50" r="40" stroke="blue" fill="lightblue" />
</svg>

<!-- ๐ŸŽฎ Canvas ์˜ˆ์ œ: ๋น„ํŠธ๋งต ๊ทธ๋ž˜ํ”ฝ (ํ”ฝ์…€ ๊ธฐ๋ฐ˜, ์‹ค์‹œ๊ฐ„ ๋ Œ๋”๋ง์— ๊ฐ•์ ) -->
<canvas id="myCanvas" width="200" height="100"></canvas>
<script>
  // 1๏ธโƒฃ canvas ์š”์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ
  const ctx = document.getElementById('myCanvas').getContext('2d');

  // 2๏ธโƒฃ ์ฑ„์šฐ๊ธฐ ์ƒ‰์ƒ ์„ค์ • (fillStyle โ†’ ์ฑ„์šธ ์ƒ‰์ƒ)
  ctx.fillStyle = 'green';

  // 3๏ธโƒฃ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ: (x์ขŒํ‘œ, y์ขŒํ‘œ, ๋„ˆ๋น„, ๋†’์ด)
  ctx.fillRect(10, 10, 150, 80); // ์ขŒ์ƒ๋‹จ (10,10)๋ถ€ํ„ฐ 150x80 ํฌ๊ธฐ์˜ ๋…น์ƒ‰ ์‚ฌ๊ฐํ˜•
</script>

๐Ÿ“Œ ํฌ์ธํŠธ:


๐Ÿš€ ๊ธฐ์ˆ  ๋ฉด์ ‘ ์˜ˆ์ƒ ์งˆ๋ฌธ ์‹ฌํ™”

์งˆ๋ฌธ ์‹ฌํ™” ํฌ์ธํŠธ
localStorage, sessionStorage, ์ฟ ํ‚ค ์ฐจ์ด? ์ €์žฅ ๊ธฐ๊ฐ„, ํฌ๊ธฐ ์ œํ•œ, ์„œ๋ฒ„ ์ „์†ก ์—ฌ๋ถ€
์‹œ๋งจํ‹ฑ ํƒœ๊ทธ SEO ์˜ํ–ฅ? ๊ฒ€์ƒ‰์—”์ง„ โ†’ ๊ตฌ์กฐ ๋ช…ํ™•, ์Šคํฌ๋ฆฐ๋ฆฌ๋” ์ ‘๊ทผ์„ฑ โ†‘
Canvas vs SVG ์„ ํƒ ๊ธฐ์ค€? SVG: UI, ํ™•๋Œ€ ๊ฐ€๋Šฅ / Canvas: ์‹ค์‹œ๊ฐ„, ๊ณ ์„ฑ๋Šฅ
HTML5 form ๊ฒ€์ฆ ์žฅ์ ? ๊ธฐ๋ณธ ๊ฒ€์ฆ ์ œ๊ณต โ†’ JS ๋ถ€๋‹ด โ†“, ํ•˜์ง€๋งŒ JS ๋ณ‘ํ–‰ ํ•„์ˆ˜
์›นํฐํŠธ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•? woff2, font-display: swap, preload ์‚ฌ์šฉ ๊ถŒ์žฅ

๐Ÿ’ผ ์‹ค๋ฌด Best Practice ์ •๋ฆฌ

ํฌ์ธํŠธ ์ด์œ 
์‹œ๋งจํ‹ฑ ํƒœ๊ทธ ์ ๊ทน ์‚ฌ์šฉ SEO & ์ ‘๊ทผ์„ฑ ๊ฐ•ํ™”
Web Storage โ†’ ๋น„๋ฏผ๊ฐ ๋ฐ์ดํ„ฐ๋งŒ ๋ณด์•ˆ (XSS) ๊ณ ๋ ค
๋น„๋””์˜ค โ†’ controls ํ•„์ˆ˜, autoplay ์ฃผ์˜ UX/์ ‘๊ทผ์„ฑ โ†‘
์›นํฐํŠธ โ†’ swap + preload ๋ Œ๋”๋ง ์ตœ์ ํ™”
SVG vs Canvas ์ƒํ™ฉ๋ณ„ ์„ ํƒ ์„ฑ๋Šฅ, UI ๋ชฉ์ ์— ๋งž๊ฒŒ ์„ ํƒ