Slack Block Kitの制約とデザインパターンガイド

はじめに

前回の記事「GoでSlack通知を実装する方法」では、Slack通知の基本的な実装方法とBlock Kitの初歩的な使い方について解説しました。

今回は、Slack Block Kitをより深く掘り下げて、その特性、制約、そして効果的なデザインパターンについて詳しく説明します。特に、Block Kitの「見た目があまり変えられない」という特性と、その制約の中でいかに美しく機能的なメッセージを作成するかに焦点を当てます。

Slack Block Kitの特性と制約

1. デザインの統一性と制約

Slack Block Kitの最も大きな特徴は、デザインの自由度が意図的に制限されていることです。これにはいくつかの理由があります。

  • 一貫性の確保: すべてのアプリからのメッセージが統一された見た目になる
  • 可読性の向上: Slackの標準UIパターンに従うことで、ユーザーが迷わない
  • アクセシビリティ: スクリーンリーダーやキーボードナビゲーションに配慮

2. 制約の具体例

以下のような点でカスタマイズが制限されています。

  • 色の変更: テキストやブロックの背景色は基本的に変更不可
  • フォントサイズ: 固定のフォントサイズ体系
  • 余白・レイアウト: ブロック間の余白やレイアウトは Slack側で制御
  • アニメーション: 動的な効果は実装不可

これらの制約があるからこそ、コンテンツの構成とブロックの組み合わせが重要になります。

Block Kitの主要ブロックタイプ解説

実際のサンプルコードを基に、各ブロックタイプの特性と使用例を詳しく見てみましょう。

1. Header ブロック

1
2
3
4
5
6
7
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Slack Block Kitデザインシステム見本"
}
}

特徴:

  • メッセージの最上部に配置される大きなタイトル
  • plain_textのみ対応(Markdownは使用不可)
  • 絵文字を使用することで視覚的なアクセントを追加可能

使用場面:

  • 通知のタイトル

2. Section ブロック

1
2
3
4
5
6
7
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*1. 基本的なセクション*\nこれは基本的なセクションブロックです。*太字*や_斜体_、~取り消し線~、`コード`などのMarkdown書式が使えます。"
}
}

特徴:

  • 最も汎用的で使用頻度が高いブロック
  • Markdownによる豊富なテキスト装飾
  • accessoryフィールドで画像やボタンを右側に配置可能

応用例 - 画像付きセクション:

1
2
3
4
5
6
7
8
9
10
11
12
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "画像を右側に配置できます"
},
"accessory": {
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/beagle.png",
"alt_text": "かわいい犬の画像"
}
}

3. Context ブロック

1
2
3
4
5
6
7
8
9
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "👆 Contextブロックは小さいテキストで補足情報を表示するのに最適です"
}
]
}

特徴:

  • 小さなフォントサイズで表示
  • 補足情報や注釈に最適
  • 複数の要素を横並びで配置可能

使用場面:

  • タイムスタンプ
  • 作成者情報
  • 追加の説明文

4. Divider ブロック

1
2
3
{
"type": "divider"
}

特徴:

  • シンプルな水平線
  • セクション間の視覚的な区切り
  • パラメータ不要で最もシンプルなブロック

5. Actions ブロック

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Primary ボタン",
"emoji": true
},
"style": "primary",
"value": "primary_button",
"url": "https://example.com/primary"
}
]
}

特徴:

  • ボタンやその他のインタラクティブ要素を配置
  • 最大5つの要素まで横並び配置可能
  • 3つのボタンスタイル:default(境界線のみ)、primary(青色)、danger(赤色)

制約の中での効果的なデザインパターン

1. 疑似的な枠線の実装

Block Kitには明確な「枠線」がありませんが、以下のようなテクニックで視覚的なグループ化を実現できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{		
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*2. 擬似的な枠線付きセクション*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "```項目:値```"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "```ステータス:完了```"
}
}

工夫のポイント:

  • Markdownを使用した疑似的な枠線

2. 状態表示のパターン

色が変更できない制約の中で、絵文字とテキストを組み合わせて状態を表現。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• *<https://example.com/task/goals|目標の基本を学ぶ>*\n :alarm_clock: 2024年9月24日"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• *<https://example.com/task/personal-goals|個人目標設定の方法を学ぶ>*\n :warning: 2024年9月24日(期限超過)"
}
}

