GODRICH
#css애니메이션#버튼#로딩#전환효과#스크롤#대시보드#실전ui#디자인트렌드

css generator 9종 — 슬라이더로 만드는 css 그림자 효과

css generator 는 CSS 값을 손으로 만지는 웹 화면입니다 — 슬라이더를 끌면 코드가 바뀝니다. 그림자·그라디언트·모서리·타이밍 같은 CSS 속성을 눈으로 맞추고, 아래 코드 상자에서 그대로 복사해 씁니다. 아홉 개를 직접 만들었고 격자에서 지금 돌아갑니다.

자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip

순서는 화면을 꾸미는 순서입니다. 카드가 떠 보이게 그림자를 깔고(01), 배경에 색 흐름을 깔고(02), 모서리를 말랑하게 다듬고(03), 사진을 모양대로 자르고(04), 글자에 테두리를 입히고(07), 글자 크기 단계를 정하고(08), 마지막에 움직임 속도를 맞춥니다(09). 그 사이에 칸 배치(06)와 색 보정(05)이 끼어 있습니다. 아홉 개 모두 값이 사용자 지정 속성 한 곳에 머물러 미리보기·손잡이·코드 상자가 같은 값을 읽는 것이 뼈대입니다. 같은 creative 기둥에서 시드로 무늬를 만드는 css 배경 패턴과 손으로 물리를 만지는 물리 시뮬레이션 만들기가 이 편의 이웃입니다.

01그림자 겹쳐 쌓기

가로·세로·번짐·퍼짐 네 축을 슬라이더로 잡고 같은 그림자를 두 겹 겹쳐 깊이를 만드는, 카드와 버튼에 들어가는 그림자 결정 도구입니다.

그림자 겹쳐 쌓기
새 창에서 열기

01 · 그림자 겹쳐 쌓기 — 측정 누적면적 10.931% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

box-shadow@property--shadow-y

네 값이 한 곳에 머무는 구조

// 네 축을 정수로 등록한다. 등록해야 키프레임에서 보간되고 counter() 로도 읽힌다
@property --shadow-x { syntax: "<integer>"; inherits: true; initial-value: 0; }
@property --shadow-y { syntax: "<integer>"; inherits: true; initial-value: 10; }
@property --shadow-blur { syntax: "<integer>"; inherits: true; initial-value: 20; }
@property --shadow-spread { syntax: "<integer>"; inherits: true; initial-value: -4; }

// 코드 상자의 숫자도 같은 속성을 카운터로 읽는다 — 화면과 코드가 한 값을 본다
.gen__v--x::after { counter-reset: v var(--shadow-x); content: counter(v); }

값이 등록된 속성 넷에만 머물러 있으니 미리보기 카드의 box-shadow·슬라이더 손잡이 위치·코드 상자의 숫자가 전부 같은 곳을 보고, 격자 미리보기는 이 속성을 그대로 키프레임으로 움직여 누적면적 10.93%·강도 110.3·움직인 프레임 23/23 로 측정됐습니다.

두 겹으로 깊이를 만드는 법

box-shadow:
  calc(var(--shadow-x) * 1px) calc(var(--shadow-y) * 1px) calc(var(--shadow-blur) * 1px) calc(var(--shadow-spread) * 1px) rgba(23, 20, 26, .34),
  calc(var(--shadow-x) * .5px) calc(var(--shadow-y) * .5px) calc(var(--shadow-blur) * .5px) 0 rgba(23, 20, 26, .22);

아래 겹은 거리와 번짐을 절반으로 줄인 같은 그림자라, 한 겹만 쓸 때보다 값을 키워도 가장자리가 지저분해지지 않아 디자인 시스템의 그림자 단계를 정할 때 기준으로 씁니다.

02각도와 정지점 그라디언트

각도 슬라이더가 linear-gradient 의 방향을 돌리고 정지점 슬라이더 두 개가 색이 갈리는 지점을 밀고 당기는, 히어로 배경과 버튼 채움을 만드는 도구입니다.

각도와 정지점 그라디언트
새 창에서 열기

02 · 각도와 정지점 그라디언트 — 측정 누적면적 8.818% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

linear-gradient--grad-angle--grad-stop-b

각도 하나가 방향을 정한다

