안녕하세요, 디자인 엔지니어 올리브예요. 멋진 사이트 분석 2편이에요.
EALARA의 호버·스크롤 인터랙션 4가지는 모두 CSS 몇 줄로 따라 만들 수 있어요. 메뉴와 버튼은 ::before 배경이 커지는 호버, 작업물 카드는 position: sticky, 저널 카드는 스크롤 값으로 가로 위치를 옮기는 짧은 스크립트예요. 아래 데모는 이 블로그 색으로 바꿔서 직접 만들어 본 거예요. 마우스를 올리거나 스크롤해 보세요.
1편에서는 EALARA의 색, 큰 제목, 섹션 틀을 봤어요. 다시 들여다보니 제 눈에 오래 남은 건 작은 움직임이었어요. 그중 네 가지를 골라 원본이 어떻게 움직이는지 보고, 똑같이 만들어 봤어요.
| 구분 | 원본에서 본 것 | 만드는 법 |
|---|---|---|
| 메뉴 호버 | 글자 아래 1px 점이 배경으로 차올라요 | ::before 크기 전환 |
| 버튼 호버 | 화살표 원이 버튼 전체로 퍼지고 화살표가 꺾여요 | ::before 너비 전환 + 회전 |
| 작업물 카드 | 다음 카드가 올라오며 앞 카드를 덮어요 | position: sticky |
| 저널 카드 | 스크롤하면 카드가 오른쪽에서 들어와요 | 스크롤 값 → translateX |
1. 메뉴 호버는 어떻게 움직이나요?
원본은 어떻게 움직이나요?
메뉴 링크마다 옅은 알약이 깔려 있어요. 마우스를 올리면 글자 아래 가운데에 1px짜리 점이 생기고, 그 점이 0.4초 동안 일정한 속도로 커지면서 글자 뒤를 채워요. 글자 색도 같은 0.4초 동안 바뀌고, 마우스를 떼면 똑같은 속도로 다시 점으로 줄어들어요. 보통 메뉴 호버는 배경색이 한 번에 바뀌는데, 여기서는 옅은 알약 안을 아래에서부터 '채워요'.

