1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Gatsbyで美少女フィギュアレビュー用Themeを作った

Posted at

Gatsby で美少女フィギュアレビュー用の Gatsby Theme を作った話。

見た目はこんな感じ↓。

スクリーンショット 2023-04-13 19.02.34.png

まぁ、美少女フィギュアレビュー用とは書いたけど、普通に写真全般に特化したThemeだと思ってもらって良い(いわゆる釣りタイトル)。

技術的な解説とかをしていくよ❗

モチベ

そもそも、ブログを引っ越ししたかったのがきっかけ。

今のブログは Hexo 製なんだけど、
細かいところのカスタマイズがしづらいんだよね。EJSにどうにも慣れなくて...。
探り探りでカスタマイズしたのも数年前で、もう全然覚えてないわけ。
で、秘伝のタレ化しちゃったから、いっそ一から作ろうと思って、別のSSGフレームワークをあさり始めた。

JekyllとかHugoとかもあったんだけど、Gatsbyに決めた。
人気もすごいし、Reactだし、表示が爆速だしで良さげだったため。

誤算だったのは、Gatsbyで美少女フィギュアレビューブログを書いてるやつはいなかったこと...なぜだ...。
皆さん頭良さそうな技術系ブログばっか作ってて、写真がメインのStarterとかThemeが意外とない❗
(自分の探し方がイマイチな可能性は大きいが。)

しょうがないから全部自分で作った。
作ってるうちに「自分だけで使うのももったいねえな...」と思い始めたので、Themeと Starter も作ったった。
皆さんも美少女フィギュアレビューブログ作ろう❗❗❗私も作ったんだからさ💢💢💢

機能

  1. 画像をできるだけ大きく表示
  2. レスポンシブ
  3. Markdown(MDXじゃなく)
  4. Special hooks
  5. Tailwind CSSサポート

他、細かいところは Readme 読んでね。

1. 画像をできるだけ大きく表示

↓みたいに記事の横幅いっぱいまで画像拡大するようにしてる。

スクリーンショット 2023-04-13 19.46.22.png

フィギュアレビューブログで画像が小さいのは致命的なんだよね。
可能な限り画面いっぱいにかわいこちゃんを表示したい❗

ただ、縦位置で撮った縦長写真で横幅いっぱいにすると、PCで見た時にでかすぎるので、そこは抑えてある。
縦幅が最大でスクリーンの高さまでになるようにした。

gatsby-remark-images を使ってるなら、↓のようにすればよい。

plugins: [
  {
    resolve: `gatsby-remark-images`,
    options: {
      wrapperStyle: (image) =>
        `max-width:${(image.aspectRatio * 100).toFixed(2)}vh`, // See [issue: Can't specify max-width](https://github.com/gatsbyjs/gatsby/issues/15578) .
    },
  },
]

ちなみに、 max-height を指定するとレイアウトが崩れちゃったんだよな...CSSは謎。

2. レスポンシブ

イマドキはレスポンシブじゃないとお話にならない。
弊ブログのGoogle Analyticsの結果が↓だけど、もう5割以上はスマホなんだよね。

スクリーンショット 2023-04-13 20.34.23.png

レスポンシブ対応にあたっては、CSSのFlexとGridが大活躍だった。
部分的に使うのではなく、むしろ全体のレイアウトに使うのが良い。

  1. ヘッダ
  2. メイン
  3. サイドバー
  4. フッタ

とあったときに、メインとサイドバーをFlexItemにすれば、
画面幅を小さくしたときに自動でサイドバーが回り込んでくれる。

このあたりは書くこと多すぎなので、あとで別途解説する...かも。

3. Markdown(MDXじゃなく)

Pure MarkdownとMDXでどっちを採用するかは結構迷った。

MDXにすると、React Componentが使えて、記事ごとの表現力が上がる。
ただ、それって当然React Componentに依存するわけで、
将来的にGatsbyから引っ越すときに枷になりそう...と思ったので却下。

あと、URLを <> で囲った書き方ができなくなるのもちょっと嫌。ただの上位互換じゃないんかい❗

さらに、あれこれ調べてたら、Pure Markdownでも表現力は補える方法があった。Special hooksでで解説。

4. Special hooks

『Special hooks』ってのは自分が勝手に作った言葉なので注意。
特定の条件のMarkdownの記述にフックして、任意のReact Componentを作る機能。

例えば、タイトルに leftright を持った2枚の画像が並んでいたら、
↓のような画像比較スライダーを作ったりできる。

image-compare-slider.png

実際に動いてるデモはここ。

