| ์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
- ์น๊ฐ๋ฐ
 - Golden
 - ๋ฐ๋ง์ผํ
 - ์นUI
 - ์ ๊ทผ์ฑ
 - ๋คํฌ๋ชจ๋ํ ๊ธ
 - ๋ทํ๋ฆญ์คost
 - ui์ปดํฌ๋ํธ
 - ๋ฐ๋๋ผ์คํฌ๋ฆฝํธ
 - ๊ฐ์์์ด๋
 - JavaScript
 - kpopdemonhunters
 - ๋ฐ๋๋ผjs
 - ๊ณจ๋
 - ์คํฌ๋กค์ ๋๋ฉ์ด์ 
 - ์ฌ์๋ณด์ด์ฆ
 - ๋น๋ณด๋์ฐจํธ
 - ๋คํฌ๋ชจ๋
 - ์น์ ๊ทผ์ฑ
 - ์๋ฐ์คํฌ๋ฆฝํธ
 - ํํธ๋ฆญ์ค
 - ํ๋ก ํธ์๋
 - js์คํฌ๋กค์ด๋ฒคํธ
 - ์๋ฐ์คํฌ๋ฆฝํธui
 - ์ผ์ดํ๋ฐ๋ชฌํํฐ์ค
 - ๋ทํ๋ฆญ์ค์ ๋๋ฉ์ด์ 
 - ์น๋์์ธ
 - UX๋์์ธ
 - UIUX
 - ์ผ๋ฐํ
 
- Today
 
- Total
 
UI Code Lab
์งํ ์ํฉ์ ์๊ฐํํ๋ ํ์๋ผ์ธ UI ๋ง๋ค๊ธฐ (JavaScript ๊ธฐ๋ฐ) ๋ณธ๋ฌธ
์งํ ์ํฉ์ ์๊ฐํํ๋ ํ์๋ผ์ธ UI ๋ง๋ค๊ธฐ (JavaScript ๊ธฐ๋ฐ)
๐ฏ๊ฟ์์ด๐ 2025. 6. 23. 09:29
์น์์ ์ฌ์ฉ์์ ์์น์ ์งํ ์ํ๋ฅผ ๋ช ํํ๊ฒ ๋ณด์ฌ์ฃผ๋ UI๋ ์ฌ์ฉ์ ๊ฒฝํ์ ํฐ ์ํฅ์ ์ค๋๋ค. ํนํ CAD์ ๊ฐ์ ๊ธฐ์ ์๋ฃ๋ฅผ ์ ๊ณตํ๋ ํ์ด์ง์์๋ “์ง๊ธ ๋ด๊ฐ ์ด๋ค ๋จ๊ณ์ ์๋์ง”๋ฅผ ์ง๊ด์ ์ผ๋ก ์ธ์ํ ์ ์์ด์ผ ํ์ฃ . ์ด๋ฒ ๊ธ์์๋ JavaScript์ CSS๋ง์ผ๋ก ๊ตฌํํ๋ ์งํ ๋จ๊ณ ํ์๋ผ์ธ UI๋ฅผ ์๊ฐํฉ๋๋ค.
๐ก ์ง์  ํ์ฉํ ์์๋ ํ์ฌ CAD ํ์ด์ง์ ํ๋ฆ
| STEP 1: CAD ํ์ผ ์ค๋น >> STEP 2: CAD ํ์ผ ๊ฒํ >> STEP 3: ์น์ธ ๋๊ธฐ >> STEP 4: ๋ค์ด๋ก๋ ๊ฐ๋ฅ | 
STEP 1๊ณผ STEP 2๋ ์ด๋ฏธ์ง๊ฐ ์ด๋ฏธ ๋ฑ๋ก๋ ์๋ฃ ๋จ๊ณ๋ก ๊ฐ์ ์์์ผ๋ก ๊ทธ๋ฃนํํ๊ณ , ์น์ธ ๋๊ธฐ ์ํ์ธ STEP 3๋ ๊ฐ์กฐ ์ ๋๋ฉ์ด์ ์ผ๋ก ํํํด ์ฌ์ฉ์์ ์ฃผ์๋ฅผ ๋ ์ ์๋๋ก ๊ตฌ์ฑํด ๋ดค์ต๋๋ค.
โ ์ฃผ์ ๊ธฐ๋ฅ ์์ฝ
- ์คํ 1, ์คํ 2๋ ๋์ผํ ์์์ผ๋ก ๊ทธ๋ฃนํ (์: ์๋ฃ๋ ๋จ๊ณ)
 - ํ์ฌ ์งํ ์ค์ธ ์คํ ์ ๊ฐ์กฐ ์ ๋๋ฉ์ด์  ์ ์ฉ
 - ๋ง์ฐ์ค ์ค๋ฒ ์ ํดํ์ผ๋ก ์์ธ ์ค๋ช ์ ๊ณต
 - ๋ฐ์ํ ๋์์ธ์ผ๋ก ๋ชจ๋ฐ์ผ ๋์
 
