css-native について
css-nativeは、ネイティブCSSでWebアニメーションや視覚効果を実装するクリエイティブコーディングスキルです。スクロール連動効果、View Transitions、ポップオーバーの配置などを扱い、ライブラリを選ぶ場面も説明します。
主な機能
- 01スクロール連動CSSアニメーション
- 02ページ切り替え用View Transitions
- 03ネイティブな表示・非表示トランジション
- 04ポップオーバーのアンカー配置
- 05CSSとライブラリの選択指針
活用シーン
- 01ページへのスクロール連動表示の追加
- 02非表示状態から開くダイアログのアニメーション
- 03ツールチップの配置とアニメーション
- 04CSSとアニメーションライブラリの選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ athevon/ genjutsu --skill css-nativeインストール後、Claude Code で/css-nativeを入力して読み込まれたか確認します。
詳細
バージョン依存。 以下に記載されているすべての API 名、SDK の要件、ブラウザーサポートに関する記述は、 一次情報に基づき 2026-09-08 に検証済みです。何を、いつ検証したかは
_jutsu/VERSIONS.mdをご覧ください。この日付が古い場合は、バージョン番号に基づいて作業する前に再検証してください。
CSS ネイティブ - 依存関係なしのアニメーションと視覚効果の手法
CSS ネイティブとライブラリの使い分け
| 状況 | 判断 |
|---|---|
| ページ上のアニメーションが 3 個未満 | CSS ネイティブ |
| スクロール連動の表示・視差効果 | CSS ネイティブ(animation-timeline)。必ず @supports (animation-timeline: scroll()) 内に記述し、デフォルトではコンテンツが表示されるようにします。Firefox のリリース版では未対応です |
display: none からの表示・非表示 | CSS ネイティブ(@starting-style + transition-behavior: allow-discrete) |
| ツールチップ/ポップオーバーの配置 | CSS ネイティブ(アンカーポジショニング) |
| ページ遷移(MPA または SPA) | CSS ネイティブ(View Transitions API) |
| 複雑な複数ステップのタイムライン(5 つ以上のトゥイーン) | GSAP |
| 動的リスト(件数不明)のスタッガー | CSS ネイティブ(animation-delay: calc(sibling-index() * 60ms))。2026 年 8 月から Baseline 対応です。実行時にスタッガーを中断または並べ替える必要がある場合にのみ、ライブラリを使います |
| 中断可能な物理ベースのスプリング | Framer Motion |
| SVG シェイプ間のモーフィング | GSAP MorphSVG |
経験則:@keyframes と 1 つの animation-timeline で表現できるなら、CSS のままにします。命令型の制御、シーケンスの調整、または実行時の値が必要になったら、ライブラリを使います。
スクロール連動アニメーション
スクロール進行タイムライン
コンテナーのスクロール位置に基づいてアニメーションします。
.progress-bar {
animation: grow-width linear both;
animation-timeline: scroll(root block);
}
@keyframes grow-width {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
scroll(<scroller> <axis>)- scroller:nearest|root|self、axis:block|inline|x|y- デフォルト:
scroll(nearest block)
ビュー進行タイムライン
要素がスクロールポートに出入りするのに合わせてアニメーションします。
.reveal {
animation: fade-in linear both;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(2rem); }
to { opacity: 1; transform: translateY(0); }
}
animation-range
タイムラインのどの区間がアニメーションを駆動するかを制御します。
/* Named ranges: cover | contain | entry | exit | entry-crossing | exit-crossing */
animation-range: entry 0% entry 100%; /* animate during entry only */
animation-range: contain 0% contain 100%; /* animate while fully visible */
animation-range: entry 25% exit 75%; /* custom start/end */
範囲をインタラクティブに視覚化するには、Scroll-driven Animations tool を使います。
View Transitions API
同一ドキュメント(SPA)
document.startViewTransition(() => {
// Update the DOM synchronously
updateContent();
});
/* Control the transition animation */
::view-transition-old(root) {
animation: fade-out 200ms ease-out;
}
::view-transition-new(root) {
animation: fade-in 300ms ease-in;
}
/* Named transitions for specific elements */
.hero-image { view-transition-name: hero; }
::view-transition-group(hero) {
animation-duration: 400ms;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
ドキュメント間(MPA)
/* Both pages need this */
@view-transition { navigation: auto; }
/* Outgoing page */
.card { view-transition-name: card-detail; }
/* Incoming page */
.detail-hero { view-transition-name: card-detail; }
view-transition-class(グループのスタイル設定)
.card { view-transition-class: card; }
::view-transition-group(*.card) {
animation-duration: 350ms;
animation-timing-function: var(--ease-spring);
}
@starting-style
display: none からのネイティブな表示アニメーションを実現します。JS によるタイミング調整のハックは不要です。
.dialog {
opacity: 1;
transform: translateY(0);
transition: opacity 300ms ease, transform 300ms ease,
display 300ms allow-discrete;
@starting-style {
opacity: 0;
transform: translateY(-1rem);
}
}
.dialog[hidden] {
opacity: 0;
transform: translateY(-1rem);
display: none;
}
主なルール:
transition-behavior: allow-discrete(または transition 内の省略形allow-discrete)を指定すると、displayとoverlayのトランジションが有効になります@starting-styleブロックで、要素が最初に描画されるときの「開始」状態を定義します[popover]と<dialog>を組み合わせると、アニメーションコードを一切使わずにネイティブモーダルを実現できます
アンカーポジショニング
トリガーに対するツールチップ、ポップオーバー、フローティング UI の位置を CSS ネイティブで指定します。
.trigger {
anchor-name: --my-trigger;
}
.tooltip {
position: fixed;
position-anchor: --my-trigger;
position-area: top center;
margin-bottom: 0.5rem;
/* Fallback if no space on top */
position-try-fallbacks: --bottom;
}
@position-try --bottom {
position-area: bottom center;
margin-top: 0.5rem;
}
アニメーションするツールチップには、@starting-style を組み合わせます。
.tooltip[popover]:popover-open {
opacity: 1;
transform: scale(1);
transition: opacity 150ms ease, transform 150ms ease,
display 150ms allow-discrete, overlay 150ms allow-discrete;
@starting-style {
opacity: 0;
transform: scale(0.96);
}
}
コンテナークエリーとコンテキストに応じたアニメーション
ビューポートではなく、コンポーネントのコンテナーサイズに合わせてアニメーションを調整します。
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card-content {
animation: slide-in-right 400ms var(--ease-out-expo);
}
}
@container card (max-width: 399px) {
.card-content {
animation: fade-in 300ms ease;
}
}
キーフレーム内のコンテナー相対単位:
@keyframes slide-in-right {
from { transform: translateX(10cqw); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
高度な視覚効果の手法
clip-path トランジション
.reveal {
clip-path: inset(0 100% 0 0);
transition: clip-path 600ms cubic-bezier(0.77, 0, 0.175, 1);
}
.reveal.visible {
clip-path: inset(0 0 0 0);
}
シェイプのモーフィング:関数の種類と頂点の数が一致している限り、circle()、ellipse()、polygon()、inset() の間をトランジションできます。
backdrop-filter
.glass {
background: oklch(0.98 0.01 250 / 0.6);
backdrop-filter: blur(12px) saturate(1.8);
-webkit-backdrop-filter: blur(12px) saturate(1.8); /* Safari */
}
mix-blend-mode
.overlay-text {
mix-blend-mode: difference;
color: white; /* inverts over any background */
}
メッシュグラデーション(近似表現)
.mesh {
background:
radial-gradient(at 20% 30%, oklch(0.7 0.2 310) 0%, transparent 50%),
radial-gradient(at 80% 60%, oklch(0.6 0.18 250) 0%, transparent 50%),
radial-gradient(at 50% 80%, oklch(0.75 0.15 170) 0%, transparent 50%),
oklch(0.15 0.02 280);
}
conic-gradient 効果
.spinner {
background: conic-gradient(from 0deg, transparent 0%, oklch(0.7 0.15 250) 100%);
border-radius: 50%;
mask: radial-gradient(farthest-side, transparent calc(100% - 4px), black calc(100% - 4px));
animation: spin 1s linear infinite;
}
避けること
| BAD | GOOD | 理由 |
|---|---|---|
transition: all 300ms | transition: opacity 300ms, transform 300ms | all はプロパティが変わるたびにトランジションを発生させ、予期しないアニメーションを引き起こし、ブラウザーの最適化を妨げます |
width、height、top、left をアニメーションさせる | transform、opacity、clip-path、filter をアニメーションさせる | レイアウトを発生させるプロパティは毎フレームのリフローを強制します。一方、コンポジットのみで処理されるプロパティは GPU 上で動作します |
| フォールバックなしでスクロール駆動アニメーションを使用する | @supports (animation-timeline: scroll()) { ... } | Firefox にはリリース版でのサポートがまったくありません(Nightly のみで、layout.css.scroll-driven-animations.enabled の有効化が必要)。また、Safari でのサポートは 26 でようやく導入されたため、訪問者のおよそ 6 人に 1 人には何も表示されません |
transition-behavior なしで @starting-style を使用する | display/overlay には必ず allow-discrete を組み合わせる | これがないと、display: none のトランジションは完全にスキップされます |
position-try-fallbacks なしでアンカーポジショニングを使用する | 必ずフォールバック位置を定義する | 優先位置に空きがないと、要素がビューポートの外に切れてしまいます |
スクロール駆動アニメーションで animation-fill-mode: forwards を使用する | スクロール駆動アニメーションには both を使用する | forwards は、スクロールを戻しても要素を最終状態に固定することがあります |
詳細
| 必要な情報 | 参照先 |
|---|---|
スクロール駆動アニメーション、View Transitions、@starting-style、アンカーポジショニング、コンテナークエリーのブラウザー対応表、フォールバックパターン、段階的拡張の戦略(アクセシビリティとパフォーマンスに関する注意事項も含む) | references/modern-css.md |