設計的には、gatsby-transformer-remarkが作るHTML抽象構文木(hast)と hast-util-to-jsx-runtime を利用する。
例えば、↑の画像比較スライダーの例だと↓のようになる。

  1. hastをパースして、タイトルが leftright から始まる2枚の画像を探す。
  2. ↑の画像を子に持つ p タグを ImageCompareSlider タグにする。
  3. hast-util-to-jsx-runtime でhastをReact Elementに変換
    • components オプションで、 ImageCompareSlider タグを同名のReact Componentへ変換するようにしておく。

これも詳細は別途解説記事を作る...かも。

5. Tailwind CSSサポート

以前、Tailwind CSSは別のプロジェクトでいじってて使い勝手が良かったので、今回も使いたい。
...が、これが結構手間取った。

まず、Themeとか関係なく、GatsbyでTailwind CSSを使う方法は検索すると出てくる。
しかし、Themeでとなるとヒットしない...。

Gatsby Themeは結構特殊で、ThemeのComponentをShadowingしたときにもTailwind CSSが使えるようにする必要があるんだよね。
そうなると、ディレクトリ構成的には2箇所でTailwind CSSを使えるようにしなきゃならない。

最初はThemeとThemeを使う側の両方でTailwind CSSをセットアップしてた。
PostCSSの有効化も tailwind.config.js の用意も gatsby-browser.jsglobal.cssimport も2箇所でやってた。
これでも正常に動いてたんだけど、ShadowingするComponentを増やしたら急にレイアウトが崩れだした❗

デバッグしたら、Tailwind CSSのClass定義が重複してて、media-queryなどの順番がめちゃくちゃになってた。
原因は gatsby-browser.jsglobal.cssimport を2箇所でやってたのが悪さをしてた。
これが重複すると、Theme側とThemeを使う側でClass名が別々に定義されて、重複しちゃうらしい。
(これに気づくまでにめっっっっちゃめちゃ時間かかった...。)

結局、Tailwind CSSのセットアップはThemeを使う側に一本化することにした。
そちらでPostCSSを有効化して、 tailwind.config.jsglobal.css も用意してもらう。
ただ、Theme側で tailwind.config.js を記述したい部分もあったので、Theme側にも tailwind.config.js を用意して、Themeを使う側で require してもらうことにした。

Theme側の tailwind.config.js が↓。

const path = require(`path`);

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    // See [Tailwind CSS | Working with third-party tools](https://tailwindcss.com/docs/content-configuration#working-with-third-party-libraries) .
    path.join(
      path.dirname(require.resolve(`@tenpamk2/gatsby-theme-figure-blog`)),
      "**/*.{js,jsx,mjs,ts,tsx}"
    ),
  ],
  theme: {
    extend: {
      dropShadow: {
        title: [
          `0 1px 1px rgb(100% 100% 100% / .8)`,
          `0 2px 3px rgb(0% 0% 0% / .5)`,
          `0 0px 20px rgb(0% 0% 0% / 1)`,
        ],
      },
      typography: {
        DEFAULT: {
          css: {
            ".gatsby-resp-image-wrapper": {
              boxShadow: `0 0 1rem rgb(0% 0% 0% / .5)`,
              borderRadius: `0.5rem`,
              overflow: `hidden`,
            },
            // 中略
          },
        },
      },
    },
  },
  plugins: [require(`@tailwindcss/typography`)],
};

Themeを使う側の tailwind.config.js が↓。

const defaultOptions = require(`@tenpamk2/gatsby-theme-figure-blog/tailwind.config.js`);

/** @type {import('tailwindcss').Config} */
module.exports = {
  ...defaultOptions,
  ...{
    content: [...defaultOptions.content, `./src/**/*.{js,jsx,mjs,ts,tsx}`],
  },
};

おまけ: 完走した感想

疲 れ た 。

2022年12月からGatsbyをいじりはじめて、今日までかかってしまった。
最終的に理解しなきゃいけない要素は↓。

  1. Gatsby
  2. Gatsby Theme
  3. GraphQL
  4. React
  5. JavaScript
  6. HTML
  7. CSS
  8. Tailwind CSS(typography含む)
  9. npm(ディレクトリ構造、workspace、publish...)
  10. Netlify
  11. Git(submoduleによるMarkdownと画像だけ別リポジトリ管理)

さすがに学習コストが高すぎた...。本職は組み込み屋さんやぞ私は...。
でも楽しかったのでOK。

で、ここまでやっておいて実はまだ引っ越しはできてないんだよねw
Hexo用に書いてた記事を新ブログ用に手直ししないといけなくて、それが面倒。

あと何日で弊ブログは新ブログに移行できるのやら...乞うご期待。

https://tenpamk2-blog.netlify.app/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?