๐งฉ HTML ๊ตฌ์กฐ ์์
<div class="timeline">
  <div class="step completed">STEP 1<br><span>CAD ํ์ผ ์ค๋น</span></div>
  <div class="step completed">STEP 2<br><span>CAD ํ์ผ ๊ฒํ </span></div>
  <div class="step active">STEP 3<br><span>์น์ธ ๋๊ธฐ</span></div>
  <div class="step">STEP 4<br><span>๋ค์ด๋ก๋ ๊ฐ๋ฅ</span></div>
</div>
๐จ CSS ๋์์ธ ํฌ์ธํธ
.timeline {
  display: flex;
  justify-content: space-between;
  margin: 30px 0;
}
.step {
  flex: 1;
  text-align: center;
  padding: 10px;
  border-bottom: 4px solid #ccc;
  position: relative;
}
.step.completed {
  border-color: #4CAF50; /* ์๋ฃ๋ ์คํ
 ์์ */
  color: #4CAF50;
}
.step.active {
  border-color: #FF9800;
  color: #FF9800;
  animation: pulse 1s infinite;
}
@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.6; }
  100% { opacity: 1; }
}
๐ก ํ์ฉ ์์: CAD ๋ฐ์ดํฐ ๋ค์ด๋ก๋ ํ๋ฆ
- STEP 1~2: ์ด๋ฏธ์ง๊ฐ ์ด๋ฏธ ๋ฑ๋ก๋ ์ํ → ๊ฐ์ ์์์ผ๋ก ๊ทธ๋ฃน ์ฒ๋ฆฌ
 - STEP 3: ์น์ธ ๋๊ธฐ ์ํ → ๊ฐ์กฐ ์ ๋๋ฉ์ด์ 
 - STEP 4: ๋ค์ด๋ก๋ ๊ฐ๋ฅ → ํ์ ์ฒ๋ฆฌ
 
์ด๋ฐ ๋ฐฉ์์ผ๋ก ์ค์  3D CAD ๋ฐ์ดํฐ ํ์ด์ง์ ํ๋ฆ์ ์๊ฐํํ๋ฉด, ์ฌ์ฉ์์๊ฒ ํ์ฌ ์์น๋ฅผ ๋ช ํํ ์ ๋ฌํ ์ ์์ด์.
์๋ฐ์คํฌ๋ฆฝํธ๋ก ๊ตฌํํ๋ ์ธํฐ๋ํฐ๋ธ ํ์๋ผ์ธ UI – CAD ํ์ด์ง ํ๋ฆ์ ์ ์ฉํ๊ธฐ
๊ธฐ์กด์๋ ์ ์ ์ธ ํ์๋ผ์ธ UI๋ฅผ HTML๊ณผ CSS๋ง์ผ๋ก ๊ตฌ์ฑํ์ง๋ง, ์ด๋ฒ์๋ ์ฌ์ฉ์์ ์ํธ์์ฉ์ ๋ฐ๋ผ ์งํ ๋จ๊ณ๋ฅผ ์ ์ดํ๊ฑฐ๋ ์ ๋๋ฉ์ด์ ์ ์ ์ดํ ์ ์๋ ๋์  ํ์๋ผ์ธ์ผ๋ก ํ์ฅํด ๋ด ๋๋ค.
โ JavaScript ์ฝ๋ ์์
// ์ด๊ธฐ ์ํ ๊ฐ์ ธ์ค๊ธฐ
let currentStep = parseInt(localStorage.getItem('currentStep')) || 1;
const steps = document.querySelectorAll('.step');
function renderSteps(step) {
  steps.forEach((el, i) => {
    el.classList.remove('completed', 'active');
    if (i < step - 1) el.classList.add('completed'); // ์ด์  ๋จ๊ณ
    else if (i === step - 1) el.classList.add('active'); // ํ์ฌ ๋จ๊ณ
  });
}
renderSteps(currentStep);
// ํด๋ฆญ ์ด๋ฒคํธ๋ก ๋จ๊ณ ์ด๋
steps.forEach((el, i) => {
  el.addEventListener('click', () => {
    currentStep = i + 1;
    localStorage.setItem('currentStep', currentStep);
    renderSteps(currentStep);
  });
});
์ด ์ฝ๋๋ ์ฌ์ฉ์ ํด๋ฆญ์ผ๋ก ์งํ ๋จ๊ณ๋ฅผ ์ ๋ฐ์ดํธํ๊ณ , ๋ค์ ๋ฐฉ๋ฌธ ์์๋ ์ด์  ์ํ๋ฅผ ์ ์งํ ์ ์๊ฒ ํด์ค๋๋ค.
๐ก ์ ์ฉ ์์ด๋์ด: ํด๋ฆญ์ผ๋ก ๋จ๊ณ ์ ํ + ์ ์ฅ ๊ธฐ๋ฅ
- ์ฌ์ฉ์๊ฐ STEP 1~4 ์ค ํ๋๋ฅผ ํด๋ฆญํ๋ฉด ํด๋น ๋จ๊ณ๋ก ์งํ ์ํ ์ ๋ฐ์ดํธ
 - ์งํ ์ํ๋ localStorage์ ์ ์ฅ๋ผ ๋ค์ ์ ์ ์์๋ ์ ์ง
 - ํน์  ์กฐ๊ฑด(API ์๋ต ๋ฑ)์ ๋ฐ๋ผ ์๋์ผ๋ก ๋จ๊ณ ์ ํ ๊ฐ๋ฅ
 
