GODRICH

フッター デザイン コピペで終わるパターン9選

フッター デザイン コピペで探しているのは、ページの一番下でサイト全体を締めくくる区画のひな形です。ここではリンクの一覧で終わらせない九つのフッターを、そのまま貼れるHTMLとSCSSで載せました。サイトマップから波の境目まで、すべて画面の中で実際に動きます。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

並び順は人気順ではなく、訪問者がフッターに着いてから出会う順にしました。まずページ全体の地図を広げ(01)、そこで関係が続くように連絡先を預かってもらい(02)、名前と著作権だけで静かに閉じる形を見せ(03)、スマホでは下部に張り付いて消えないバーを置き(04)、外のアカウントへ渡し(05)、規約や方針の置き場を決め(06)、実店舗なら来店への道を示し(07)、最後に上の本文との境目そのものを作り(08)、暗い床で全体を引き締めます(09)。文字も図形もサイト共通のインク・クリーム・アンバーのトークンだけで組んであるので、自分のブランド色に差し替えても配置は崩れません。

01多段サイトマップフッター

広い画面ではリンクのまとまりが三列に並び、狭い画面では各列がアコーディオンになります。開閉は高さではなくグリッドの行を0fr1frの間で動かしているので、中身の行数がいくつでも同じコードで滑らかに開きます。24コマ中12コマで動きが出て、累積の変化面積は2.053%と控えめです。

grid-template-rowsaria-expanded:focus-visible
.fsm__panel {
  display: grid;
  grid-template-rows: 1fr;
  overflow: hidden;
  transition: grid-template-rows $dur-base $easing;
}
.fsm__panel > * { min-height: 0; }
.fsm__col:has(.fsm__btn[aria-expanded="false"]) .fsm__panel { grid-template-rows: 0fr; }

@keyframes fsmSweep {
  0%        { grid-template-rows: 0fr; }
  8%, 74%   { grid-template-rows: 1fr; }
  86%, 100% { grid-template-rows: 0fr; }
}

02ニュースレター統合フッター

メール欄の横のボタンが押し込まれ、紙飛行機が回る輪の読み込みに変わり、その読み込みがチェック印に入れ替わります。入れ替えはsteps(1, end)の一コマ切り替えなので、二つの絵が薄く重なった中間のコマが生まれません。動いたコマは24コマ中10と少なめですが、平均の強度は109.8あります。

aria-livesteps(1, end)translateY
@keyframes fnPlane   { 0% { opacity: 1; } 40% { opacity: 0; } 82% { opacity: 1; } }
@keyframes fnLoad    { 0% { opacity: 0; } 40% { opacity: 1; } 58% { opacity: 0; } }
@keyframes fnDone    { 0% { opacity: 0; } 58% { opacity: 1; } 82% { opacity: 0; } }

@keyframes fnPress {
  0%, 38%   { transform: translateY(0); }
  41%       { transform: translateY(3px); }
  46%, 100% { transform: translateY(0); }
}
@keyframes fnBar {
  0%, 40%     { transform: scaleX(0); }
  58%, 88.9%  { transform: scaleX(1); }
  89%, 100%   { transform: scaleX(0); }
}

03ミニマル一行フッター

ロゴと著作権と丸い点3つが一行に収まり、点は0.667秒ずつずれて順に浮き上がります。浮いた点は元の色からそのサービスの色に変わり、色の値は点ごとの--onという変数一つで決まります。累積の変化面積は1.868%と九つの中で最も小さいのに、24コマ中18コマで何かが動いています。

translateYscaleX:focus-visible
@keyframes foLift {
  0% {
    transform: translateY(0);
    background: #{$ft-paper};
    color: #{$ft-stone};
  }
  8%, 26% {
    transform: translateY(-6px);
    background: var(--on);
    color: var(--on-ink);
  }
  33.33%, 100% {
    transform: translateY(0);
    background: #{$ft-paper};
    color: #{$ft-stone};
  }
}

04スティッキー下部アプリバー

