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 コンポーネントを読み込むとかそんな感じなんでしょうかね。気が向いたらやってみます(多分向かない)