Contents
see List2025-2026년 웹 플랫폼에는 JavaScript 없이 구현 가능한 강력한 HTML/CSS 기능들이 속속 추��되었다. 이 글에서는 실무에서 바로 활용할 수 있는 최신 웹 표준 기능 3가지를 다룬다.
1. Popover API
Popover API는 팝업, 드롭다운, 툴팁 등을 JavaScript 없이 순수 HTML로 구현할 수 있게 해준다. 접근성(ARIA), 포커스 관리, 외부 클릭 닫기가 자동으로 처리된다.
기본 사용법
<!-- popover 속성만 추가하면 팝오버 동작 -->
<button popovertarget="menu">메뉴 열기</button>
<div id="menu" popover>
<nav>
<a href="/home">홈</a>
<a href="/about">소개</a>
<a href="/contact">연락처</a>
</nav>
</div>
<!-- JavaScript 없이 자동으로:
- 버튼 클릭 시 팝오버 표시/숨김 토글
- 외부 클릭 시 자동 닫힘
- ESC 키로 닫기
- 접근성(ARIA) 자동 처리 -->
팝오버 모드
<!-- auto (기본): 외부 클릭으로 닫힘, 한 번에 하나만 열림 -->
<div id="popup1" popover="auto">자동 팝오버</div>
<!-- manual: 외부 클릭으로 안 닫힘, 여러 개 동시 열기 가능 -->
<div id="toast" popover="manual">토스트 알림</div>
<!-- popovertargetaction: 열기/닫기 동작 지정 -->
<button popovertarget="dialog" popovertargetaction="show">열기</button>
<button popovertarget="dialog" popovertargetaction="hide">닫기</button>
<button popovertarget="dialog" popovertargetaction="toggle">토글</button>
팝오버 스타일링
/* 팝오버 기본 스타일 */
[popover] {
padding: 1.5rem;
border: 1px solid #e0e0e0;
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
max-width: 400px;
}
/* ::backdrop 의사 요소로 배경 오버레이 */
[popover]::backdrop {
background: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(4px);
}
/* 열기/닫기 애니메이션 */
[popover] {
opacity: 0;
transform: translateY(-10px) scale(0.95);
transition: opacity 0.2s, transform 0.2s,
display 0.2s allow-discrete,
overlay 0.2s allow-discrete;
}
[popover]:popover-open {
opacity: 1;
transform: translateY(0) scale(1);
}
/* 시작 상태 (Opening) */
@starting-style {
[popover]:popover-open {
opacity: 0;
transform: translateY(-10px) scale(0.95);
}
}
2. CSS Anchor Positioning
Anchor Positioning은 한 요소를 다른 요소에 상대적으로 위치시킬 수 있는 CSS 기능이다. 툴팁, 드롭다운 메뉴 등에서 JavaScript로 위치를 계산하던 작업이 순수 CSS로 가능해졌다.
<!-- 앵커 정의 -->
<button class="anchor-btn" style="anchor-name: --my-button">
설정
</button>
<!-- 앵커에 연결된 팝오버 -->
<div popover id="settings-menu" class="anchored-menu">
<ul>
<li>프로필 편집</li>
<li>알림 설정</li>
<li>로그아웃</li>
</ul>
</div>
/* 앵커 정의 */
.anchor-btn {
anchor-name: --my-button;
}
/* 앵커에 위치 연결 */
.anchored-menu {
/* 기본 앵커 설정 */
position-anchor: --my-button;
/* 앵커 아래에 위치 */
top: anchor(bottom);
left: anchor(left);
/* 앵커와의 간격 */
margin-top: 8px;
/* 고정 위치 */
position: fixed;
}
/* position-area로 더 간단하게 */
.tooltip {
position-anchor: --trigger;
position-area: top center; /* 앵커 위쪽 중앙 */
margin-bottom: 8px;
}
/* 화면 밖으로 나갈 때 자동 위치 조정 */
.dropdown {
position-anchor: --menu-trigger;
position-area: bottom span-right;
/* 화면 밖으로 나가면 위로 이동 */
position-try-fallbacks: flip-block;
}
/* 커스텀 폴백 */
@position-try --above {
position-area: top center;
margin-bottom: 8px;
}
@position-try --right {
position-area: right center;
margin-left: 8px;
}
.adaptive-tooltip {
position-anchor: --element;
position-area: bottom center;
position-try-fallbacks: --above, --right;
}
3. Scroll-Driven Animations
���크롤 위치에 연동되는 애니메이션을 JavaScript 없이 CSS만으로 구현할 수 있다.
Progress Bar
<!-- 스크롤 진행률 표시 바 -->
<div class="progress-bar"></div>
<main class="content">
<!-- 긴 콘텐츠 -->
</main>
/* 스크롤 진행률 바 */
.progress-bar {
position: fixed;
top: 0;
left: 0;
height: 4px;
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
width: 100%;
transform-origin: left;
transform: scaleX(0);
z-index: 1000;
/* 스크롤에 연동 */
animation: progress-grow linear;
animation-timeline: scroll(root); /* 루트 스크롤에 ��동 */
}
@keyframes progress-grow {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
스크롤 시 요소 등장
/* 스크롤하면 요소가 페이드인 */
.reveal-card {
opacity: 0;
transform: translateY(50px);
animation: reveal linear both;
animation-timeline: view(); /* 요소가 뷰포트에 들어올 때 */
animation-range: entry 0% entry 100%;
}
@keyframes reveal {
to {
opacity: 1;
transform: translateY(0);
}
}
/* 여러 카드에 시차 적용 */
.reveal-card:nth-child(2) { animation-delay: 0.1s; }
.reveal-card:nth-child(3) { animation-delay: 0.2s; }
.reveal-card:nth-child(4) { animation-delay: 0.3s; }
패럴렉스 효과
/* 배경 패럴렉스 */
.hero {
position: relative;
height: 100vh;
overflow: hidden;
}
.hero__background {
position: absolute;
inset: -20% 0;
background: url('hero.jpg') center / cover;
animation: parallax linear;
animation-timeline: scroll(root);
}
@keyframes parallax {
from { transform: translateY(-10%); }
to { transform: translateY(10%); }
}
/* 수평 스크롤 연동 */
.horizontal-gallery {
display: flex;
gap: 2rem;
animation: scroll-horizontal linear;
animation-timeline: scroll(root);
}
@keyframes scroll-horizontal {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
4. 기타 주목할 CSS 기능들
CSS Nesting (네이티브 중첩)
/* Sass 없이 네이티브 CSS 중첩 */
.card {
padding: 1rem;
border-radius: 12px;
& .title {
font-size: 1.25rem;
font-weight: 700;
}
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
@media (max-width: 768px) {
padding: 0.5rem;
}
}
color-mix() 함수
:root {
--primary: #3b82f6;
}
.button {
background: var(--primary);
}
.button:hover {
/* 기본 색상에 검정 20% 혼합 = 어둡게 */
background: color-mix(in srgb, var(--primary), black 20%);
}
.button:active {
background: color-mix(in srgb, var(--primary), black 35%);
}
.button--light {
/* 기본 색상에 흰색 80% 혼합 = 밝은 변형 */
background: color-mix(in srgb, var(--primary), white 80%);
color: var(--primary);
}
text-wrap: balance / pretty
/* 제목 텍스트 균형 잡기 */
h1, h2, h3 {
text-wrap: balance; /* 줄 길이를 균등하게 분배 */
}
/* 본문 텍스트 고아 방지 */
p {
text-wrap: pretty; /* 마지막 줄에 한 단어만 남는 것 방지 */
}
Popover API, Anchor Positioning, Scroll-Driven Animations는 모두 기존에 JavaScript 라이브러리가 필요했던 기능을 네이티브 HTML/CSS로 대체한다. 번들 크기 감소, 성능 향상, 접근성 개선이라는 세 가지 이점을 동시에 얻을 수 있으므로, 새 프로젝트에서는 적극 활용할 것을 권장한다.