// 각도는 정수 하나. calc 이 도 단위를 붙이고 정지점 둘이 색 경계를 민다
.gen__preview {
  background: linear-gradient(
    calc(var(--grad-angle) * 1deg),
    $subject-blue calc(var(--grad-stop-a) * 1%),
    $subject-pink calc(var(--grad-stop-b) * 1%)
  );
}

각도는 --grad-angle 정수 하나이고 calc 가 도 단위를 붙이는데, 45도에서 315도로 도는 동안 색이 통째로 밀리는 면적이 넓어 밝기 변화가 크게 잡혀 측정은 누적면적 8.82%·강도 70.1·움직인 프레임 23/23 이 나왔습니다.

css 텍스트 그라디언트에도 같은 값이 쓰인다

.gen__row:nth-child(1) .gen__thumb { --pct: calc(var(--grad-angle) / 360 * 100); }
.gen__row:nth-child(2) .gen__thumb { --pct: var(--grad-stop-a); }
.gen__row:nth-child(3) .gen__thumb { --pct: var(--grad-stop-b); }

손잡이 위치도 같은 속성에서 계산하고, 갈림점 A 를 0 근처로, B 를 100 근처로 밀면 두 색이 넓게 섞이고 두 값을 가까이 붙이면 선에 가까운 경계가 됩니다 — 배경이 아니라 글자 채움에 쓸 때도 같은 감각입니다.

03여덟 손잡이 모서리

모서리 네 곳의 가로 반경과 공통 세로 반경을 따로 잡아 슬래시 문법으로 적는, 말랑한 블롭 모양을 만드는 도구입니다.

여덟 손잡이 모서리
새 창에서 열기

03 · 여덟 손잡이 모서리 — 측정 누적면적 5.821% · 움직인 프레임 22/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

border-radius--r-tl--r-vy

모서리별 longhand 가 슬래시 문법과 같다

// 모서리별 longhand 두 값(가로 세로)은 슬래시 문법과 동치다 — 값이 속성마다 붙어 있어
// 어느 모서리가 움직이는지 읽기도 쉽다
border-top-left-radius: calc(var(--r-tl) * 1px) calc(var(--r-vy) * 1px);
border-top-right-radius: calc(var(--r-tr) * 1px) calc(var(--r-vy) * 1px);
border-bottom-right-radius: calc(var(--r-br) * 1px) calc(var(--r-vy) * 1px);
border-bottom-left-radius: calc(var(--r-bl) * 1px) calc(var(--r-vy) * 1px);

오른쪽 위와 왼쪽 아래를 크게, 왼쪽 위와 오른쪽 아래를 작게 하면 물방울처럼 기울어진 모양이 되는데, 코드 상자는 border-radius: 12px 48px 12px 48px / 28px 꼴의 짧은 문법으로 내놓고, 미리보기는 위처럼 모서리별로 풀어 둡니다.

모서리 점이 값을 따라 붙는다

.gen__dot--tl { left: calc(var(--r-tl) * 1px); top: calc(var(--r-vy) * 1px); }
.gen__dot--tr { right: calc(var(--r-tr) * 1px); top: calc(var(--r-vy) * 1px); }
.gen__dot--br { right: calc(var(--r-br) * 1px); bottom: calc(var(--r-vy) * 1px); }
.gen__dot--bl { left: calc(var(--r-bl) * 1px); bottom: calc(var(--r-vy) * 1px); }

검은 점 네 개가 반경값만큼 안쪽으로 붙어 어느 모서리가 움직이는지 보여 주고, 측정은 누적면적 5.82%·강도 133.6·움직인 프레임 22/23 입니다.

04다각형 꼭짓점 자르기

여섯 꼭짓점의 반경을 슬라이더로 끌면 그 자리에서 사진이 잘리고 좌표 목록이 그대로 clip-path 코드가 되는 도구입니다.

다각형 꼭짓점 자르기
새 창에서 열기

04 · 다각형 꼭짓점 자르기 — 측정 누적면적 6.233% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

clip-pathpolygonpointerdown

CSS 와 JS 가 같은 계수표를 공유한다