画面の底に張り付いたバーの中を、アクティブな枠を示すピルが4つの位置を巡ります。ピルの幅を枠ひとつ分の25%にしてあるため、translateX(100%)がちょうど一枠となり、バーの幅が変わっても位置がずれません。累積の変化面積は9.898%、動いたコマは24コマ中18です。

translateXaria-current:focus-visible
.dk__pill {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 25%;            // 一枠 = 100% → translateX(100%) がちょうど一枠
  height: 100%;
  border-radius: $r-control;
  background: $color;
  transform: translateX(calc(var(--n, 0) * 100%));
  transition: transform $dur-base $ease-spring;
}

@keyframes dockSlide {
  0%        { transform: translateX(300%); }
  10%, 22%  { transform: translateX(0); }
  34%, 46%  { transform: translateX(100%); }
  58%, 70%  { transform: translateX(200%); }
  82%, 100% { transform: translateX(300%); }
}

05ソーシャルタイルフッター

大きなタイル4枚が0.5秒ずつずれて浮き上がり、浮いた瞬間だけアイコンがそのサービスの色になります。隅の「開く」印は透明度ではなくscale(0)で隠してあるので、休んでいる間はピクセルが一つも残りません。累積の変化面積は13.897%で、24コマ中19コマが動いています。

translateYbox-shadow:focus-visible
@keyframes tileLift {
  0%        { transform: translateY(0);    box-shadow: $shadow-press; }
  5%, 16%   { transform: translateY(-6px); box-shadow: $shadow-raised; }
  25%, 100% { transform: translateY(0);    box-shadow: $shadow-press; }
}

@keyframes tileIcon {
  0%,  19.9% { color: var(--brand); }
  20%, 100%  { color: $ft-stone; }
}

@keyframes tileGo {
  0%        { transform: scale(0); }
  5%, 16%   { transform: scale(1); }
  25%, 100% { transform: scale(0); }
}

06リーガル・リンクツリーフッター

大きい2行が主要な行き先、小さい2行がその次、いちばん下の細い行が規約と方針という三段の階段です。下線は幅ではなくscaleXで伸びるため、文字の再配置が起きず、行がガタつきません。累積の変化面積は3.451%、動いたコマは24コマ中19です。

scaleXfont-size:focus-visible
.lt__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 3px;
  border-radius: $r-pill;
  background: $color;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform $dur-quick $easing;
}

.lt__link:hover,
.lt__link:focus-visible { transform: translateX(6px); }
.lt__link:hover::after,
.lt__link:focus-visible::after { transform: scaleX(1); }

07連絡先・地図カードフッター

地図は画像ファイルではなくrepeating-linear-gradientを三枚重ねた道路の模様で、外部への読み込みが一件もありません。そこへピンが落ちて一度跳ね、輪が広がり、横の住所・電話・メールのカードが左から順に姿を現します。累積の変化面積は29.003%と九つの中で最大ですが、動きが薄く広がるため平均の強度は45.9と最も低くなります。

repeating-linear-gradienttranslateYscale
@keyframes pinDrop {
  0%       { transform: translateY(var(--drop)); opacity: 0; }
  6%       { transform: translateY(var(--drop)); opacity: 1; }
  30%      { transform: translateY(0); }
  40%      { transform: translateY(-9px); }
  52%, 100% { transform: translateY(0); }
}
@keyframes pinRipple {
  0%, 28%  { transform: scale(.3); opacity: 0; }
  34%      { transform: scale(.7); opacity: .9; }
  76%, 100% { transform: scale(2.4); opacity: 0; }
}
@keyframes cardIn {
  0%, 6%    { transform: translateY(10px); clip-path: inset(0 100% 0 0); }
  26%       { transform: translateY(0);    clip-path: inset(0 0 0 0); }
  86%       { transform: translateY(0);    clip-path: inset(0 0 0 0); }
  99%, 100% { transform: translateY(0);    clip-path: inset(0 0 0 100%); }
}

08ウェーブ境界フッター

明るい本文と暗いフッターの境目では、濃い波と淡い波の2枚が別々の速さで流れます。波の形はSVGをdata:URIで敷いた背景なので、こちらも外部ファイルが要りません。動いたコマは24コマ中23と九つの中で最多、平均の強度も149.1で最も高い値です。

