FNA Design System

표

관제·이력·일지 목록의 기본형. 숫자는 오른쪽 정렬 tabular-nums, 단위는 작게, 부적합 행은 배경 + 왼쪽 3px 바, 폰에서는 열을 숨기지 않고 가로 스크롤합니다.

센서온도 (℃)상태
냉동창고 A-18.4정상
냉장 17.3이탈
냉장 23.1정상

정의

같은 구조의 항목 여러 개를 열로 비교하는 요소입니다. 헤더는 12px 굵게 muted, 셀은 13px, 행 높이 약 40(compact 32, dense 28~32). 정렬·선택·상태 행·고정 헤더·고정 첫 열·줄무늬·밀도 변형이 있습니다.

언제 쓰고 언제 쓰지 않나

  • 3열 이상, 5행 이상이면 표. 그보다 적으면 카드 목록 또는 정의 목록.
  • 폰에서 카드로 바꾸지 않는다. .fna-table--responsive + 첫 열 고정으로 가로 스크롤.
  • 표 안 차트는 스파크라인만. 표 안 버튼은 sm 아웃라인 하나까지.
  • 모든 차트에는 표 보기 쌍둥이가 있다(Data Visualization).

해부도

센서온도 (℃)기준상태수신
냉동창고 AFRZ-01 · 배터리 82%-18.4−22 ~ −15정상3분 전
냉장 1CHL-017.30 ~ 5이탈방금 전
전처리실--0 ~ 10미수신2시간 전
  1. 헤더12/700 muted · surface-low · 밑선 2px · 줄바꿈 없음
  2. 정렬 헤더aria-sort 로 화살표 CSS 생성, 활성 정렬만 primary. 단위는 헤더에 (셀에서는 생략)
  3. 숫자 셀td.num 우측 정렬 tabular-nums, 소수 자릿수 통일
  4. 부적합 행error-container 배경 + 첫 셀 왼쪽 3px error 바 + 첫 셀 제목 error-text
  5. 보조 줄.fna-table__sub 11px muted — ID·배터리·모델

변형

정렬 · 선택 · 상태 행 · 단위 · 결재 셀
날짜라인점검부적합결재
09-27 (일)1라인42건0승인 완료
09-28 (월)1라인45건0승인 대기
09-29 (화)3라인40건2반려
09-29 (화)2라인38건0작성 중
코드
<div class="fna-table-wrap"><table class="fna-table"><thead><tr><th><input type="checkbox" aria-label="전체 선택"></th><th aria-sort="ascending">날짜</th><th>라인</th><th class="num">점검</th><th class="num">부적합</th><th>결재</th><th></th></tr></thead><tbody>
  <tr class="is-selected"><td><input type="checkbox" checked aria-label="선택"></td><td>09-27 (일)</td><td>1라인</td><td class="num">42<span class="unit">건</span></td><td class="num">0</td><td class="approval"><span class="fna-approval" data-status="approved">승인 완료</span></td><td><button class="fna-btn fna-btn--outline fna-btn--sm">보기</button></td></tr>
  <tr><td><input type="checkbox" aria-label="선택"></td><td>09-28 (월)</td><td>1라인</td><td class="num">45<span class="unit">건</span></td><td class="num">0</td><td class="approval"><span class="fna-approval" data-status="reviewed">승인 대기</span></td><td><button class="fna-btn fna-btn--outline fna-btn--sm">보기</button></td></tr>
  <tr class="is-nonconform"><td><input type="checkbox" aria-label="선택"></td><td><b>09-29 (화)</b></td><td>3라인</td><td class="num">40<span class="unit">건</span></td><td class="num">2</td><td class="approval"><span class="fna-approval" data-status="rejected">반려</span></td><td><button class="fna-btn fna-btn--outline fna-btn--sm">보기</button></td></tr>
  <tr class="is-caution"><td><input type="checkbox" aria-label="선택"></td><td>09-29 (화)</td><td>2라인</td><td class="num">38<span class="unit">건</span></td><td class="num">0</td><td class="approval"><span class="fna-approval" data-status="draft">작성 중</span></td><td><button class="fna-btn fna-btn--outline fna-btn--sm">보기</button></td></tr>
  </tbody></table></div>