// 여섯 꼭짓점은 60도 간격 고정. 각 꼭짓점의 (dx, dy) 계수표 — CSS 와 JS 가 같은 표를 공유한다
// (60도 간격 여섯 방향의 단위원 좌표, 소수 셋째에서 반올림). 중심 50% 에서 계수만큼 뻗는다
var DIRS = [
  [0, -1], [0.87, -0.5], [0.87, 0.5], [0, 1], [-0.87, 0.5], [-0.87, -0.5]
];

미리보기의 잘린 모양은 SCSS 의 calc 가 그리고, 복사 문자열은 JS 가 만드는데 둘이 같은 계수표를 쓰므로 화면과 복사한 코드가 어긋나지 않고, 꼭짓점 반경을 엇갈리게 움직이면 육각형이 별처럼 숨쉬어 측정은 누적면적 6.23%·강도 127.8·움직인 프레임 23/23 입니다.

세로 계수로 납작하게 누른다

.gen__preview {
  box-sizing: border-box; width: 116px; height: 72px;
  background: $subject-blue;
  clip-path: polygon(
    calc(50% + 0 * var(--v0) * 1%) calc(50% + -1 * var(--v0) * 0.6 * 1%),
    calc(50% + 0.87 * var(--v1) * 1%) calc(50% + -0.5 * var(--v1) * 0.6 * 1%),
    calc(50% + 0.87 * var(--v2) * 1%) calc(50% + 0.5 * var(--v2) * 0.6 * 1%)
  );
}

세로 좌표에 0.6 을 곱해 미리보기 상자 비율에 맞추고(여섯 꼭짓점 전부 같은 계수), 점선 테두리는 잘리기 전 원래 크기를 보여 주어 어디가 잘렸는지 읽게 합니다.

05필터 체인 프리셋

밝기·대비·채도·블러를 한 줄에 이어 적고 프리셋 단추가 네 값을 한꺼번에 옮기는, 사진 갤러리 톤을 정하는 도구입니다.

필터 체인 프리셋
새 창에서 열기

05 · 필터 체인 프리셋 — 측정 누적면적 9.446% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

filtersaturatedata-preset

순서가 바뀌면 결과가 달라진다

filter:
  brightness(calc(var(--f-bri) * 1%))
  contrast(calc(var(--f-con) * 1%))
  saturate(calc(var(--f-sat) * 1%))
  blur(calc(var(--f-blur) * 1px));

필터는 왼쪽부터 순서대로 적용되므로 blur 를 앞에 두면 흐려진 위에 대비가 걸려 결과가 달라지는데, brightness 부터 blur 까지가 흔히 쓰이는 정석이고, 채도가 0 이 되는 순간을 잡은 측정은 누적면적 9.45%·강도 96.3·움직인 프레임 23/23 입니다.

프리셋은 네 값을 한 번에 넣는다

// 프리셋 단추 — 네 값을 한꺼번에 속성에 넣는다. 단추가 값의 출처라는 걸 data-preset 으로 보여 준다
Array.prototype.forEach.call(gen.querySelectorAll('.gen__preset'), function (btn) {
  btn.addEventListener('click', function () {
    gen.classList.remove('is-demo');
    btn.dataset.preset.split(',').forEach(function (val, i) {
      gen.style.setProperty(VARS[i], val);
      ranges[i].value = val;
    });
  });
});

data-preset 속성에 네 값이 쉼표로 들어 있어 단추 하나가 곧 저장된 값 묶음이고, 직접 조작 실측에서 단추를 눌렀을 때 슬라이더 넷과 코드 상자가 한꺼번에 바뀌는 것을 확인했습니다.

06격자 열과 간격

최소 폭과 간격을 슬라이더로 잡으면 repeat() 문법이 그대로 적히고 auto-fit 이 칸 수를 화면에 맞춰 정하는 반응형 격자 도구입니다.

격자 열과 간격
새 창에서 열기

06 · 격자 열과 간격 — 측정 누적면적 10.212% · 움직인 프레임 22/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

grid-template-columnsrepeatminmax

열 개수 슬라이더가 없는 이유

.gen__preview {
  display: grid; align-content: start;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--g-min) * 0.32px), 1fr));
  gap: 0;
  overflow: hidden;
}