使用される表現方法:

  • :alarm_clock: - 通常の期限
  • :warning: - 期限超過や注意
  • :white_check_mark: - 完了
  • :x: - エラーやキャンセル

3. 複数ボタンのレイアウトパターン

Actionsブロックでは、最大5つまでのボタンを配置できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "確認",
"emoji": true
},
"style": "primary",
"value": "confirm"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "後で",
"emoji": true
},
"value": "later"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "キャンセル",
"emoji": true
},
"style": "danger",
"value": "cancel"
}
]
}

デザインの考慮点:

  • Primary(青色)は最重要アクション用
  • Default(境界線のみ)は通常アクション用
  • Danger(赤色)は削除や危険なアクション用

まとめ

Slack Block Kitは確かに「見た目があまり変えられない」という制約がありますが、これらの制約を理解し、適切にブロックを組み合わせることで、美しく機能的なメッセージを作成できます。

重要なのは以下の点です。

  1. 制約を受け入れる: デザインの自由度は制限されているが、その分一貫性と可読性が保たれる
  2. コンテンツ構成に集中: 色やレイアウトではなく、情報の構造化と優先順位付けに注力
  3. パターンの活用: 疑似的な枠線や絵文字による状態表現など、制約内でのテクニックを習得

Block Kitの詳細なリファレンスはSlack Block Kit Builderで実際に構築しながら確認できますので、ぜひご活用ください。

この記事で紹介したテクニックのサンプルもぜひご利用ください!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Slack Block Kitデザインシステム見本",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "こんにちは、鈴木 太郎さん\nこちらはデザインパターンの総合的な見本です。"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*1. 基本的なセクション*\nこれは基本的なセクションブロックです。 *太字* や _斜体_ 、 ~取り消し線~ 、 `コード` などのMarkdown書式が使えます。"
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "👆 Contextブロックは小さいテキストで補足情報を表示するのに最適です"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*2. 擬似的な枠線付きセクション*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "```項目:値```"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "```ステータス:完了```"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*3. リンク付きのテキスト*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• *<https://example.com/task/1|リンク付きタスク名>*\n 2024年9月24日"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• リンクなしタスク名\n 2024年9月25日"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*4. 画像付きセクション*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "画像を右側に配置できます"
},
"accessory": {
"type": "image",
"image_url": "https://api.slack.com/img/blocks/bkb_template_images/beagle.png",
"alt_text": "かわいい犬の画像"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*5. ボタンとアクション*"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Primary ボタン",
"emoji": true
},
"style": "primary",
"value": "primary_button",
"url": "https://example.com/primary"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Default ボタン(アウトライン)",
"emoji": true
},
"value": "default_button",
"url": "https://example.com/default"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Danger ボタン",
"emoji": true
},
"style": "danger",
"value": "danger_button",
"url": "https://example.com/danger"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*6. 通知カード*"
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "┌──────────────────────────────────────────┐"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": " *【オンボーディング】入社後1ヶ月間のTODO*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": " *社員*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": " 佐藤 花子、田中 一郎、山田 太郎"
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "└──────────────────────────────────────────┘"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "コースを確認",
"emoji": true
},
"style": "primary",
"value": "check_course",
"url": "https://example.com/onboarding/course"
}
]
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*7. タスクリスト(期限付き)*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• *<https://example.com/task/goals|目標の基本を学ぶ>*\n :alarm_clock: 2024年9月24日"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• *<https://example.com/task/management|代表的なマネジメントの型を知る>*\n :alarm_clock: 2024年9月25日"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "• *<https://example.com/task/personal-goals|個人目標設定の方法を学ぶ>*\n :warning: 2024年9月24日(期限超過)"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*8. 複数ボタン配置*"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "確認",
"emoji": true
},
"style": "primary",
"value": "confirm"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "後で",
"emoji": true
},
"value": "later"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "キャンセル",
"emoji": true
},
"style": "danger",
"value": "cancel"
}
]
},
{
"type": "divider"
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "このメッセージはデザインシステムの参考用に自動生成されました"
}
]
}
]
}