โ ํ์๋ผ์ธ UI์ ํต์ฌ ๊ธฐ๋ฅ
- ์๋ฃ๋ ๋จ๊ณ(STEP 1~2)๋ ๋์ผํ ์์๊ณผ ์์ด์ฝ์ผ๋ก ๊ทธ๋ฃน ์ฒ๋ฆฌ
 - ์งํ ์ค์ธ ๋จ๊ณ(STEP 3)๋ ์ปฌ๋ฌ ๊ฐ์กฐ + ์ ๋๋ฉ์ด์  ํจ๊ณผ
 - ๋๊ธฐ ์ํ(STEP 4)๋ ํ๋ฆฐ ์์ผ๋ก ์๊ฐ์  ๋๋น
 - ๋ฐ์ํ ๋ ์ด์์์ผ๋ก ๋ชจ๋ฐ์ผ์์๋ ์ ์๋
 - ์คํฌ๋ฆฐ๋ฆฌ๋ ์ฌ์ฉ์๋ฅผ ์ํ ์ ๊ทผ์ฑ ์์ฑ(aria-label, role) ํฌํจ
 
๐ ์ ๊ทผ์ฑ์ ๊ณ ๋ คํ ์ค๊ณ ํฌ์ธํธ
์์ฆ์ ๋จ์ํ ์๊ฐ์  ๋ง์กฑ์ ๋์ด์, ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์ ๋ณด๋ฅผ ๋๋ฑํ๊ฒ ์ ๋ฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ด ํ์๋ผ์ธ ์ปดํฌ๋ํธ์๋ ๋ค์๊ณผ ๊ฐ์ ์ ๊ทผ์ฑ ์์๋ฅผ ๋ฐ์ํ์ต๋๋ค:
- ๊ฐ ๋จ๊ณ์ role="listitem"๊ณผ aria-label ์ ์ฉ: ์คํฌ๋ฆฐ๋ฆฌ๋๊ฐ ๊ฐ ์ํ๋ฅผ ์ฝ์ ์ ์๊ฒ ํจ
 - ์์ ์ธ์ โ/โณ ๋ฑ์ ํ ์คํธ ํน์ ์์ด์ฝ์ผ๋ก ์ํ ๊ตฌ๋ถ
 - ์ถฉ๋ถํ ์ ๋๋น ํ๋ณด (WCAG ๊ธฐ์ค 4.5:1 ์ด์)
 - ํฅํ์๋ ํค๋ณด๋ ์ ๊ทผ์ฑ(tab ํค ์ง์)๋ ์ถ๊ฐํ ๊ณํ
 
โ ์ ๊ทผ์ฑ ๊ณ ๋ ค HTML ์์ 
<section aria-labelledby="timeline-heading">
  <h2 id="timeline-heading">์งํ ๋จ๊ณ ํ์๋ผ์ธ</h2>
  <ol class="timeline" role="list" aria-label="CAD ํ์ผ ๋ค์ด๋ก๋ ์งํ ๋จ๊ณ">
    <li class="step completed" role="listitem" aria-label="STEP 1 ์๋ฃ: CAD ํ์ผ ์ค๋น">
      <span class="visually-hidden">โ</span>
      <strong>STEP 1</strong>: CAD ํ์ผ ์ค๋น
    </li>
    <li class="step completed" role="listitem" aria-label="STEP 2 ์๋ฃ: CAD ํ์ผ ๊ฒํ ">
      <span class="visually-hidden">โ</span>
      <strong>STEP 2</strong>: CAD ํ์ผ ๊ฒํ 
    </li>
    <li class="step active" role="listitem" aria-label="STEP 3 ์งํ์ค: ์น์ธ ๋๊ธฐ">
      <span class="visually-hidden">โณ</span>
      <strong>STEP 3</strong>: ์น์ธ ๋๊ธฐ
    </li>
    <li class="step" role="listitem" aria-label="STEP 4 ์์ : ๋ค์ด๋ก๋ ๊ฐ๋ฅ">
      <span class="visually-hidden">โฌ</span>
      <strong>STEP 4</strong>: ๋ค์ด๋ก๋ ๊ฐ๋ฅ
    </li>
  </ol>