translateXprefers-reduced-motion:focus-visible
.wv__wave {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 960px;                // 一組 480px(タイル4枚)× 2
  height: 28px;
  background-repeat: repeat-x;
  background-size: 120px 28px; // タイルを先に固定する
  animation-timing-function: $easing;
  animation-iteration-count: infinite;
  animation-duration: $duration;
}

@keyframes waveBack  { from { transform: translateX(0); } to { transform: translateX(-240px); } }
@keyframes waveFront { from { transform: translateX(0); } to { transform: translateX(-480px); } }

.wv.is-paused .wv__wave { animation-play-state: paused; }

09ダークインクのコントラストフッター

明るい本文のカードが暗い床へ降り、少しだけ跳ね返ってから落ち着きます。床の上の4つのリンクには0.18秒ずつずれてアクア色の下線が走り、この下線は自動再生を外してもマウスとキーボードの両方でそのまま出ます。累積の変化面積は14.908%、1コマあたりの最大変化は10.526%で九つの中で最も大きな一撃です。

scaleXtranslateY:focus-visible
.ic__rule {
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: 2px;
  background: $color;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform $dur-quick $easing;
}
.ic__link:hover .ic__rule,
.ic__link:focus-visible .ic__rule { transform: scaleX(1); }

@keyframes ruleScan {
  0%        { transform: scaleX(0); }
  24%, 60%  { transform: scaleX(1); }
  84%, 100% { transform: scaleX(0); }
}

どこで壊れるか — 落とし穴

九つを仕上げるまでに、同じ失敗を四つの形で踏みました。

一つ目は、スマホ幅に残された縦の余地です。320×200で描かせると実際に使える縦は「200 − 舞台の余白12.8×2 = 174.4px」しかありません。01は最初、各列のリンクを縦に積む作りにしていて176.4pxになり、2pxだけはみ出しました。狭い画面では縦に積むという定番の処方が、ここではフッターを長くする方向に働きます。リンクの並びをflex-direction: row; flex-wrap: wrapで横に寝かせ、余白を詰めて160pxまで下げて収めました。狭い画面向けのメディアクエリの中では、値を上げずに下げるだけにするのが安全です。

二つ目は、代表画像の選ばれ方です。poster は「直前のコマから一番大きく変わったコマ」なので、登場より退場のほうが勝ちやすくなります。07の連絡先カードは当初opacityで出していましたが、cubic-bezier(.2,.8,.2,1)は区間の30%地点ですでにopacity0.827まで上がるため、24コマのサンプルに半透明の幽霊が必ず紛れ込みます。さらにカードが出るコマの変化面積14,625pxが、次のコマの13,669pxに勝ってしまい、3枚目のカードがまだないコマが代表に選ばれました。透明度をやめてclip-path: inset()で左から現す形にすると変化がコマごとに均され、カード3枚とピンと輪がそろったコマが代表になりました。06も同じ問題で、下線が満ちるのに9%・引くのに5%かけていた配分を5%・9%へ逆転させ、下線のあるコマが勝つようにしています。

三つ目は、継ぎ目のない波です。08のトラック幅は Playwright のoffsetWidthで測って960px、波のタイルは120px、一組が480pxでタイルちょうど4枚にあたります。手前の層は−480px、奥の層は−240pxと、どちらもタイルの整数倍だけ動かしました。translateXが0・−480・−240のときのスクリーンショットのハッシュは完全に一致し、−479pxのときだけ違いました — 一周してもピクセルがずれない証拠です。

四つ目は、アクティブ表示が移動する最中に枠がまるごと消えた件です。04では当初アクティブな文字色をピルと同じ色にしていたため、ピルが隣へ移るコマでその枠の文字が背景に溶けました。ピルの到着時刻もキーフレームの終わりではありません。cubic-bezier(.2,1.4,.4,1)は行き過ぎてから戻るので、Playwright の実測では[46,58]%の区間の52%ですでに到着していました。ピルの幅も当てずっぽうではなくグリッドに決めさせています。nav が312pxなら一枠は78px、ピルも78px、タブのx座標は84・162・240・318で、きれいに一致しました。

