멤피스 디자인 패턴 랜딩 키트, 점·물결 섹션 9개
멤피스 디자인은 1980년대 밀라노에서 시작된, 점·물결선·지그재그 같은 기하 형상을 밝은 색 위에 물들이듯 반복하는 스타일입니다. 이 글은 이미지 한 장 없이 CSS 그라디언트 타일과 도형만으로 멤피스 패턴을 재현해 코퍼레이트 랜딩 섹션 아홉 개로 묶은 키트입니다.
핀터레스트에서 "memphis pattern"으로 저장되는 화면 대부분은 일러스트 파일입니다. 일러스트를 통째로 올리면 용량이 무거워지고 색을 바꿀 때마다 다시 그려야 합니다. 여기서는 무늬 전부를 그라디언트 한 줄씩으로 만들어, 색 값만 바꾸면 패턴 전체가 따라 바뀌게 했습니다. 아래 원페이지를 스크롤하면서 어느 경계에서 무늬가 살아나는지 먼저 찾아보세요.
저 페이지를 이루는 부품 아홉 개를 떼어내 격자에 늘어놓았습니다. 순서는 화면에 무늬가 스며드는 차례를 따랐습니다. 배경이 무늬 바다가 되고, 형상이 길을 잡고, 무늬가 흐르기 시작하고, 상자에 담기고, 스티커로 증언하고, 값이 매겨지고, 섹션이 톱니로 잘리고, 띠가 흘러가고, 마지막으로 물결이 밀어낸니다.
자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip
- 01 패턴 바다 히어로
- 02 형상 배지 내비
- 03 반복 패턴 밴드
- 04 검은 외곽선 카드 격자
- 05 스티커 후기 더미
- 06 패턴 머리띠 요금제
- 07 지그재그 구분선
- 08 패턴 마퀴 띠
- 09 물결 CTA 밴드
01패턴 바다 히어로
무대 자체가 repeating-radial-gradient 한 줄로 그린 동심원 잔물결입니다. 흰 안내판은 정지해 있고 반원·삼각·십자·톱니 조각 네 개가 둘레에 떠 있는데, 주기는 전부 2초로 같고 음수 딜레이로 위상만 서로 엇갈리게 했습니다. 주기를 섞으면 2초짜리 루프가 한 바퀴 돌아올 때 한 조각이 다른 구간에 있어 화면이 튑니다. 측정에서 누적면적 2.831%, 움직인 프레임 23/23이 나왔습니다.
// 동심원 잔물결 — 원점 하나에서 퍼지는 반경 그라디언트의 반복
.stage {
background-image: repeating-radial-gradient(circle at 14px 14px, rgba(36, 31, 38, .1) 0 2.5px, transparent 3.5px 28px);
}
// 네 형상은 같은 2초, 다른 위상
.herom__shape { animation: shapeFloat 2s ease-out infinite; }
.herom__shape--half { animation-delay: -.5s; }
.herom__shape--tri { animation-delay: -1s; }
@keyframes shapeFloat {
0%, 100% { transform: translateY(0) rotate(-3deg); }
50% { transform: translateY(-12px) rotate(4deg); }
}
02형상 배지 내비
메뉴 세 칸이 각각 원·반원·삼각 배지를 담고, 활성 칸이 돌아가며 바뀝니다. 활성 교체는 steps(1, end) 타이밍으로 한 프레임에 컷하는데, 페이드로 섞으면 두 색이 반투명하게 겹친 유령 프레임이 24프레임 사이에 몇 장 끼어듭니다. 컷으로 교체하고 살아 있는 움직임은 배지가 위로 튀는 transform에만 담았습니다. 컷 덕분에 이 데모는 변화가 있는 프레임이 9/23으로 적지만, 면적과 강도는 넉넉합니다.
.navm__tab {
--on: #ff5c47; // 칸마다 자기 색
animation: tabFill 2s steps(1, end) infinite;
}
.navm__tab:nth-child(2) { animation-delay: -.6667s; }
.navm__tab:nth-child(3) { animation-delay: -1.3333s; }
@keyframes tabFill {
0%, 33.32% { background: var(--on); } // 활성 창 동안 색 유지
33.33%, 100% { background: transparent; }
}
@keyframes badgePop {
0% { transform: translateY(0); }
6%, 28% { transform: translateY(-7px); }
33.33%, 100% { transform: translateY(0); }
}
03반복 패턴 밴드
점·물결·십자 무늬 판 세 개가 나란히 서고 각 판의 무늬 바닥이 옆으로 흐릅니다. 무늬 층은 폭을 타일(24px)의 정수배인 240px로 고정하고 translateX(-120px), 즉 타일 다섯 칸만큼만 밉니다. 120px은 24px의 배수라 민 순간 무늬가 처음과 픽셀 단위로 같아져 이음매가 생기지 않습니다. 세 판은 0.22초씩 어긋나 들렸다 앉습니다. 누적면적 33.613%로 아홉 개 중 가장 넓게 움직입니다.
.bandm__fill {
position: absolute; inset: 0 auto 0 0;
width: 240px; // 타일 24px × 10 — 절반은 정확히 5타일
animation: fillFlow 2s linear infinite;
}
// 물결 리본 — 타일(24×40) 안에 띠(y 8~28)와 위·아래 가장자리 반원
.bandm__fill--wave {
background-image:
linear-gradient(to bottom, transparent 8px, #241f26 8px 28px, transparent 28px),
radial-gradient(circle 10px at 12px 8px, #241f26 0 9.5px, transparent 10px),
radial-gradient(circle 10px at 0 28px, #241f26 0 9.5px, transparent 10px);
background-size: 24px 40px;
}
@keyframes fillFlow { from { transform: translateX(0); } to { transform: translateX(-120px); } }
04검은 외곽선 카드 격자
흰 카드에 잉크 테두리 3px와 흐림 0 그림자 0 6px 0 을 함께 줬습니다. 이 조합은 네오브루탈리즘과 닮았지만 여기서는 테두리가 주역이 아니라 머리띠의 액자입니다. 세 카드가 각각 점·십자·톱니 무늬 머리띠를 이고, 0.22초씩 어긋나 들렸다 앉으면서 들 때 그림자 두께가 6px에서 10px로 늘어납니다. 누적면적 24.302%.
.gridm__card {
border: 3px solid #241f26;
box-shadow: 0 6px 0 #241f26; // 딱 붙은 그림자 = 두께
animation: cardRise 2s cubic-bezier(.2, .8, .2, 1) infinite;
}
.gridm__card:nth-child(2) { animation-delay: -.22s; }
.gridm__card:nth-child(3) { animation-delay: -.44s; }
@keyframes cardRise {
0%, 100% { transform: translateY(0) rotate(0); box-shadow: 0 6px 0 #241f26; }
45% { transform: translateY(-12px) rotate(-1.5deg); box-shadow: 0 10px 0 #241f26; }
}
05스티커 후기 더미
후기 스티커 세 장이 비스듬히 겹쳐 쌓여 있고 제 차례에 한 장씩 앞으로 나옵니다. 나오는 장은 기울기가 0도로 펴지면서 8px 들고, 차례가 지나면 제 각도로 물러납니다. 겹침 순서(z-index)는 고정하고 앞으로 나옴을 들어올림과 각도로만 표현했는데, z-index를 애니메이션하면 값이 계단으로 건너뛰어 카드가 깜빡이기 때문입니다. 움직인 프레임은 11/23.
.stickm__card {
--tilt: -7deg; // 제자리 각도
animation: toFront 2s ease-out infinite;
}
.stickm__card--two { animation-delay: -.6667s; }
.stickm__card--three { animation-delay: -1.3333s; }
@keyframes toFront {
0% { transform: rotate(var(--tilt)) translateY(0); }
6%, 28% { transform: rotate(0deg) translateY(-8px); }
34%, 100% { transform: rotate(var(--tilt)) translateY(0); }
}
06패턴 머리띠 요금제
가운데 추천 플랜만 점 무늬 머리띠와 인기 배지를 답니다. 플랜이 6px 들었다 앉는 동안 배지는 반 주기 딜레이로 반대 위상에 맥박치는데, 플랜이 가장 높을 때 배지가 가장 작고 플랜이 내려앉을 때 배지가 커집니다. 두 움직임이 엇갈리면 카드 하나가 움직이는 것보다 살아 있는 인상이 됩니다. 누적면적 4.699%, 23/23 프레임.
.pricem__plan--best { animation: bestFloat 2s ease-out infinite; }
.pricem__badge {
animation: badgePulse 2s ease-out infinite;
animation-delay: -1s; // 반 주기 = 반대 위상
}
@keyframes bestFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@keyframes badgePulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
07지그재그 구분선
두 섹션 사이에 톱니 두 줄을 넣고 서로 반대 방향으로 흘려 지퍼처럼 맞물리게 합니다. 톱니 하나는 conic-gradient 쐐기인데, 아래를 향하는 이는 꼭짓점을 타일 아래 변에 두고 from 315deg, 위를 향하는 이는 꼭짓점을 위 변에 두고 from 135deg 에 반 타일(8px) 오프셋을 줍니다. 흐름은 타일 두 칸(32px)만큼 이동합니다. 무늬가 주기적이므로 순환 지점에 이음매가 없습니다. 두 줄이 같은 타일 폭(16px)을 쓰는 것이 맞물림의 조건입니다.
.zzm__teeth--down {
height: 32px;
background: conic-gradient(from 315deg at 50% 100%, #ffcf33 0 90deg, transparent 90deg 360deg);
background-size: 16px 16px; background-repeat: repeat-x;
animation: teethFlow 2s linear infinite;
}
.zzm__teeth--up {
top: 16px;
background: conic-gradient(from 135deg at 50% 0%, #2ec4a6 0 90deg, transparent 90deg 360deg);
background-size: 16px 16px; background-repeat: repeat-x; background-position: 8px 0;
animation: teethFlow 2s linear infinite reverse; // 반대 방향
}
@keyframes teethFlow { from { transform: translateX(0); } to { transform: translateX(-32px); } }
08패턴 마퀴 띠
점·물결·십자·반원·삼각 조각 다섯 개를 한 벌로 만들고 그대로 두 벌 깔았습니다. 트랙의 실측 폭은 460px, 한 벌(조각 다섯 개와 오른쪽 여백 다섯 개)은 230px로 정확히 절반이므로 translateX(-50%) 는 230px 이동과 같고 한 바퀴가 끝나는 순간 화면이 첫 프레임과 같습니다. 조각 사이 간격을 flex gap 으로 주면 두 벌 사이에 gap이 하나 모자라 -50%가 8px씩 어긋나므로 margin-right 로 줍니다.
.marqm__track {
display: flex;
width: max-content; // 실측 460px = 한 벌 230px × 2
animation: trackFlow 2s linear infinite;
}
.marqm__tok { margin-right: 16px; } // gap 은 2N 사이 2N-1 개뿐이라 -50% 가 어긋난다
@keyframes trackFlow {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
09물결 CTA 밴드
산호색 밴드의 윗가장자리가 반원 볏의 물결입니다. 볏은 반경 12px 원을 타일 위 가장자리에 반복해 그리고, 층 폭을 타일의 20배(480px)로 잡아 translateX(-24px), 즉 한 타일만큼 흐릅니다. 밴드 안의 버튼은 8px 들었다가 바닥에 앉으면서 딱 붙은 그림자가 13px에서 5px로 줄어듭니다. 누적면적 5.556%.
.ctam__wave {
width: 480px; height: 20px; // 타일 24px × 20
background: radial-gradient(circle 12px at 12px 0, #ff5c47 0 11.5px, transparent 12px);
background-size: 24px 24px; background-repeat: repeat-x;
animation: waveDrift 2s linear infinite;
}
@keyframes waveDrift { from { transform: translateX(0); } to { transform: translateX(-24px); } }
@keyframes btnFloat {
0%, 100% { transform: translateY(-8px); box-shadow: 0 13px 0 #241f26; }
50% { transform: translateY(0); box-shadow: 0 5px 0 #241f26; }
}
tailwind.config 커스텀
이 트렌드에서 값을 한 곳에 모아야 하는 이유는 색이 아니라 무늬 타일과 두께입니다. 타일 폭이 항목마다 다르면 이음매 없이 흐리는 이동량이 제각각이 되고, 그림자가 흐려지면 멤피스의 평평한 힘이 사라집니다.
theme: {
extend: {
colors: {
base: "#fdf4ec", sheet: "#ffffff", ink: "#241f26", stone: "#5d5560",
coral: "#ff5c47", lemon: "#ffcf33", sky: "#2fa3dd",
mint: "#2ec4a6", pink: "#ff8fab",
},
borderRadius: { card: "16px", control: "12px", chip: "4px", pill: "999px" },
boxShadow: {
hard: "0 6px 0 #241f26", // 딱 붙은 그림자 = 두께
"hard-sm": "0 4px 0 #241f26",
lift: "0 10px 0 #241f26", // 들었을 때 두께가 늘어난다
},
},
},
| 역할 | 토큰 | 언제 |
|---|---|---|
| 두께 | shadow-hard |
카드·밴드가 바닥에 붙어 있을 때 |
| 들어올림 | shadow-lift |
카드가 떠 있는 동안만 |
| 테두리 | border 3px ink |
형상·카드 전부 — 이 둘은 세트다 |
바이브코딩 프롬프트
준비가 끝났으면 AI 도구에 건넬 덩어리는 아래 하나로 족합니다. 색 목록보다 무늬 만드는 법이 먼저 오는 순서가 중요합니다. 줄이지 않은 원문과 변형 세 개는 zip 안의 prompt.md 에 있습니다.
무늬는 전부 CSS 그라디언트 타일로 만든다. 이미지를 한 장도 쓰지 않는다. 점은
radial-gradient(circle at 12px 16px, #241f26 0 3px, transparent 3.5px) 를 24px
타일로 반복한다. 톱니는 conic-gradient(from 315deg at 50% 100%, 색 0 90deg,
transparent 90deg) 을 24px 타일 repeat-x 로 늘어놓는다. 무늬가 흐를 때는 이동량을
타일 폭의 정수배로만 준다. 그러면 한 바퀴 뒤 무늬가 원래 자리와 픽셀 단위로 같아진다.
카드·형상에 3px 잉크 테두리와 0 6px 0 #241f26 그림자를 함께 준다.
이 지시대로 page/index.html 을 만들어 1280·768·390px 세 폭에서 렌더한 것이 아래 그림입니다. 세 폭 모두 가로 넘침 0을 실측했습니다.

어디서 깨지는가 — 함정
가장 오래 헤맨 것은 십자 무늬였습니다. 막대 두 개를 겹치면 십자가 되니 linear-gradient(#241f26, #241f26) 두 장을 background-size: 5px 17px 로 줬는데, 렌더된 세 번째 판은 하늘색이 아니라 잉크로 통째로 칠해진 판이었습니다. 막대용 그라디언트는 타일 전체가 아니라 막대 폭만 반복하므로, 세로 막대가 5px 간격으로 화면 전체에 도배된 것입니다. 십자가 되려면 타일(24px)을 먼저 정의하고 그 안에서 transparent 9.5px, 잉크 9.5px 14.5px, transparent 14.5px 처럼 막대의 위치를 지정해야 합니다. 같은 실수가 카드 머리띠에도 숨어 있어 두 곳을 함께 고쳤습니다.
두 번째는 톱니의 방향입니다. 콘 그라디언트에서 꼭짓점을 at 50% 100% 에 두고 from 135deg 를 주면 쐐기가 아래쪽, 즉 타일 밖으로 열려 아무것도 그려지지 않습니다. 아래를 향하는 이는 from 315deg 부터 시작해야 꼭짓점에서 위로 벌어집니다. 방향이 반대여도 컴파일도 콘솔도 조용해서, 첫 렌더에서 지그재그 줄이 그저 비어 있는 것으로만 보였습니다. 세 번째로 마퀴는 앞에서 적은 대로 트랙 실측 460px가 한 벌 230px의 정확히 두 배인지를 Playwright offsetWidth 로 확인하고 넘어갔습니다. 이 세 가지를 다 손본 부품과 원페이지 전체는 압축 비밀번호 yqayt28g으로 열리는 zip 에 그대로 들어 있습니다.
접근성
멤피스 팔레트의 밝은 색은 어느 것도 흰 글자를 지탱하지 못합니다. WCAG 2.1 대비 기준의 상대 휘도 공식으로 직접 계산하면 가장 어두운 산호색 #ff5c47조차 흰 글자와 3.06:1로 본문 기준 4.5:1에 못 미칩니다. 그래서 이 키트는 색을 고르는 대신 글자색을 하나로 정했습니다. 잉크(#241f26)라면 모든 면에서 기준을 넉넉히 넘습니다.
| 앞 | 뒤 | 실측 대비 | 본문 기준 |
|---|---|---|---|
| 잉크 #241f26 | 흰 면 #ffffff | 16.17:1 | 통과 |
| 잉크 #241f26 | 크림 바탕 #fdf4ec | 14.88:1 | 통과 |
| 잉크 #241f26 | 레몬 #ffcf33 | 10.95:1 | 통과 |
| 잉크 #241f26 | 민트 #2ec4a6 | 7.36:1 | 통과 |
| 잉크 #241f26 | 산호 #ff5c47 | 5.29:1 | 통과 |
| 잉크 #241f26 | 하늘 #2fa3dd | 5.7:1 | 통과 |
| 흰 글자 | 산호 #ff5c47 | 3.06:1 | 미달 — 쓰지 않는다 |
무늬 위에 글자를 얹을 때는 반드시 흰 판을 하나 깔고 그 위에 잉크로 썼습니다. 무늬의 밝기가 칸마다 달라 대비가 글자 위치에 따라 변하는 것을 판으로 차단하는 것입니다. 움직임은 MDN prefers-reduced-motion 문서의 미디어 쿼리를 아홉 부품 전부에 넣어 동작 줄이기를 켠 방문자에게는 정지 상태만 보이게 했고, 형상 배지 내비는 움직임이 꺼진 뒤에도 두 번째 칸이 활성으로 보이는 정적 규칙을 남겼습니다. 마퀴와 물결처럼 흐르는 무늬가 멈추면 그것은 잘못이 아니라 완성된 패턴 벽지입니다.
무늬가 마음에 드셨다면 디자인 트렌드 모아보기에서 이웃 스타일들을 만나보시고, 이 사이트가 무엇을 나눠 주는 곳인지는 소개에 정리해 뒀습니다.
FAQ
멤피스 패턴과 네오브루탈리즘은 뭐가 다른가요?
둘 다 굵은 검은 테두리를 쓰지만 주역이 다릅니다. 네오브루탈리즘은 테두리와 오프셋 그림자 자체가 정체성이라 색이 두세 가지면 성립합니다. 멤피스는 테두리가 무늬의 액자일 뿐, 점·물결·톱니·기하 형상이 반복되는 패턴 채움이 주역입니다. 이 글의 04번 카드처럼 테두리는 그대로 두고 머리띠의 무늬를 빼면 멤피스가 아님을 확인할 수 있습니다.
패턴 배경 위에서 본문을 읽기 힘들지 않나요?
무늬를 본문 바로 밑에 깔지 않으면 됩니다. 이 키트의 모든 본문은 흰 판 위에 잉크로 쓰고, 무늬는 판의 바깥, 즉 무대와 머리띠와 경계에만 둡니다. 대비 실측표의 숫자는 이 원칙을 지킨 화면에서 잰 값입니다. 판 없이 무늬 위에 글자를 얹는 순간 대비는 글자가 놓인 칸의 밝기에 따라 제각각이 됩니다.
진중한 브랜드에는 너무 장난스럽지 않나요?
팔레트를 잉크와 크림 두 색으로 줄이면 멤피스의 구조는 남으면서 장난기가 빠집니다. zip 안의 변형 표의 모노 멤피스가 그 상태입니다. 반대로 형상 크기를 줄이고 타일 간격을 넓히면 무늬가 배경 소음 수준으로 가라앉으므로, 밝은 색 한두 개만 남겨도 코퍼레이트 톤을 유지할 수 있습니다.