따라 만들면?
메뉴 글자에 마우스를 올려 보세요. 속도와 곡선은 원본을 프레임 단위로 재서 그대로 맞췄어요.
<style>
.stage { display: grid; place-items: center; height: 100vh; background: #F4F6F4; }
.nav { display: flex; gap: 8px; }
/* 링크마다 옅은 알약 (원본: 검정 10% + 배경 흐림) */
.nav a {
position: relative; isolation: isolate; overflow: hidden;
padding: 8px 24px; border-radius: 38px;
background: rgba(10, 31, 14, .06); backdrop-filter: blur(40px);
color: #0A1F0E; font-size: 15px; font-weight: 500; text-decoration: none;
transition: color .4s linear;
}
/* 글자 아래 가운데 1px 점 → 링크 전체로 차오른다 (원본: 0.4초, linear) */
.nav a::before {
content: ""; position: absolute; z-index: -1;
left: 50%; bottom: -1px; width: 1px; height: 1px; /* 쉴 때는 알약 바로 아래라 잘려서 안 보인다 */
border-radius: 16px; background: #00A30F;
transform: translateX(-50%);
transition: width .4s linear, height .4s linear;
}
.nav a:hover { color: #fff; }
.nav a:hover::before { width: calc(100% + 2px); height: calc(100% + 2px); }
@media (max-width: 420px) { .nav { gap: 4px; } .nav a { padding: 8px 12px; font-size: 13px; } }
</style>
<div class="stage">
<nav class="nav">
<a href="#">About</a><a href="#">Services</a><a href="#">Works</a><a href="#">Blog</a>
</nav>
</div>
- 배경은
::before하나: 처음엔 1×1px 점, 호버하면 링크 크기(100%×100%)까지 커져요. bottom: -1px+left: 50%: 점을 알약 바로 아래 가운데에 숨겨 두면, 호버할 때 위와 양옆으로 차올라요.- 링크마다 옅은 알약 +
overflow: hidden: 차오르는 배경은 둥글기 16px이지만, 링크(둥글기 38px)가 잘라 줘서 끝 모양은 완전한 알약이 돼요. linear0.4초: 원본은 가속 없이 일정한 속도예요. 그래서 커지는 동안 작은 알약 모양이 눈에 보여요.
2. 버튼 호버는 어떻게 움직이나요?
원본은 어떻게 움직이나요?
히어로의 버튼 두 개는 오른쪽에 화살표가 든 동그라미가 있어요. 마우스를 올리면 이 동그라미가 왼쪽으로 늘어나 버튼 전체를 채우고, 색이 뒤집히고, 화살표가 → 에서 ↗ 로 꺾여요. 흰 버튼은 검게, 투명한 버튼은 하얗게 바뀌어서 두 버튼이 서로 반대로 움직여요.

따라 만들면?
두 버튼에 차례로 마우스를 올려 보세요.
<style>
.stage { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; align-items: center; height: 100vh; padding: 16px; background: #F4F6F4; }
.btn {
--fill: #00A30F; --ink: #fff;
position: relative; isolation: isolate; overflow: hidden;
display: inline-flex; align-items: center; gap: 12px;
padding: 5px 5px 5px 22px; border-radius: 999px;
border: 1px solid #E6E9E6; background: #fff; color: #0A1F0E;
font-size: 15px; font-weight: 600; text-decoration: none;
transition: color .45s;
}
.btn.alt { --fill: #fff; --ink: #00A30F; border-color: #00A30F; background: #00A30F; color: #fff; }
/* 오른쪽 동그라미가 버튼 전체로 퍼진다 */
.btn::before {
content: ""; position: absolute; z-index: -1;
top: 5px; right: 5px; bottom: 5px; width: 40px;
border-radius: 999px; background: var(--fill);
transition: width .45s cubic-bezier(.2,.8,.2,1);
}
.btn:hover { color: var(--ink); }
.btn:hover::before { width: calc(100% - 10px); }
.icon { display: grid; place-items: center; width: 40px; height: 40px; color: var(--ink); transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.btn:hover .icon { transform: rotate(-45deg); }
</style>
<div class="stage">
<a class="btn" href="#">View Selected Work
<span class="icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</a>
<a class="btn alt" href="#">Start a project
<span class="icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</a>
</div>
- 동그라미 =
::before: 오른쪽에 붙인 채width만 40px → 100%로 늘려요. 그래서 오른쪽에서 왼쪽으로 퍼져요. - 색 뒤집기는 변수 두 개:
--fill(퍼지는 색)과--ink(바뀐 글자 색)만 바꾸면 반대 버튼이 돼요. - 화살표는
rotate(-45deg): → 가 ↗ 로 꺾이면서 "누르면 이동해요"라는 느낌을 줘요.
3. 작업물 카드는 어떻게 바뀌나요?
원본은 어떻게 움직이나요?
Selected Works에서 스크롤을 내리면 다음 사진 카드가 아래에서 올라와 앞 카드를 덮어요. 앞 카드는 위쪽 끝만 살짝 남아서 카드가 겹겹이 쌓이는 것처럼 보여요. 카드가 바뀔 때마다 Fashion → Portrait → Editorial → Campaign 라벨도 같이 바뀌어서, 넘겨 보는 재미가 있어요.

따라 만들면?
상자 안에서 스크롤해 보세요.
<style>
body { background: #F4F6F4; }
.hint { position: sticky; top: 0; z-index: 10; margin: 0; padding: 12px; text-align: center; font-size: 13px; color: #6B7F6E; background: #F4F6F4; }
.stack { max-width: 460px; margin: 0 auto; padding: 0 20px 160px; }
.card {
position: sticky; top: calc(56px + var(--i) * 12px);
height: 280px; margin-bottom: 48px; padding: 18px;
display: flex; flex-direction: column; justify-content: space-between;
border-radius: 16px; box-shadow: 0 -10px 24px rgba(10, 31, 14, .10);
}
.card b { font-size: 40px; line-height: 1; }
.label { align-self: center; padding: 6px 14px; border-radius: 999px; background: #fff; color: #0A1F0E; font-size: 13px; font-weight: 600; }
</style>
<p class="hint">↓ 스크롤해 보세요</p>
<div class="stack">
<div class="card" style="--i: 0; background: #00A30F; color: #fff;"><b>01</b><span class="label">Fashion</span></div>
<div class="card" style="--i: 1; background: #E5F2E7; color: #007A0B;"><b>02</b><span class="label">Portrait</span></div>
<div class="card" style="--i: 2; background: #007A0B; color: #fff;"><b>03</b><span class="label">Editorial</span></div>
<div class="card" style="--i: 3; background: #0A1F0E; color: #fff;"><b>04</b><span class="label">Campaign</span></div>
</div>
- 핵심은
position: sticky한 줄: 카드마다 화면 위쪽에 붙어 있고, 뒤에 오는 카드가 그 위를 덮어요. top을 카드마다 12px씩 더 내리기: 앞 카드의 위쪽 끝이 남아서 '쌓인' 느낌이 나요.- 위로 드리운 그림자:
box-shadow를 위쪽(-10px)으로 줘서 올라오는 카드가 앞 카드 위에 떠 보여요.
4. 저널 카드는 어떻게 들어오나요?
원본은 어떻게 움직이나요?
From The Journal 섹션에서는 세로로 긴 카드들이 한 줄로 놓여 있어요. 스크롤을 내리면 카드 줄이 왼쪽으로 밀려 가고, 오른쪽에서 새 카드가 들어와요. 스크롤을 멈추면 카드도 멈춰요. 세로 스크롤로 가로 움직임을 만드니, 글 목록인데도 갤러리를 넘기는 기분이 들어요.

따라 만들면?
상자 안에서 스크롤해 보세요. 오른쪽에서 들어오는 카드는 아래에서 살짝 올라오게 해서, 제가 원본에서 느낀 '올라오는' 느낌을 조금 더 살렸어요.
<style>
body { background: #F4F6F4; }
.scroller { height: 400vh; }
.sticky { position: sticky; top: 0; height: 100vh; overflow: hidden; display: flex; flex-direction: column; justify-content: center; gap: 18px; }
.title { margin: 0; text-align: center; font-size: 18px; font-weight: 700; }
.title small { display: block; margin-top: 4px; font-size: 12px; font-weight: 400; color: #6B7F6E; }
.track { display: flex; gap: 14px; width: max-content; padding-left: 20px; will-change: transform; }
.card { flex: none; width: 160px; overflow: hidden; background: #fff; border: 1px solid #E6E9E6; border-radius: 12px; will-change: transform, opacity; }
.thumb { height: 170px; }
.meta { padding: 10px 12px 12px; font-size: 13px; }
.meta b { display: block; margin-bottom: 2px; }
.meta span { color: #6B7F6E; font-size: 11px; }
</style>
<div class="scroller">
<div class="sticky">
<p class="title">Notes from the blog<small>↓ 스크롤해 보세요</small></p>
<div class="track">
<div class="card"><div class="thumb" style="background: #00A30F"></div><div class="meta"><b>Chasing Light</b><span>SEP 18</span></div></div>
<div class="card"><div class="thumb" style="background: #E5F2E7"></div><div class="meta"><b>The Art of Seeing</b><span>SEP 12</span></div></div>
<div class="card"><div class="thumb" style="background: #007A0B"></div><div class="meta"><b>Frames in Motion</b><span>SEP 05</span></div></div>
<div class="card"><div class="thumb" style="background: #0A1F0E"></div><div class="meta"><b>Quiet Moments</b><span>AUG 29</span></div></div>
</div>
</div>
</div>
<script>
const track = document.querySelector('.track');
// 카드 묶음을 한 번 더 붙여서 끝없이 이어지게 한다
const count = track.children.length;
[...track.children].forEach(card => track.appendChild(card.cloneNode(true)));
const cards = [...track.children];
function update() {
const loop = cards[count].offsetLeft - cards[0].offsetLeft; // 카드 묶음 하나의 폭
const x = (scrollY * 0.8) % loop;
track.style.transform = `translateX(${-x}px)`;
// 화면 오른쪽에 있을수록 아래에 있다가, 왼쪽으로 오면서 올라온다
cards.forEach(card => {
const left = card.getBoundingClientRect().left;
const t = Math.min(1, Math.max(0, (left - innerWidth * 0.5) / (innerWidth * 0.5)));
card.style.transform = `translateY(${t * 48}px)`;
card.style.opacity = 1 - t * 0.5;
});
}
addEventListener('scroll', update, { passive: true });
addEventListener('resize', update);
update();
</script>
- 세로 스크롤 → 가로 이동: 섹션을
sticky로 붙여 두고,scrollY만큼 카드 줄을 왼쪽으로 옮겨요. - 끝없이 이어지기: 카드 묶음을 한 번 더 복사해 두고, 묶음 하나의 폭으로 나눈 나머지(
%)만큼만 옮겨요. - 올라오는 느낌: 카드가 화면 오른쪽에 있을수록 아래로 내리고 흐리게 해서, 왼쪽으로 오며 제자리로 올라와요.
올리브의 한마디
1편을 쓸 때는 색과 큰 제목만 보였는데, 다시 보니 이 사이트를 기억에 남게 만든 건 이런 작은 움직임이었어요. 그런데 직접 만들어 보니 대부분 CSS 속성 한두 개를 전환하는 것이 전부였어요. 메뉴와 버튼은 ::before 크기를 바꾸고, 카드는 sticky로 붙여 두는 정도예요.
어려운 기술보다 어디서 시작해서 어디로 커지는지를 정하는 게 디테일의 차이였어요. 점이 배경으로 차오르고, 동그라미가 버튼으로 퍼지는 것처럼요. 저도 이 블로그 버튼에 하나쯤 가져와 볼까 해요.
오늘도 읽어 주셔서 고마워요. 다음 글에서 만나요! 🌿