auto-fit 과 minmax 는 칸 수를 직접 정하지 않고 최소 폭에 맡기는 반응형 격자여서 슬라이더는 최소 폭과 간격만 잡고 칸 수는 화면 폭이 결정하는데, 최소 폭이 커지면 칸이 여러 줄로 접히고 작아지면 한 줄로 펴져 측정은 누적면적 10.21%·강도 169.7·움직인 프레임 22/23 입니다.

칸 간격은 칸 자신의 테두리로

// 칸 간격은 gap 이 아니라 투명 border 로 준다(297 선례) — 칸 자신의 일부라
// 값이 소수 px 이 되어도 격자 눈금 규칙을 어기지 않는다. 좌우 상하 반씩 나눠 붙인다
.gen__cell {
  height: 20px; border-radius: $r-xs; box-sizing: border-box;
  border: calc(var(--g-gap) * 0.32px / 2) solid transparent;
  background-clip: padding-box;
}

간격값을 칸마다 투명 테두리로 나눠 붙이면 간격이 소수 픽셀이 되어도 화면이 고르게 유지되고, 미리보기 계수 0.32 는 상자가 실제 사용 폭보다 작기 때문이며 칸 수 변화는 그대로 보입니다.

07글자 테두리 두께

테두리 두께와 채움 불투명도를 슬라이더로 잡고 속을 비우면 스티커 같은 글자가 되는, 사진 위 큰 제목을 위한 도구입니다.

글자 테두리 두께
새 창에서 열기

07 · 글자 테두리 두께 — 측정 누적면적 2.958% · 움직인 프레임 22/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

-webkit-text-stroketext-shadowpaint-order

스트로크를 안쪽에 그리는 paint-order

.gen__word {
  color: rgba(255, 247, 230, calc(var(--t-fill) * 1%));
  -webkit-text-stroke: calc(var(--t-sw) * 1px) $subject-ink;
  paint-order: stroke fill;
  font-family: $mono; font-weight: 900; font-size: 44px; line-height: 1;
}

paint-order: stroke fill 은 SVG 관례를 CSS 가 물려받은 속성으로 스트로크를 글자 안쪽에 그려 얇은 글자가 뭉개지지 않게 하고, 채움을 0 으로 내리면 속이 빈 글자가 되어 측정은 누적면적 2.96%·강도 123.8·움직인 프레임 22/23 입니다.

오래된 브라우저용 그림자 대체

// 네 방향(대각선 포함 여덟 방향) 같은 오프셋의 그림자로 테두리를 흉내 낸다
var shades = [];
for (var dx = -1; dx <= 1; dx++) {
  for (var dy = -1; dy <= 1; dy++) {
    if (dx === 0 && dy === 0) continue;
    shades.push((dx * sw) + 'px ' + (dy * sw) + 'px 0 #17141a');
  }
}
return 'text-shadow: ' + shades.join(', ') + ';';

-webkit-text-stroke 가 없는 환경에서는 여덟 방향 같은 오프셋의 text-shadow 로 같은 굵기를 흉내 내는데, 복사 단추를 누르면 두 코드가 함께 들어가므로 붙여 넣은 곳에서 골라 쓰면 됩니다.

08타이포 배율 사다리

기준 크기와 배율 하나로 여섯 단계를 계산해 사다리로 보여 주고 그 값이 사용자 지정 속성 목록으로 떨어지는 글자 크기 결정 도구입니다.

타이포 배율 사다리
새 창에서 열기

08 · 타이포 배율 사다리 — 측정 누적면적 42.674% · 움직인 프레임 21/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

clampMath.pow--step-3

곱의 개수만 단계마다 다르다

.gen__step--1 { font-size: calc(var(--s-base) * 0.6px); }
.gen__step--2 { font-size: calc(var(--s-base) * 0.6px * var(--s-ratio) * 0.01); }
.gen__step--3 { font-size: calc(var(--s-base) * 0.6px * var(--s-ratio) * var(--s-ratio) * 0.0001); }
.gen__step--4 { font-size: calc(var(--s-base) * 0.6px * var(--s-ratio) * var(--s-ratio) * var(--s-ratio) * 0.000001); }

