μžλ°”μŠ€ν¬λ¦½νŠΈUI

μ§„ν–‰ 상황을 μ‹œκ°ν™”ν•˜λŠ” νƒ€μž„λΌμΈ UI λ§Œλ“€κΈ° (JavaScript 기반)

πŸ―κΏ€μƒμ΄πŸ 2025. 6. 23. 09:29

νƒ€μž„λΌμΈ UI λ§Œλ“€κΈ°

 

 

μ›Ήμ—μ„œ μ‚¬μš©μžμ˜ μœ„μΉ˜μ™€ μ§„ν–‰ μƒνƒœλ₯Ό λͺ…ν™•ν•˜κ²Œ λ³΄μ—¬μ£ΌλŠ” 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);
  });
});

 

이 μ½”λ“œλŠ” μ‚¬μš©μž 클릭으둜 μ§„ν–‰ 단계λ₯Ό μ—…λ°μ΄νŠΈν•˜κ³ , λ‹€μŒ λ°©λ¬Έ μ‹œμ—λ„ 이전 μƒνƒœλ₯Ό μœ μ§€ν•  수 있게 ν•΄μ€λ‹ˆλ‹€.

 

πŸ’‘ 적용 아이디어: 클릭으둜 단계 μ „ν™˜ + μ €μž₯ κΈ°λŠ₯

  1. μ‚¬μš©μžκ°€ STEP 1~4 쀑 ν•˜λ‚˜λ₯Ό ν΄λ¦­ν•˜λ©΄ ν•΄λ‹Ή λ‹¨κ³„λ‘œ μ§„ν–‰ μƒνƒœ μ—…λ°μ΄νŠΈ
  2. μ§„ν–‰ μƒνƒœλŠ” localStorage에 μ €μž₯돼 λ‹€μŒ 접속 μ‹œμ—λ„ μœ μ§€
  3. νŠΉμ • 쑰건(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”λ₯Ό λ„˜μ–΄μ„œ 

μ‚¬μš©μžμ™€μ˜ μƒν˜Έμž‘μš©μ„ 기반으둜 단계가 λ³€κ²½λ˜λŠ” μ‹€μ‹œκ°„ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€ 수 μžˆμ–΄μš”.