フリーランスでWeb制作をしている矢野です。
今回、この技術ブログを含むポートフォリオサイト(yanoworks.com)そのものを、購入テーマやページビル ダーを使わず、WordPressのオリジナルテーマとして一から自作しました。
この記事では、「なぜ自作したか」「どう設計したか」「どこでハマったか」を、実際の試行錯誤も含めて 書いておきます。
なぜ購入テーマではなく自作したか
正直、購入テーマやページビルダーを使えば、もっと早く形にできたと思います。
それでもオリジナルテーマにこだわったのには理由があります。
1つ目は、単純に技術力を直接示せるからです。
ポートフォリオサイト自体が購入テーマだと、「このサイト、テンプレートっぽいな」と思われた時点で説 得力が落ちてしまいます。
逆に、サイト自体が自分の実装力の証明になるなら、これほど分かりやすいアピールはありません。
2つ目は、カスタム投稿タイプやカスタムフィールドを使った柔軟な設計が、既製テーマだと窮屈に感じたこ とです。
実績(work)をどう管理するか、フォームの項目をどう増やすか、といった細かい調整を自分の裁量で決め られるのは、自作ならではのメリットだと感じています。
設計の全体像
構成としては、大きく分けて2つの独自実装があります。
1つ目は、実績管理用のカスタム投稿タイプ「work」です。
クライアント名・サイトURL・タグをカスタムフィールドとして持たせ、実績一覧はこのカスタム投稿タイプ をループして表示する形です。
実績が増えても、投稿を追加するだけで一覧・詳細ページが自動的に増えていく設計です。
2つ目は、プラグインを使わない自作のお問い合わせフォームです。
admin-post.phpのフックを使い、nonceによるCSRF対策、ハニーポットによるスパム対策、wp_mail()による メール送信までを自前で実装しています。
プラグインに頼らず自作したのは、「自分で作れる」という一貫性を持たせたかったからです。
デザインで意識したこと:「AI感」を消す試行錯誤
正直、ここが一番時間をかけた部分です。
最初に組んだデザインは、実績カードに枠線・影・ブラウザ風のモックアップフレームをつけた、いわゆる 「よくあるテンプレート的な」見た目でした。
ただ自分で見返すと、生成AIが作ったようなテンプレ感が強く、何度も作り直す羽目になりました。
最終的に実績セクションは、カード型をやめて、連番とセリフ体タイトルを使った編集誌風のリスト表示へ と作り替えています。
枠や影に頼らず、タイポグラフィだけで情報の階層を作る方向です。
もう1つ判断に迷ったのが、スキルセットの見せ方です。
最初はスキルの習熟度をドットやバーで可視化する案を検討していました。
ただ、これは依頼者目線で考えたときにリスクがあると気づいたんです。
「バーが100%じゃないから、この人に頼むのはやめておこうか」と、非技術者の依頼者に余計な不安を与え てしまう可能性があるからです。
信頼構築が目的のセクションでは、定量的な自己評価よりもプレーンな一覧の方が適切だと判断し、最終的 には装飾のない連番リストに落ち着きました。
つまずいたポイント
FAQアコーディオンのアニメーションが不安定だった
開閉のアニメーションを、最初はCSSのgrid-template-rowsを0frから1frに変える方法で実装していました。
BEFORE(CSSのみで実装)
.faq-item .faq-answer {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 300ms ease;
}
.faq-item[open] .faq-answer {
grid-template-rows: 1fr;
}
ただ、閉じるときの動きが不安定だったり、特定の項目だけ挙動がおかしくなったりして、原因の切り分け に時間がかかりました。
最終的には、JavaScriptで開閉前後の実際の高さを測定し、Web Animations APIで直接アニメーションさせる方式に切り替えています。
AFTER(実測した高さをWeb Animations APIでアニメーション)
const toggleFaq = (item) => {
const answer = item.querySelector('.faq-answer');
const height = measureOpenHeight(answer);
item.animate(
[{ height: '0px' }, { height: height + 'px' }],
{ duration: 300, easing: 'ease' }
);
};
こちらに切り替えたことで、安定した開閉動作を実現できています。
レスポンシブでCSS Gridの列数が想定より減っていた
スマートフォン表示で、2列になるはずのグリッドが1列になってしまう不具合がありました。
BEFORE(余白を考慮していなかった指定)
.flow-steps {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 2rem;
}
原因を追ったところ、親要素の.sectionと.containerの両方に左右の余白(パディング)が設定されており 、想定より表示エリアが狭くなっていたことが分かりました。
AFTER(スマホ幅では最小値と余白を縮小)
@media (max-width: 900px) {
.flow-steps {
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 1rem;
}
}
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr))のような指定は、余白を含めた実際の表示幅次第で列数が変わるため、レイアウトの入れ子構造まで含め て計算する必要がある、という学びがありました。
まとめ
購入テーマを使えばもっと早く公開できたと思いますが、自作したことで、「自分が何を作れるか」を一番 説得力のある形で示せたと感じています。
特に、「AI感をどう消すか」「依頼者にとって不要な不安を与えない見せ方は何か」といった判断は、実際 に手を動かして初めて気づけたことでした。
これから副業や独立でWeb制作を始めようとしている方の参考になれば嬉しいです。
次回は、このサイトのローカル開発環境をDocker(wp-env)で構築した話を書く予定です。