Gatsbyでもブログによくある吹き出しを使いたい件

4

目次

これをつくったのです

吹き出しがあると日本のブログっぽくてイイネ!

長い本文もへっちゃらだよ!じゅげむじゅげむ ごこうのすりきれ かいじゃりすいぎょのすいぎょうまつうんらいまつふうらいまつ くうねるところにすむところ やぶらこうじのぶらこうじ ぱいぽぱいぽぱいぽのしゅーりんがん しゅーりんがんのぐーりんだい ぐーりんだいのぽんぽこぴーのぽんぽこなのちょうきゅうめいのちょうすけ

作り方

gatsby-remark-custom-blocksというプラグインを使用します。リファレンスはこちら

インストールしましょう

まずは

CommandLine
$ yarn add gatsby-remark-custom-blocks

$ npm i gatsby-remark-custom-blocks

でインストールしましょう。

gatsby-config に追記

こちらのプラグインはgatsby-transformer-remarkのプラグインですのでその中に追記します。

gatsby-config.js
{
  resolve: `gatsby-transformer-remark`,
  options: {
    plugins: [
    {      resolve: "gatsby-remark-custom-blocks",      options: {        blocks: {          danger: {            classes: "danger",          },          info: {            classes: "info",            title: "optional",          },        },      },    },

今回は吹き出しなのでballoonとかにしておきましょう。

gatsby-config.js
{
  resolve: `gatsby-transformer-remark`,
  options: {
    plugins: [
    {
      resolve: "gatsby-remark-custom-blocks",
      options: {
        blocks: {
          danger: {
            classes: "danger",
          },
          info: {
            classes: "info",
            title: "optional",
          },
          balloon: {            classes: "balloon",          }        },
      },
    },

こちらのプラグインを使用すると、マークダウンファイルで

sample.md
[[balloon]]
| 吹き出し本文

こんな風に記述するとビルド時に下のような HTML として出力されます。

sample.html
<div class="custom-block balloon">
  <div class="custom-block-body"><p>吹き出し本文</p></div>
</div>

なので、親要素に擬似要素として画像を当て、子要素に吹き出しのスタイルを当てていきましょう。

実際に作っていく

僕の環境はstyled-componentsなので、ご自身の環境に合わせてコードは適宜修正してください。また、scss で書いているので css 環境の人は直してください。

import { css } from "styled-components";
import icon from "../icon/icon.png";

export const balloonStyle = css`
  /* balloon */
  .balloon {
    padding-left: 60px;
    position: relative;
    &::before {
      background-image: url(${icon});
      background-repeat: no-repeat;
      background-size: contain;
      border: 2px solid #ccc;
      border-radius: 50%;
      content: "";
      height: 40px;
      left: 0;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      width: 40px;
    }
    .custom-block-body {
      border: 2px solid #ccc;
      border-radius: 3px;
      display: inline-block;
      max-width: 100%;
      min-width: 120px;
      padding: 0.5em 1em;
      position: relative;
      &::before {
        border: 10px solid transparent;
        border-right: 10px solid #fff;
        content: "";
        left: -17px;
        margin-top: -10px;
        position: absolute;
        top: 50%;
        z-index: 2;
      }
      &::after {
        border: 10px solid transparent;
        border-right: 10px solid #ccc;
        content: "";
        left: -20px;
        margin-top: -10px;
        position: absolute;
        top: 50%;
        z-index: 1;
      }
      p {
        margin: 0;
      }
    }
  }
`;

あとは記事テンプレファイルにて定義してあげれば OK。

blogTemplate.js
import balloonStyle from "../style/balloonStyle";

const PostContent = styled.div`
  ${balloonStyle}
`;

class BlogPostTemplate extends React.Component {
  render() {
    // 略
    <PostContent dangerouslySetInnerHTML={{ __html: html }} />;
    // 略
  }
}

この方法の欠点

  • CSS 側から画像を出力するため複数のアイコンに対応していない
  • 左側画像パターンのみ(新しく balloon2 として登録していけば右側画像パターンもいけますが)

まぁ個人ブログ程度であれば何も問題はないのですが、きちんとしたメディアサイトだと思うと解消の必要がありそう。

まとめ

ご覧の通りかなりの荒技ではあるのでもっとスマートに作成できる方いたら教えていただければ幸いです。

.mdx で記事書いて balloon コンポーネントを読み込むとかそんな感じなんでしょうかね。気が向いたらやってみます(多分向かない)

  • SNSでシェアしよう
  • Twitterでシェア
  • FaceBookでシェア
  • Lineでシェア
  • 記事タイトルとURLをコピー
トップへ戻るボタン

\ HOME /

トップへ戻る