アクセシビリティ

暗い床に明るい文字を置く配色は、それ自体がコントラストの試験です。九つで使った組み合わせを WCAG 2.1 の相対輝度の式でそのまま計算した結果が次の表で、最後の2行は落ちたので本文には使っていません。

前景 背景 実測コントラスト 本文の基準
白 #ffffff インク #1b1a20 17.28:1 合格
アンバー #ffd23f インク #1b1a20 11.97:1 合格
アクア #6ee7d7 インク #1b1a20 11.58:1 合格
ミスト #b9b3c4 インク #1b1a20 8.48:1 合格
インク #1b1a20 クリーム #fbf6ee 16.06:1 合格
ストーン #575162 クリーム #fbf6ee 7.08:1 合格
白 #ffffff ティール #0b7269 5.79:1 合格
インク #1b1a20 オレンジ #ff4d1f 5.21:1 合格
白 #ffffff オレンジ #ff4d1f 3.32:1 不足 — 使わない
白 #ffffff アンバー #ffd23f 1.44:1 不足 — 使わない

prefers-reduced-motion: reduceでは、九つとも飾りの動きだけを止めて、状態と情報のほうは残します。01はアコーディオンの開閉アニメーションを切ってもaria-expandedが開閉の唯一の出どころとして残り、02は紙飛行機と読み込みとチェック印の切り替えを止めても、どの絵を見せるかは根元のクラス一つが決めているので結果表示は消えません。03は点の浮き沈みがなくなるだけで、ホバーとフォーカスの色変化は指定ごと残ります。04はピルの移動を切ってもアクティブな枠の文字がインクのまま見えます。05は浮き沈みを切っても隅の「開く」印がマウスとキーボードで出せ、06は現在地の下線がscaleX(1)のまま満ちた状態で止まります。07はピンと輪とカードを止めたうえでopacity: 1に戻すので、地図も連絡先も欠けません。08は波の流れが止まるだけで曲線の形はそのまま、09はカードの落下と下線の走りが消えても配色は動きません。ここまでの切り替えを含む九つ分のSCSSは、7g7q5d5zを入れて開く zip にそのまま入っています。

支えている仕掛けは派手ではありません。九つともフッターの一番外側は<footer>で、01・02・03にはrole="contentinfo"も明示してあります。リンクのまとまりには<nav aria-label>で名前を付け(01は製品・会社・サポートの三つ)、01のアコーディオンはaria-expanded、04と06の現在地はaria-current、02の申込結果はrole="status"aria-live="polite"、08の一時停止スイッチはaria-pressedで伝えます。キーボードで触れる要素にはすべて:focus-visibleの輪郭を付けてあり、04ではアクア色のピルの上でも見えるように白い輪郭にしました。根拠はMDN の grid-template-rowsMDN の prefers-reduced-motion、コントラストの基準はW3C の Understanding Contrast (Minimum)です。

ほかの区画のひな形はテンプレート一覧にまとまっています。このサイトを作っている人のことはサイト紹介に書きました。

FAQ

フッターの一番外側は<footer>だけで十分ですか

本文やセクションの外側に置いた<footer>は、それだけで contentinfo というランドマークになります。この九つでは念のため01・02・03にrole="contentinfo"も書き足しましたが、<article><section>の内側に入れるとランドマーク扱いが消えるので、置き場所のほうに気を配ってください。

波(08)の継ぎ目は本当に見えませんか

見えません。トラック幅960pxに対して波のタイルは120px、一周で動かす量は手前が480px・奥が240pxと、どちらもタイルの整数倍です。ずらした位置のスクリーンショットを比べると、整数倍のときだけハッシュが元と完全に一致しました。

自動再生をやめて、自分のサイトの操作に差し替えられますか

はい、九つとも自動再生は.is-demoという印を付けたときだけ働く上書きで、ホバーとフォーカスの静的な指定が先に書いてあります。印を外せば、開閉も下線もタイルの浮き沈みも、訪問者の操作だけで同じように動きます。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。