웹 리퀴드 글라스은(는) 무엇을 하나요?
라이브 Next.js + Tailwind 사이트에서 추출한 프로덕션 유리 소재입니다. 전체 작업 소스는 reference/ 디렉토리에 있습니다:
reference/liquid-glass.css: 전체 소재(토큰, 표면, 변형, 성형 유리, 굴절, 저하). 모든 값을 설명하는 긴 주석이 포함된 약 2,200줄입니다. 전체 파일을 읽지 말고 필요한 섹션만 읽으세요.reference/glass.tsx:<Glass>React 컴포넌트와 SVG 굴절 필터.reference/glass-specular.tsx: 포인터 및 기울기 추적 정반사 하이라이트.
참조 코드는 두 개의 사이트 헬퍼(cn과 LITE_CLASS)를 가져옵니다. 프로젝트 자체의 cn/clsx와 "효과 끄기"용 클래스 이름으로 교체하세요. sky-*, kiosk-* 및 기도 관련 선택자로 명명된 규칙은 사이트별 변형 예시입니다. 삭제하거나 패턴으로 사용하세요.
유리의 정의
유리는 네 가지 부분으로 구성됩니다. 웹 버전은 첫 번째 부분만 구현하면 싸구려처럼 보입니다:
- 재질(Material): 흐림 효과와 채도 향상(약 200%). 150% 미만이면 회색 플라스틱처럼 보입니다. 밝기를 높이고 대비를 낮춰 배경의 복잡한 콘텐츠가 부드럽게 확산되도록 합니다.
- 테두리(Rim): 가장자리에 빛이 닿는 밝은 가는 선, 반대쪽 가장자리는 더 어둡게. 테두리 없는 흐림 효과는 절대 유리처럼 보이지 않습니다.
- 광택(Sheen): 상단 가장자리 안쪽의 부드러운 정반사 하이라이트.
- 깊이(Depth): 넓고 매우 부드러우며 불투명도가 낮은 그림자(좁은 카드 그림자가 아님).
굴절(가장자리에서 콘텐츠가 휘어짐)은 다섯 번째 부분이며, 웹에서 저렴하게 구현할 수 없는 유일한 부분입니다. backdrop-filter: url(#svg-filter)가 필요하며, 이는 Chromium에서만 작동합니다.
유리의 배치
유리는 탐색 레이어(바, 캡슐 내비게이션, 플로팅 컨트롤, 시트)에 배치하고 본문 콘텐츠에는 사용하지 마세요. 유리 위의 텍스트 대비는 뒤에 스크롤되는 콘텐츠에 따라 달라지므로 보장할 수 없습니다. 콘텐츠에는 불투명 카드를 기본으로 사용하고, 표면당 옵트인(.lg)으로 유리를 적용하세요.
실제 시간이 많이 드는 규칙들
- 유리 CSS는
@tailwind base와 같은 파일,@layer안에 있어야 합니다. Tailwind는 파일별로@layer를 처리하므로 별도 CSS 파일은@layer base에서 오류가 발생합니다. 래퍼를 제거하면 규칙이 레이어 없이 적용되어 모든 Tailwind 유틸리티를 덮어씁니다..lg { position: relative }가 내비게이션의fixed를 조용히 덮어씁니다. - 절대
--x: calc(var(--x) * 0.7)를 작성하지 마세요. 계산 값 시간에 무효화되어 오류 없이 조용히 상속된 값으로 대체됩니다. 두 번째 변수(--lg-clarity-bump,--lg-press)를 사용하세요. - 유리 표면은 정확히 하나의 가장자리를 가지며,
::before가 그립니다. 두 개의 가장자리(::before테두리 + 내부box-shadow베벨, 또는 테두리 상자 외부의 확산 그림자)는 어떤 알파 값 조정으로도 고칠 수 없는 "이중 테두리"를 만듭니다. corner-shape는 상속되지 않습니다. 표면에corner-shape: squircle이 있으면, 테두리를 따라 그려지는 모든 의사 요소에는border-radius: inherit과corner-shape: inherit이 모두 필요합니다. 그렇지 않으면 테두리가 본체와 다른 곡선을 따릅니다.- 유리 안에 중첩된 유리에는
backdrop-filter를 사용하지 마세요. 이미 착색된 배경을 샘플링하여 흐릿해집니다. 유리 바 안의 선택 칩(.lg-chip)은 자체 흐림 효과 없이 착색된 렌즈입니다. :root에서 상속된 사용자 정의 속성을 애니메이션하지 마세요. 전체 문서 스타일을 무효화합니다: 60개 표면 페이지에서 프레임당 약 11.6ms, 동일 값을 요소당 작성하는 2ms와 대조적입니다.- 바는 모든 스크롤 프레임에서 다시 흐려집니다.
.lg-bar에 더 작은 흐림 반경과contain: paint를 지정하세요. 장치가 여전히 버벅이면--lg-blur-bar: 0px로 설정하세요. 테두리와 광택만으로도 충분한 효과를 냅니다. - 결함을 고치기 위해 프로스트 유리를 평평하게 만들지 마세요. 거의 불투명한 "단색" 바는 느낌을 잃습니다. 대신 기하학적 원인을 찾으세요(가장자리에서 본체를 얇게 만드는 마스크, 이중 테두리).
- SVG 굴절 렌즈는 절대 자신의 박스를 넘어 샘플링하지 않아야 합니다. Chrome은 그곳에서 투명을 반환하여 원본 콘텐츠가 유령처럼 보입니다.
Safari와 iPhone
WebKit은 backdrop-filter를 지원하지만 내부의 SVG 필터는 거부하므로, Safari는 Chrome보다 기능이 적습니다: 굴절은 절대 없습니다. Safari가 굴절시킬 수 있는 것은 자체 툴바입니다. viewportFit: "cover"를 설정하여 페이지가 그 아래에서 실행되도록 한 다음, env(safe-area-inset-*)가 탐색 및 푸터에 필수가 됩니다.
접근성 및 대체 처리 (항상 포함하세요)
모든 표면은 비슷하게 보이고 프레임당 비용이 들지 않는 거의 불투명한 착색으로 저하되어야 합니다:
@media (prefers-reduced-transparency: reduce)@supports not (backdrop-filter: blur(1px))@media (prefers-contrast: more): 더 강한 착색과 단색 가장자리- 루트 클래스(예:
.lg-off): 모든 유리 표면을 한 번에 비활성화(사용자 토글 또는 저전력 모드용)
바에는 자체적으로 더 높은 최대 착색(--lg-tint-max-bar)을 지정하여, 콘텐츠가 아래로 스크롤될 때 탐색 링크가 텍스트 대비를 유지하도록 하세요.
적용 방법
reference/liquid-glass.css에서 토큰 블록과 표면 섹션을 프로젝트의 메인 CSS 파일로 복사하고, 기존@layer블록 안에 넣으세요(규칙 1).- 색상 토큰을 프로젝트 팔레트에 매핑하세요. 참조 코드는 shadcn 스타일의
hsl(var(--card))토큰을 사용합니다. reference/glass.tsx의<Glass>또는 일반.lg,.lg-bar,.lg-nav,.lg-pane,.lg-chip,.lg-refract클래스를 사용하세요.reference/glass-specular.tsx의 정반사 하이라이트는 비용 대비 효과가 확실한 곳(히어로 컨트롤, 메인 탐색)에만 추가하고,prefers-reduced-motion을 존중하세요.- Chrome과 Safari 모두, 라이트 및 다크 모드 모두, 복잡한 사진 위와 일반 텍스트 위에서 확인하세요.
기성 컨트롤: Glisse
Kelvin Zhang의 Glisse(npm install glisse, MIT, React 18+, 기타 종속성 없음)는 누르면 렌즈처럼 올라오는 동작이 이미 내장된 대화형 리퀴드 글라스 컨트롤을 제공합니다: Button, Switch, Slider, TabBar, SegmentedControl, Menu, Input, SearchField 및 일반 Glass 표면. 스타일은 JS 번들에 의해 주입되므로 CSS 파일을 가져올 필요가 없습니다.
각각을 사용해야 하는 경우:
- Glisse: 컨트롤용: 스위치, 슬라이더, 탭 바, 분할 컨트롤(드래그 시 엄지가 렌즈로 올라감). 수동으로 만들려면 며칠이 걸립니다.
- 이 소재: 표면용: 탐색 바, 캡슐 내비게이션, 패널, 시트, 사진 위의 카드, 기존 디자인 시스템 또는 Tailwind 테마와 일치해야 하는 모든 것.
결합 시 함정:
- 둘 다
lg-프리픽스를 사용합니다. Glisse는.lg-glass,.lg-button,.lg-tab-bar와 변수--lg-blur,--lg-tint,--lg-rim,--lg-filter를 정의하며, 이는 이 소재의 토큰과 충돌합니다. 둘 다 사용하는 페이지에서는 이 소재의 프리픽스 이름을 바꾸거나(예:ylg-) Glisse를 해당 변수를 재설정하는 래퍼 안에 범위를 지정하세요. 그렇지 않으면 각각이 조용히 서로를 재조정합니다. - Glisse의 다크 모드는
data-theme="dark"또는prefers-color-scheme에 반응하며, Tailwind의.dark클래스에는 반응하지 않습니다. 클래스 기반 다크 모드를 사용하는 경우,.dark와 함께<html>에data-theme을 설정하세요. 그렇지 않으면 Glisse는 라이트 모드로 유지됩니다. - Glisse는
prefers-reduced-motion을 처리하지만prefers-reduced-transparency나prefers-contrast는 처리하지 않습니다. 이 스킬의 접근성 섹션에 있는 대체 처리를 Glisse 컨트롤 주위에 추가하세요. - Glisse의
.lg-glass는 이미 내부box-shadow로 가장자리를 그립니다. 그 위에::before테두리를 추가하지 마세요(규칙 3: 하나의 가장자리만).