CSS 의 calc 는 거듭제곱이 없어서 배율을 곱할 때마다 한 번 더 쓰는데, 식은 하나이고 곱의 개수만 단계마다 달라서 값 하나가 사다리 전체를 숨쉬게 하고 여섯 줄이 전부 크기를 바꾸니 측정은 누적면적 42.67%·강도 153.5·움직인 프레임 21/23 입니다.

복사되는 쪽은 rem 목록이다

// 기준 크기와 배율 — 다섯 단계 사다리가 calc 곱으로 저절로 따라온다(scss 의 calc 랑 같은 식).
// 속성은 --s-base(정수 px) 와 --s-ratio(백분율 정수) 둘뿐이다
var base = readVar('--s-base');
var ratio = readVar('--s-ratio') / 100;
var lines = [];
for (var i = 1; i <= 6; i++) {
  lines.push('--step-' + i + ': ' + (Math.round(base * Math.pow(ratio, i - 1) * 100) / 100 / 16).toFixed(3) + 'rem;');
}

복사 단추를 누르면 --step-1 부터 --step-6 까지 rem 값이 :root 묶음으로 나오고, 미리보기의 0.6 계수는 여섯 단계가 무대 안에 들어가게 하는 표시 배율일 뿐 단계 사이 비율은 그대로입니다.

09타이밍 값 미리보기

길이·지연·반복을 슬라이더로 잡으면 옆의 공이 그 값으로 바로 다시 뛰는 애니메이션 속도 결정 도구입니다.

타이밍 값 미리보기
새 창에서 열기

09 · 타이밍 값 미리보기 — 측정 누적면적 3.245% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

animation-durationanimation-delaygetAnimations

단축이 아니라 낱개 속성을 쓰는 이유

// 낱개 속성 — 단축이 delay 를 리셋하는 함정을 피한다
animation-name: ballRun;
animation-duration: calc(var(--a-dur) * 1ms);
animation-delay: calc(var(--a-delay) * 1ms);
animation-iteration-count: var(--a-iter);
animation-timing-function: $easing;
animation-direction: alternate;
animation-fill-mode: both;

animation: 단축은 자리에 없는 하위 속성을 초기값으로 되돌려 지연을 따로 두는 순간 그걸 지우므로, 이 도구는 처음부터 낱개 속성으로 쓰고, 값이 오가는 동안 공은 계속 그 값대로 왕복해 측정은 누적면적 3.25%·강도 146.0·움직인 프레임 23/23 입니다.

값을 바꾸면 공을 다시 띄운다

// 값이 바뀌면 공의 애니메이션을 새로 띄운다 — getAnimations 으로 잡아 시계를 0 에 되돌린다
function restartBall() {
  ball.getAnimations().forEach(function (a) {
    a.cancel();
  });
  // cancel 뒤 같은 이름의 애니메이션이 다시 만들어진다 — CSS 시트가 그대로 있으므로
}

슬라이더를 끌면 getAnimations() 로 잡은 애니메이션을 취소하는데, CSS 시트가 그대로 있으므로 같은 이름의 애니메이션이 다시 만들어져 공이 새 길이값으로 0 부터 뜁니다.

css 박스 그림자는 슬라이더 몇 개로 만드나?

css 박스 그림자를 결정하는 값은 가로·세로·번짐·퍼짐·색 다섯 개이지만 색은 디자인 시스템이 정해 두는 경우가 많아 이 도구는 네 슬라이더로 시작합니다. 그림자를 잡을 때 눈으로 먼저 보고 값을 읽는 순서가 중요합니다 — 감으로 16px 를 찍는 것보다 슬라이더로 2px 간격을 오가며 카드가 뜨는 지점을 찾는 편이 빠릅니다. 두 겹 쌓기의 아래 겹은 절반값이므로 실제 조절 축은 넷으로 충분합니다.

아홉 개의 조절값과 내놓는 코드

항목 조절값 내놓는 코드
01 그림자 가로·세로·번짐·퍼짐 box-shadow 두 겹
02 그라디언트 각도·갈림 A·갈림 B linear-gradient
03 모서리 네 모서리 반경·세로 반경 border-radius 슬래시
04 다각형 여섯 꼭짓점 반경 clip-path: polygon
05 필터 밝기·대비·채도·블러 filter 체인
06 격자 최소 폭·간격 grid-template-columns + gap
07 글자 테두리 두께·채움 -webkit-text-stroke + color
08 타이포 기준·배율 --step-1 부터 --step-6
09 타이밍 길이·지연·반복 animation- 낱개 속성

