# Jelly UI - 네이티브 HTML 폼 컨트롤에 소프트 바디 물리 효과 적용

> Clean Markdown view of GeekNews topic #31648. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=31648](https://news.hada.io/topic?id=31648)
- GeekNews Markdown: [https://news.hada.io/topic/31648.md](https://news.hada.io/topic/31648.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-07-21T11:34:20+09:00
- Updated: 2026-07-21T11:34:20+09:00
- Original source: [jelly-ui.com](https://jelly-ui.com/)
- Points: 4
- Comments: 1

## Topic Body

- **Jelly UI v1.1**은 실제 폼 컨트롤과 말랑한 소프트 바디 물리 효과를 결합한 의존성 없는 웹 컴포넌트 라이브러리로, 40개 커스텀 엘리먼트를 제공함
- 하나의 모듈 스크립트로 설치하며 **다크 모드**, 운영체제 테마 자동 추적, 강조색 변경, 오른쪽에서 왼쪽으로 쓰는 RTL 배치를 지원함
- 버튼은 네이티브 `&lt;button&gt;`, 슬라이더는 숨겨진 `range` 입력을 이용해 키보드 조작·스크린 리더·폼 참여를 위한 **네이티브 의미 구조**를 유지함
- 체크박스와 입력창부터 토스트·탭·다이얼로그까지 다양한 요소에 눌림·늘어남·물결·튕김 같은 **촉각적 애니메이션**을 적용함
- WCAG AA 색상 토큰과 ARIA 패턴을 내장해 부드러운 시각 효과를 살리면서도 **접근 가능한 제품 인터페이스**를 구성할 수 있음

---

### 설치와 테마
- Jelly UI는 **의존성 없이**, 40개 커스텀 엘리먼트와 하나의 `&lt;script type="module"&gt;` 태그만으로 사용할 수 있음
  ```html
  &lt;script type="module" src="https://jelly-ui.com/package.js"&gt;&lt;/script&gt;
  
  &lt;jelly-theme mode="auto"&gt;
    &lt;jelly-button variant="mint"&gt;Publish&lt;/jelly-button&gt;
  &lt;/jelly-theme&gt;
  ```
- [`&lt;jelly-theme&gt;`](https://jelly-ui.com/api/#jelly-theme)는 하위 트리에 디자인 토큰을 한정 적용하는 테마 공급자임
  - `mode`는 `auto`, `light`, `dark`를 지원해 운영체제 설정을 따르거나 특정 테마를 강제할 수 있음
  - `accent`로 **강조색**을 다시 지정할 수 있음
- 공통 색상 변형은 `azure`, `rose`, `amber`, `mint`, `graphite`, `platinum`, `white`이며, 크기는 주로 `small`, `medium`, `large`로 구성됨

### 버튼과 동작 요소
- [`&lt;jelly-button&gt;`](https://jelly-ui.com/api/#jelly-button)은 내부에 실제 네이티브 `&lt;button&gt;`을 넣어 키보드와 스크린 리더를 지원하는 **캡슐형 버튼**임
  - 색상·크기와 `pill`·`square` 형태, 비활성화 및 블록 배치를 설정할 수 있음
- [`&lt;jelly-icon-button&gt;`](https://jelly-ui.com/api/#jelly-icon-button)은 아이콘 하나에 맞춘 사각형 또는 원형 버튼임
  - `label` 속성으로 스크린 리더가 인식할 이름을 지정함

### 폼 입력 컨트롤
- [`&lt;jelly-checkbox&gt;`](https://jelly-ui.com/api/#jelly-checkbox)는 폼에 참여하며 `checked`와 **불확정 상태**(`indeterminate`)를 지원하고, 상태가 바뀔 때 젤리 사각형이 튀어 오름
- [`&lt;jelly-input&gt;`](https://jelly-ui.com/api/#jelly-input)은 `text`, `email`, `password`용 한 줄 입력 필드임
  - 포커스를 받으면 표면이 들리고 테두리가 나타나며, 입력할 때마다 캐럿 위치에서 물결이 번짐
  - `disabled`와 `readonly`를 지원함
- [`&lt;jelly-label&gt;`](https://jelly-ui.com/api/#jelly-label)은 `for`로 컨트롤과 연결됨
  - 클릭하면 대상에 포커스하고 라벨 텍스트가 **접근 가능한 이름**이 되며, 필수 여부와 크기를 지정할 수 있음
- [`&lt;jelly-otp&gt;`](https://jelly-ui.com/api/#jelly-otp)는 숫자마다 상자 하나를 제공하는 **일회용 코드 입력기**임
  - 입력, 백스페이스, 화살표 키, 붙여넣기를 처리하며 길이·색상·크기·비활성화를 설정할 수 있음
- [`&lt;jelly-radio&gt;`](https://jelly-ui.com/api/#jelly-radio)는 같은 루트에서 동일한 `name`을 공유하는 항목끼리 그룹을 형성함
  - 이동식 `tabindex`와 문서 방향을 고려한 **화살표 키 탐색**을 지원함
- [`&lt;jelly-radio-group&gt;`](https://jelly-ui.com/api/#jelly-radio-group)은 `jelly-radio`를 위한 라벨 있는 `radiogroup` 컨테이너임
  - 범례, 가로·세로 흐름 배치, 자식 요소로의 크기 전달을 제공함
- [`&lt;jelly-range&gt;`](https://jelly-ui.com/api/#jelly-range)는 최솟값과 최댓값 구간을 고르는 **이중 핸들 슬라이더**임
  - 두 손잡이에 `role="slider"`, 포커스, ARIA를 적용하며 드래그할 때 젤리 손잡이가 눌림
- [`&lt;jelly-segmented&gt;`](https://jelly-ui.com/api/#jelly-segmented)는 상호 배타적인 선택지를 담은 캡슐형 트랙임
  - 선택 표시는 구간 사이를 이동하면서 기울고 늘어나는 젤리 알약 형태로 동작함
- [`&lt;jelly-select&gt;`](https://jelly-ui.com/api/#jelly-select)는 ARIA `combobox`·`listbox` 패턴을 사용하는 폼 연동 드롭다운임
  - 트리거와 옵션 패널 모두 소프트 바디 표면으로 구성됨
  - 패널은 필드에서 펼쳐지며 아래 공간이 부족하면 **위쪽으로 전환**됨
- [`&lt;jelly-slider&gt;`](https://jelly-ui.com/api/#jelly-slider)는 단일 값을 선택하는 슬라이더임
  - 숨겨진 네이티브 `range` 입력이 의미 구조와 폼 참여를 담당하고, 화면에는 눌리는 젤리 손잡이가 표시됨
- [`&lt;jelly-switch&gt;`](https://jelly-ui.com/api/#jelly-switch)는 드래그 가능한 스위치로, 손잡이가 액체 방울처럼 늘어나고 꺼짐·켜짐 색상이 교차 전환됨
- [`&lt;jelly-textarea&gt;`](https://jelly-ui.com/api/#jelly-textarea)는 여러 줄 입력에 따라 최소·최대 높이 사이에서 자동으로 커짐
  - 표면도 높이에 맞춰 늘어나며 입력 시 캐럿 위치에서 물결이 발생하고, `disabled`와 `readonly`를 지원함

### 상태와 피드백
- [`&lt;jelly-alert&gt;`](https://jelly-ui.com/api/#jelly-alert)는 `info`, `success`, `warning`, `danger` 네 가지 톤과 선택적인 **닫기 버튼**을 제공하는 배너임
- [`&lt;jelly-badge&gt;`](https://jelly-ui.com/api/#jelly-badge)는 배지·태그·상태 표시에 쓰는 작은 요소로, 텍스트가 바뀔 때 튀어 오름
  - 채움·외곽선, 알약·사각형 형태와 `live`, `instant` 동작을 설정할 수 있음
- [`&lt;jelly-progress&gt;`](https://jelly-ui.com/api/#jelly-progress)는 진행에 따라 채움의 앞부분이 흔들리는 진행 표시줄임
  - **불확정 모드**에서는 덩어리가 양쪽 벽 사이를 튕김
- [`&lt;jelly-skeleton&gt;`](https://jelly-ui.com/api/#jelly-skeleton)은 반짝임 대신 부드럽게 호흡하듯 흔들리는 로딩 자리표시자임
  - `line`, `rect`, `circle` 형태를 지원함
- [`&lt;jelly-spinner&gt;`](https://jelly-ui.com/api/#jelly-spinner)는 세 점 사이를 이동하는 점액 덩어리형 `dots`와 형태를 바꾸며 회전하는 `blob` 표시기를 제공함
- [`&lt;jelly-toaster&gt;`](https://jelly-ui.com/api/#jelly-toaster)는 인라인 끝 방향에서 나타났다가 사라지는 토스트 알림을 관리함
  - 일반적으로 `jellyToast('Saved!', { tone: 'success' })` 헬퍼로 호출함
  - 배치된 요소에 `position="bottom"`을 주면 알림 스택이 위로 자라남

### 콘텐츠 표면
- [`&lt;jelly-accordion&gt;`](https://jelly-ui.com/api/#jelly-accordion)은 여러 `&lt;jelly-collapsible&gt;` 항목을 묶음
  - `single` 모드에서는 하나가 열릴 때 나머지가 튕기듯 닫힘
- [`&lt;jelly-card&gt;`](https://jelly-ui.com/api/#jelly-card)는 콘텐츠 아래에 놓이는 젤리 표면 컨테이너임
  - `squish`를 추가하면 부드러운 쿠션처럼 눌리면서 **버튼 역할**을 함
- [`&lt;jelly-chip&gt;`](https://jelly-ui.com/api/#jelly-chip)은 정적 라벨, 전환 가능한 필터 또는 제거 가능한 태그로 사용할 수 있음
  - 선택 가능·선택 상태·제거 가능·비활성화 여부를 설정함
- [`&lt;jelly-collapsible&gt;`](https://jelly-ui.com/api/#jelly-collapsible)은 헤더 버튼으로 패널을 튕기듯 열고 닫는 펼침·접기 영역임
  - 텍스트가 아니라 **표면이 움직이도록** 구성됨
- [`&lt;jelly-divider&gt;`](https://jelly-ui.com/api/#jelly-divider)는 가로·세로 또는 라벨이 있는 가는 구분선임
- [`&lt;jelly-kbd&gt;`](https://jelly-ui.com/api/#jelly-kbd)는 눌러 볼 수 있는 젤리 키캡임
  - `key`로 실제 키와 연결하면 페이지 어디서든 해당 키를 누르는 동안 키캡도 내려감

### 탐색과 레이아웃
- [`&lt;jelly-resizable&gt;`](https://jelly-ui.com/api/#jelly-resizable)은 젤리 구분선을 드래그하거나 키보드로 크기를 조절하는 **패널 그리드**임
  - `row`, `vertical`, `both` 방향을 지원함
- [`&lt;jelly-tabs&gt;`](https://jelly-ui.com/api/#jelly-tabs)는 실제 `tablist` 의미 구조를 사용하는 탭 보기임
  - 젤리 알약 형태의 선택 표시가 이동하고 탭 패널이 튕기며 나타남

### 오버레이
- [`&lt;jelly-dialog&gt;`](https://jelly-ui.com/api/#jelly-dialog)는 젤리처럼 튀며 나타나는 모달 대화상자임
  - 페이지를 잠그고 닫힌 뒤 이전 위치로 **포커스를 반환**함
  - Escape 키, 닫기 버튼 또는 배경 클릭으로 닫을 수 있음
- [`&lt;jelly-drawer&gt;`](https://jelly-ui.com/api/#jelly-drawer)는 끝에서 약간 넘어갔다 돌아오는 스프링 효과로 나타나는 플로팅 시트임
  - 인라인 시작·끝 또는 아래쪽에서 열 수 있음
- [`&lt;jelly-popover&gt;`](https://jelly-ui.com/api/#jelly-popover)는 클릭으로 여는 비모달 패널임
  - 트리거에 고정되며 Escape 키나 외부 클릭으로 닫힘
  - `top`, `bottom`, `start`, `end` 배치를 지원함
- [`&lt;jelly-tooltip&gt;`](https://jelly-ui.com/api/#jelly-tooltip)은 마우스를 올리거나 키보드 포커스를 받을 때 트리거 위에 테마가 적용된 말풍선을 표시함
  - 네 방향 배치와 세 가지 크기를 지원함

## Comments



### Comment 62143

- Author: neo
- Created: 2026-07-21T11:34:21+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48981620) 
- 창이 다소 버벅여서 원인을 파고들어 봤는데, 이 라이브러리는 페이지의 모든 컴포넌트에 걸쳐 **8ms마다 requestAnimationFrame(RAF) 애니메이션 루프**를 실행하며 문서 전체를 다시 그리게 함  
  위의 “활성 컴포넌트를 한 프레임에서 함께 처리하고 유휴 상태에서는 멈춘다”는 주석도 AI가 생성한 듯함. `JellyEngine`은 포인터 이벤트가 발생할 때만 젤리 애니메이션을 계산하지 않고, 페이지의 모든 활성 컴포넌트를 프레임마다 다시 계산함. 보통 사람이 보면 “이렇게 하면 안 된다, 너무 과하다”고 할 만한 구현임
  - Chrome에서 **성능 프로파일링**을 해보니 이 설명을 뒷받침하지 않았음. 루프는 갱신할 컴포넌트를 활성 `Set()`으로 관리하고 움직임이 멈추면 제거하는 구조로 보임  
    주석이 다소 AI가 대충 생성한 듯하다는 데는 동의하지만 접근법 자체에 명백한 문제는 찾지 못했고, 아무 동작도 없을 때 핵심 루프는 수 마이크로초 만에 끝남
  - 과한 방식이 아님. **비디오 게임의 99.99%** 가 말 그대로 이렇게 동작하며, 수직 동기화 주사율이나 하드웨어 성능이 허용하는 한 계속 전체 화면을 다시 그림

- 마음에 들지만 **표준 UX 관행**에는 맞지 않는 듯함  
  누른 채로 마우스를 요소 밖으로 옮겨 놓으면 클릭으로 처리되지 않아야 한다고 봄. 현재는 버튼은 클릭으로 처리하지만 체크박스는 그렇지 않아 일관성이 없음
  - Flash 개발자들과 일할 때 늘 겪던 문제임. “스크롤바의 모든 기능을 구현할 수 없다면 **스크롤바를 재구현하지 말라**”는 원칙이 흔했지만, 결국 다섯 번 넘게 고치며 며칠씩 쓰곤 했음
  - 좋은 발견이라 **버튼 로직**을 수정했으며, 이제 커서가 버튼 경계 밖에 있으면 클릭이 발생하지 않음

- 진심으로 귀엽고, `@media (prefers-reduced-motion: reduce)`에서 자연스럽게 기능을 줄이는 점도 좋음  
  다만 데모 사이트에서는 시스템 설정을 바꾸지 않고도 사용자가 이를 재정의하게 하거나, 적어도 **애니메이션이 표시되지 않는다는 안내**가 있으면 좋겠음
  - 의도적으로 모션을 줄인다는 걸 놓쳐서 고장 난 줄 알았음. 예전에 해당 설정을 켰다는 사실도 잊고 있었음
  - Apple 메뉴 > 시스템 설정 > 손쉬운 사용 > 동작에서 **동작 줄이기**를 설정할 수 있음  
    이런 멋진 데모가 나올 때마다 설정을 기억하는 데 잠시 걸리며, 그동안은 “뭐가 특별하다는 거지?”라며 실망한 채 클릭하게 됨
  - 이제 알림을 표시하고, **예쁜 토끼 아이콘**을 눌러 시스템 설정을 덮어쓸 수도 있게 했음

- 젊었을 때라면 정말 좋아했겠지만, 요즘은 로컬 스타일시트로 이런 효과를 제거하거나 **다크 모드와 읽기 모드**를 쓰는 데 더 많은 시간을 보냄. 세월이 많이 변했음
  - 애니메이션이 현재 일어나거나 변경되는 일을 강조해 주는 피드백이라 좋음. 네이티브 컴포넌트는 이를 항상 잘 표현하지 못하며, 제대로 사용한 애니메이션은 단순한 장식이 아니라 **실질적인 UX 가치**가 있음
  - 해마다 한 번쯤은 소프트웨어에 더 많은 재미를 원했다가, 다시 **방해하지 않기만을** 바라게 됨

- 마우스를 올렸을 때도 약한 강도로 효과가 나타나면 좋겠음. 진행률 표시줄과 토스트 등 일부 컨트롤에는 젤리 효과가 없는 듯함  
  데모 페이지의 **성능도 썩 좋지 않고 스크롤을 가로채는 느낌**이 들지만, 전체적으로 귀엽고 게임 UI에 잘 어울릴 듯함

- `Chip` 요소는 제자리에 머물며 전환되어야 하는데, 클릭하면 **경계 밖으로 벗어나서** 마음에 들지 않음

- 귀엽지만 일부 컨트롤의 **반응 속도**가 너무 나쁨. 슬라이더를 앞뒤로 드래그하면 마우스 커서를 크게 뒤처지며, 접착제로 붙인 것처럼 커서를 따라야 함  
  반면 `jelly-resizable` 같은 다른 컨트롤은 커서에 잘 붙어 움직임. `"Placeholder"` 컨트롤은 클릭해도 자리표시자가 사라지지 않는 듯함

- 2007~2010년 무렵 Paul Neave의 웹사이트·블로그·쇼케이스에서 페이지 테두리에 비슷한 **젤리 효과**가 있었던 것을 기억하는 사람이 있는지 궁금함. 당시에는 Flash로 구현했음  
  그 시절 Paul Neave는 개인적인 영웅이었으며, 이 글을 읽고 있다면 잘 지내길 바람

- 이 UI 디자인 시스템에서 **물리 효과**라고 할 만한 것을 전혀 찾기 어려움
  - 이 라이브러리는 클라이언트의 **동작 줄이기 설정**을 존중해 모든 애니메이션 효과를 비활성화함

- 내 **색각 이상 유형**이나 모니터 설정 때문일 수도 있지만, 빨간색과 호박색이 너무 비슷해 버튼을 눌렀는지조차 구분할 수 없었음