밀도 높은 관제 목록 (dense, striped, sticky 헤더)
사업장센서온도 (℃)상태추세수신
평택공장냉동창고 A-18.4정상3분 전
평택공장냉동창고 B-20.1정상3분 전
평택공장냉장 17.3이탈방금 전
안성공장냉동 1-19.2정상1분 전
안성공장냉장 24.8주의1분 전
음성공장전처리실--미수신2시간 전
음성공장냉동 1-18.9정상2분 전
음성공장냉동 2-18.7정상2분 전
폰 — 가로 스크롤 + 첫 열 고정 (.fna-table--responsive + --sticky-col)
센서 목록
센서온도 (℃)기준상태수신배터리
냉동창고 A-18.4−22 ~ −15정상3분 전82%
냉장 17.30 ~ 5이탈방금 전64%
냉동창고 B-20.1−22 ~ −15정상3분 전90%

← 옆으로 밀어 더 보기

빈 상태
날짜라인점검결재
이 기간에 작성된 일지가 없습니다
코드
<div class="fna-table-wrap"><table class="fna-table"><thead><tr><th>날짜</th><th>라인</th><th class="num">점검</th><th>결재</th></tr></thead><tbody><tr><td colspan="4" class="fna-table__empty"><svg width="56" height="40" viewBox="0 0 56 40" aria-hidden="true" style="display:block;margin:0 auto 10px"><rect x="24" y="0" width="32" height="8" rx="4" fill="var(--fna-border-strong)"/><rect x="12" y="14" width="32" height="8" rx="4" fill="var(--fna-border-strong)"/><rect x="0" y="28" width="20" height="8" rx="4" fill="var(--fna-border-strong)"/></svg>이 기간에 작성된 일지가 없습니다<br><button class="fna-btn fna-btn--sm" style="margin-top:10px">오늘 일지 작성</button></td></tr></tbody></table></div>

상태 (행)

클래스모양뜻
(기본)surface, 호버 시 table-hover
tr.is-selectedtable-selected(primary-container)체크박스와 함께
tr.is-nonconform / .is-baderror-container + 왼쪽 3px error 바 + 첫 셀 b error-text부적합·반려·이탈 행
tr.is-cautionwarning-container주의·작성 중 미제출
tr.is-offneutral-container + muted 글자미수신·중지

치수

항목기본compactdense폰
셀 패딩.75em .9em.45em .6em.4em .6em.6em .65em
행 높이(약)40323036
글자13 (헤더 12)131213
최소 폭———560 (responsive)
고정 높이--fna-table-max-h 60vh (sticky)
스파크라인96 × 28

Do · Don't

센서온도 (℃)
냉동 A-18.4
냉장 12.0
Do 단위는 헤더에, 숫자 우측 정렬, 자릿수 통일
센서온도
냉동 A-18.4℃
냉장 12℃
Don't 단위 반복 · 왼쪽 정렬 · 자릿수 제각각
냉장 17.3이탈
Do 상태 행은 배경 + 바 + 배지
냉장 17.3이탈
Don't 셀 글자를 빨갛게만

접근성

  • <table> + <th scope="col">. 첫 열이 행 제목이면 <th scope="row">. <caption> 또는 aria-label 로 표 이름.
  • 정렬: th[aria-sort] 안에 <button>. 화살표는 CSS 라 스크린리더는 aria-sort 로 읽는다.
  • 행 상태는 배경만이 아니라 배지 텍스트로도 전달된다.
  • 가로 스크롤 영역은 tabindex="0" + role="region" aria-label 로 키보드 스크롤 가능.
  • 고정 헤더·첫 열은 큰글씨 모드에서도 유지(em 패딩).

문구

헤더는 명사 + (단위): 온도 (℃) · 점검 · 부적합 · 수신. 빈 상태는 "이 기간에 …가 없습니다" + 다음 행동 버튼. 숫자 없음은 "--"(하이픈 둘)이 아니라 "—"(em dash) 또는 "미수신" 배지로. 시각 열은 상대("3분 전") + 툴팁 절대("2026-09-29 12:37:04").

코드

<div class="fna-table-wrap fna-table-wrap--sticky-col" role="region" aria-label="센서 목록" tabindex="0">
  <table class="fna-table fna-table--responsive">
    <thead><tr><th scope="col">센서</th><th scope="col" class="num" aria-sort="descending"><button>온도 (℃)</button></th>…</tr></thead>
    <tbody>
      <tr class="is-nonconform"><th scope="row"><b>냉장 1</b><span class="fna-table__sub">CHL-01</span></th><td class="num">7.3</td><td class="status"><span class="fna-badge fna-badge--alarm">이탈</span></td></tr>
    </tbody>
  </table>
</div>
<!-- 변형: --striped --dense --compact --nowrap · wrap: --sticky (--fna-table-max-h) --sticky-col -->

안정마지막 갱신 담당 디자인시스템 TF · jjo831@farmzone.kr소스 components.css .fna-table · docs/dataviz.md §4Components · FNA 디자인 시스템 v1.0