값은 전부 사용자 지정 속성으로 흐르므로, 한 항목의 미리보기·손잡이·코드 상자가 어긋날 수 없습니다. 직접 조작 실측에서도 아홉 항목 모두 슬라이더 이동에 값·미리보기·코드가 같이 움직였습니다(run/073/_조작실측.json).

어디서 깨지는가 — 함정

가장 먼저 깨진 곳은 320px 폭이었습니다. 데스크톱 폭(480px) 에서는 멀쩡하던 아홉 개 중 일곱 개가 폰 폭에서 본문이 331~444px 까지 밀려 나갔습니다. 원인은 슬라이더의 원래 폭이었습니다 — input[type=range] 는 자기 최소 크기를 가지고, 그 최소 크기가 격자 트랙과 카드를 그대로 밀어낸 것입니다. 고친 방법은 세 가지입니다: 트랙을 repeat(2, minmax(0, 1fr)) 로 최솟값을 0 으로 내리고, 슬라이더 자리와 입력에 min-width: 0 을 주고, 카드 자체도 무대 격자의 항목이라 그 자동 최소폭을 끊었습니다. 고친 뒤 아홉 개 전부 본문 320×200 에 들어갑니다.

두 번째는 코드 상자의 숫자였습니다. 값이 CSS 카운터로 그려지는 자리는 textContent 로 읽히지 않고, 계산값을 물어보면 counter(v) 라는 문자열이 그대로 돌아옵니다. 조작 실측 프로브는 결국 코드 상자를 찍은 픽셀 해시로 숫자가 바뀌는 것을 증명했습니다 — 눈에 보이는 것과 기계가 읽는 것이 다른 전형입니다. 세 번째는 클립보드였습니다. iframe 안에서 navigator.clipboard.writeText 는 거부된 프로미스를 돌려주는데 try/catch 만으로는 잡히지 않아 .catch 로 잡아, 화면 밖 textarea 를 선택해 복사하는 방식으로 떨어뜨렸습니다. 아홉 파일 전부 같은 패턴입니다. 이 파일 아홉 개의 압축 비밀번호는 ycejvu79 이고, 풀면 vanilla 판과 React 판이 함께 들어 있습니다.

접근성

prefers-reduced-motion 이 켜진 환경에서는 격자 미리보기의 값 순환이 멈추고 09 의 공도 시작 위치에 멈춥니다 — 요소가 사라지지는 않습니다. 슬라이더는 네이티브 input[type=range] 라 화살표 키로 값이 오가고(조작 실측도 키보드로 했습니다), 라벨은 aria-label 로 붙어 있으며 초점 링은 focus-visible 로 뚜렷합니다. 복사 단추를 누른 뒤에는 글자가 짧게 바뀌어 결과를 눈으로 확인할 수 있습니다.

FAQ

css 그림자 효과를 복사하면 두 줄이 같이 들어오는데 한 줄만 써도 되나요?

됩니다. 첫 줄이 주 그림자이고 둘째 줄이 절반값의 받침 그림자입니다. 카드 하나에는 첫 줄만으로 충분하고, 떠 있는 느낌을 강조하고 싶을 때 둘을 함께 쓰세요.

값이 이상한 단위로 보이는데 고쳐야 하나요?

아니요. 코드 상자의 숫자는 화면과 같은 사용자 지정 속성을 읽는 카운터라 내놓는 문자열과 같은 값입니다. 복사 단추를 누르면 JS 가 만든 온전한 코드가 들어가므로 그대로 붙여 쓰면 됩니다.

css 리니어 그라디언트 말고 conic 이나 radial 로 바꾸고 싶으면요?

02 의 코드에서 linear-gradient(각도, 색 정지점) 을 radial-gradient(원점, 색 정지점) 이나 conic-gradient(시작각, 색 정지점) 으로 이름만 바꾸면 됩니다. 정지점 문법은 셋이 같아 갈림값을 그대로 옮겨 쓸 수 있습니다.

참고

압축 비밀번호를 입력하세요

비밀번호는 이 글 본문 안에 있습니다. 읽다 보면 나옵니다.