</section>
๐ ์ฃผ์ ์ ๊ทผ์ฑ ํฌ์ธํธ
- <ol> ํ๊ทธ ์ฌ์ฉ → ๋จ๊ณ์ ์์๋ฅผ ์๋ฏธ์ ์ผ๋ก ํํ
 - aria-label, role="list" / listitem" ์์ฑ → ์คํฌ๋ฆฐ๋ฆฌ๋๊ฐ ๊ฐ ๋จ๊ณ๋ฅผ ์ ํํ ์๋ด
 - ์ํ ์์ด์ฝ(โ, โณ, โฌ) ํ ์คํธ ์จ๊น ์ฒ๋ฆฌ → <span class="visually-hidden">์ผ๋ก ์๊ฐ ์ฅ์ ์ฌ์ฉ์์๊ฒ ์ค๋ช ์ ๊ณต
 - aria-labelledby๋ฅผ ํตํด ํ์๋ผ์ธ ์ ๋ชฉ ์ฐ๊ฒฐ
 
๐ก ์๊ฐ์ ์ผ๋ก ์จ๊ธด ํ ์คํธ ์ฒ๋ฆฌ CSS ์์
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
์ด๋ ๊ฒ ๊ตฌ์ฑํ๋ฉด ๋์์ธ์ ํด์น์ง ์์ผ๋ฉด์๋ ๋ณด์กฐ ๊ธฐ์ ์ ์ฌ์ฉํ๋ ๋ถ๋ค์๊ฒ ์น์ ํ UI๊ฐ ๋ฉ๋๋ค. ๐
๐ง๐ป ์๋๋ฆฌ์ค ์ ์ฉ ์ (CAD ๋ค์ด๋ก๋ ํ์ด์ง)
- ์ฌ์ฉ์๊ฐ STEP 2(CAD ์ด๋ฏธ์ง ์ ๋ก๋)๋ฅผ ์๋ฃํ๋ฉด ์๋์ผ๋ก STEP 3์ผ๋ก ๋์ด๊ฐ
 - ๊ด๋ฆฌ์ ๊ณ์ ์์๋ ์น์ธ ์ ์๋ STEP 4๋ก ์ ํ + ๋ค์ด๋ก๋ ๋ฒํผ ํ์ฑํ
 - ์ด๋ฏธ์ง๋ฅผ ์ ๋ก๋ํ๋์ง ์ฌ๋ถ๋ API ์ํ๊ฐ์ ํตํด ๊ฐ์ง ๊ฐ๋ฅ
 
๐ ์ถ๊ฐ ๊ธฐ๋ฅ ์์ด๋์ด (ํ์ฅ ๊ฐ๋ฅ)
- ๋ฒํผ ํด๋ฆญ ์ ์๋ฒ์ ์ํ ์ ๋ฐ์ดํธ ์์ฒญ (fetch ์ด์ฉ)
 - ์ ๊ทผ ์ ์ด: ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ง ํน์  ๋จ๊ณ ์งํ ๊ฐ๋ฅ
 - ์ํ๋ณ๋ก ์๊ฐ ๊ธฐ๋ก ์ ์ฅ (์: ์น์ธ ๋๊ธฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ๊ฒฝ์ฐ ํ์)
 
๐ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์ด์ฒ๋ผ ๊ฐ๋จํ ํ์๋ผ์ธ ์ปดํฌ๋ํธ ํ๋๋ง์ผ๋ก๋ ์ฌ์ฉ์์ ๊ฒฝํ์ ํ์ธต ๋์ผ ์ ์์ต๋๋ค.
ํนํ CAD์ ๊ฐ์ด ๋จ๊ณ๋ณ ํ๋ฆ์ด ๋ช ํํ ์๋น์ค๋ผ๋ฉด ๋์ฑ ์ ํฉํ์ฃ .
๊ทธ๋ฆฌ๊ณ JavaScript๋ฅผ ๋ํ๋ฉด ๋จ์ํ “๋ณด์ฌ์ฃผ๋ UI”๋ฅผ ๋์ด์
์ฌ์ฉ์์์ ์ํธ์์ฉ์ ๊ธฐ๋ฐ์ผ๋ก ๋จ๊ณ๊ฐ ๋ณ๊ฒฝ๋๋ ์ค์๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค ์ ์์ด์.