🖼️

【DifyのUIテクニック:後半】UIをよりリッチに!HTML/CSSの活用方法

に公開

1. はじめに👋

こんにちは!前回の記事では、DifyアプリのUIを整えるために Markdownを用いて回答を見やすく構造化する方法 を学びました。
Markdownは軽量で扱いやすく、ちょっとした強調や段落整理にとても便利です。
ただ、アプリを活用していくと、もっと自由なレイアウトやデザインを実現したくなることはないでしょうか?

そこで今回は、Markdownでは表現しきれない柔軟なUIを実現できる「HTML」と「CSS」 について、基本の仕組みから実践的な活用方法まで、すぐに試せるコード例とともに丁寧に解説していきます。
これらを活用することで、DifyのUI上だけで以下のような高度なレイアウトを自由にカスタマイズすることができるようになります。

またこの記事の最後には、すぐにDify上でHTML・CSSを使えるように以下の二つを準備していますので、ぜひご活用ください!

  • イメージを伝えるだけでDifyの制約に対応した高クオリティのUIを生成してくれる専用プロンプト
  • すぐにコピペして使用できるMarkdown・HTML/CSSのデザイン一覧をまとめたDSLファイル
当シリーズのブログ一覧
  1. 【DifyのUIテクニック:前半】コード不要!Markdown活用術
  2. 【DifyのUIテクニック:後半】UIをよりリッチに!HTML/CSSの活用方法 ← 現在ココ

2. HTMLとCSSとは?

1. UIの「構造」を定義する"HTML"

HTML (HyperText Markup Language) とは、文書やコンテンツがどんな情報で構成されているか、その「構造」を定義する言語です。
<h1><p>といった「タグ」を使って、「これは見出し」「これは段落」というように、各コンテンツに意味や役割を与えます。

<h1>これは大見出しです。</h1>
<p>これは文章の段落です。</p>

↓実際の表示画面


2. 見た目を「デザイン」する"CSS"

CSS (Cascading Style Sheets) とは、HTMLによって組み立てられた骨格に、「デザイン」を施して美しく見せるための言語です。
一般的にはCSSを別ファイルとして管理することもありますが、DifyではHTMLのタグ内に直接記述するインラインCSSを用いてデザインを調整します。これを使用することで、文字・背景の色、余白、角の丸みといった、視覚的な表現をデザインすることが可能になります。
例として、先ほどのHTMLに「見出しの文字色を青にする」というCSSの指示(プロパティ)を加えてみましょう。

<h1 style="color: blue;">これは大見出しです。</h1>
<p>これは文章の段落です。</p>

↓実際の表示画面

3. よく使用されるHTMLタグ・CSSプロパティ一覧

ここでは、DifyのUI作成で特に使われる代表的なHTMLタグと、UIのレイアウト装飾で使用される基本的なCSSプロパティをご紹介します。

基本的なHTMLタグ一覧

タグ 名称 主な役割と特徴
<h1><h3> 見出し h1(大見出し)からh3(小見出し)まで、セクションの見出しを定義します。
<p> パラグラフ 「段落」を意味します。文章のまとまりをこのタグで囲みます。
<div> ディビジョン 特定の範囲を「ブロック」としてグループ化するために使います。
<span> スパン 文章中の一部をグループ化するために使います。
<strong> ストロング テキストを「太字」で表示します。
<table> テーブル 表を作成します。<tr>(行)、<th>(見出しセル)、<td>(データセル)といったタグと組み合わせて使用します。
<br> 改行 テキストの途中で改行を入れます。<p>タグが段落ごと分けるのに対し、<br>は行を分けるだけです。
<form> フォーム ユーザーが入力・送信するための範囲を定義します。
<input> 入力 フォーム内で、テキスト入力欄やチェックボックスなどの入力フィールドを作成します。
<button> ボタン クリック可能なボタンを作成します。
<details> / <summary> 詳細・要約 クリックで開閉できるトグルを作成します。<summary>が見出し部分、<details>が全体を囲みます。

基本的なCSSプロパティ一覧

ここでは、UIのレイアウト装飾で使用される、基本的なCSSプロパティをご紹介します。

プロパティ 説明 使用例 (style="..." の中身)
background-color 要素の背景色を指定します。 background-color: #f0f8ff;
color テキストの色を指定します。 color: #d9534f;
padding 要素の内側の余白を設定します。 padding: 15px;
margin 要素の外側の余白を設定します。 margin-bottom: 20px;
border 要素の周りに枠線を引きます。 border: 1px solid #cccccc;
border-radius 要素の角を丸くします。 border-radius: 8px;
font-size テキストの大きさを指定します。 font-size: 16px;
font-weight テキストの太さを指定します。boldで太字にすることで、キーワードを強調できます。 font-weight: bold;
text-align テキストの水平方向の配置(行揃え)を指定します。centerで中央揃えにすると、タイトルなどが引き立ちます。 text-align: center;
display 要素を横並びにするなど、柔軟なレイアウトを実現します。 display: flex;

サンプル1

<h2>CSSサンプル 1</h2>
<div style="background-color: #e6f7ff; color: #0056b3; padding: 15px; margin-bottom: 20px; border: 1px solid #b3e0ff;">
  <strong>情報:</strong> このボックスには、インラインCSSで5つのプロパティが適用されています。
</div>
<p>このテキストはボックスの外にあります(marginの確認用)。</p>

↓実際の表示画面

解説
  • ボックスの背景が、薄い水色→background-color: #e6f7ff
  • ボックス内のテキストが、濃い青色→color: #0056b3
  • ボックスの枠線と中のテキストとの間に、15pxの内側の余白を確保→padding: 15px
  • ボックスの下側に20pxの外側の余白→margin-bottom: 20px
  • ボックスの周囲を1ピクセルの太さの実線(薄い青色の枠線)で囲む→border: 1px solid #b3e0ff

サンプル2

<h2>CSSサンプル 2</h2>
<div style="display: flex; justify-content: space-around; background-color: #f4f4f4; padding: 20px;">
  <div style="border-radius: 8px; font-size: 18px; font-weight: bold; text-align: center; background-color: #ffffff; border: 1px solid #ddd; padding: 30px; width: 120px;">
    プランA
  </div>
  <div style="border-radius: 8px; font-size: 18px; font-weight: bold; text-align: center; background-color: #ffffff; border: 1px solid #ddd; padding: 30px; width: 120px;">
    プランB
  </div>
  <div style="border-radius: 8px; font-size: 18px; font-weight: bold; text-align: center; background-color: #ffffff; border: 1px solid #ddd; padding: 30px; width: 120px;">
    プランC
  </div>
</div>

↓実際の表示画面

解説
  • 3つの「プラン」カードが縦に並ばず、横一列に配置→display: flex
  • 各カードの間隔を均等に空け、両端にも余白を確保→justify-content: space-around
  • 各カードの四隅を丸く→border-radius: 8px
  • 「プラン」の文字を18pxの大きさで表示→font-size: 18px
  • 「プラン」の文字を太字で表示し強調→font-weight: bold
  • 「プラン」の文字を各カードの中央に配置→text-align: center

4.DifyでHTML/CSSを使う際のポイント

前の章で紹介した便利なCSSプロパティを使えば、様々なデザインが実現できます。しかし、実際にこれらをDifyで使う際には、いくつか知っておくべきDifyならではの仕様や注意点があります。
ここでは、トラブルを避けてスムーズにUIを実装するために、その重要ポイントを解説します。

✅ Difyで利用できるHTML/CSS

まずは、Difyで利用できる要素とスタイルです。基本的なレイアウトや装飾は、これらを組み合わせるだけで十分に実現できます。

分類 タグ/プロパティ 主な用途
レイアウト・テキスト <div>, <span>, <h1><h3>, <p>, <strong>, <a> など コンテンツの配置、テキストの装飾、リンク設定など、静的な表示の大部分をカバーします。
フォーム・ボタン <form>, <input>, <button> ユーザーからの入力を受け付けるフォームとして使用可能です。⚠️利用に制約があるため注意(後述)
リスト・テーブル <ol>, <li>, <table>, <tr>, <td> 箇条書きリストや、情報を整理して見せるための表を作成できます。
その他 <details>, <summary>, <hr>, <blockquote> アコーディオン(クリックで開閉)、区切り線、引用などを表現できます。
CSS (テキスト) font-family, font-size, color, text-align など フォントの種類、大きさ、色、行揃えといった、文字の見た目を自由に調整できます。
CSS (ボックス) padding, margin, border, width, displayなど 要素の余白、枠線、サイズなどを指定し、レイアウトを整えることができます。

⚠️ Difyで利用する際に注意が必要なポイント

次に、利用時に予期せぬ表示崩れなどを起こしやすい項目です。特にユーザーからの入力を受け付ける<form>タグ周りや、スタイルの適用範囲には独自の制約があります。

分類 対象 制限事項・注意点
フォームの構造 <form> タグの内部 フォーム内で使えるタグは基本的に<input>,<label>,<button>,<textarea>のみになっています。これ以外のタグをフォーム内に配置すると、レイアウト崩れを引き起こす原因となります。
フォームの装飾 <input> <button> <form> 内のパーツ(ボタンや入力欄)には、インラインCSS(style="...")が効きません。デフォルトのデザインが適用されます。
テキストの装飾 <p> タグ <p> タグにもインラインCSSは適用できません。文字色やサイズを変えたい場合は、<div><span> を代用してください。
フォームの個数 複数の <form> タグ 1つの出力内に複数の <form> を設置しても、システム上機能するのは1つだけです。原則として1出力につき1つに留めてください。
記述ルールの注意 タグ内の空行 タグの内部に空行が入ると、正しくレンダリングされないことがあります。コード内では不要な空行を避けて記述してください。

5.コピペで実装!UIレシピ集📖

ここまでで、UIをカスタマイズするための基礎知識は十分に揃いました。ここからは、それらを組み合わせて実際に使えるUIレシピをご紹介します。
紹介するコードは、Difyの回答ノードもしくはテンプレートノードにそのままコピー&ペーストし、テキストや色を少し調整するだけで簡単に利用できます。


ボタン

コード
<button data-message="試してみる">
  試してみる
</button>
解説
  • ボタン→<button>
    • 送信するメッセージの設定→data-message="試してみる"

↓実際の表示画面


入力フォーム

コード
<div style="background-color: #f8f9fa; border-radius: 12px; padding: 24px; font-family: sans-serif; max-width: 500px; margin: auto; border: 1px solid #dee2e6;">
  <form data-format='json'>
    <label for="email_input">メールアドレス (Email):</label>
    <input id="email_input" name="email_input" type="email" placeholder="メールアドレスを入力">
    <label for="password_input">パスワード (Password):</label>
    <input id="password_input" name="password_input" type="password" placeholder="パスワードを入力">
    <button type="submit">
      ログイン
    </button>
  </form>
</div>
解説
  • HTMLタグの説明
    • 外側のブロック→<div>
    • フォーム→<form>
      • データ形式→data-format='json'(※下に説明追記)
    • 各入力欄のタイトル→<label>
      • 入力欄の識別子と連携→for="email_input"
    • 各入力欄→<input>
      • 入力欄の識別子→id="email_input"
      • データを送信した時の名前→name="email_input"
      • 入力欄の種類→type="email"
      • 入力のヒント→placeholder="メールアドレスを入力"
  • インラインCSSの説明
    • 背景色→background-color: #f8f9fa
    • 角を丸くする→border-radius: 12px
    • 内側の余白→padding: 24px
    • フォントの設定→font-family: sans-serif
    • 横幅の最大値を制限→max-width: 500px
    • 画面内の配置→margin: auto
    • 枠線の設定→border: 1px solid #dee2e6
【解説】data-format='json'とは?

通常、<form> タグで入力された内容は、以下のようにテキストが送信されます。

ここに <form data-format='json'> と記述すると、入力された複数の項目が JSON形式(キーと値がペアになったデータ形式) にひとまとめにされて送信されます。

↓実際の表示画面


コード
<table style="width: 100%; border-collapse: collapse; text-align: left; border: 1px solid #e9ecef;">
  <thead>
    <tr style="background-color: #f8f9fa; border-bottom: 2px solid #dee2e6;">
      <th style="padding: 20px 24px; vertical-align: middle; white-space: nowrap;">プラン</th>
      <th style="padding: 20px 24px; vertical-align: middle; white-space: nowrap;">料金</th>
      <th style="padding: 20px 24px; vertical-align: middle; width: 100%;">主な機能</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="padding: 20px 24px; vertical-align: middle;">ベーシック</td>
      <td style="padding: 20px 24px; vertical-align: middle;">¥980/月</td>
      <td style="padding: 20px 24px; vertical-align: middle;">基本的な機能、メールサポート</td>
    </tr>
    <tr style="background-color: #f8f9fa;">
      <td style="padding: 20px 24px; vertical-align: middle; font-weight: bold;">プレミアム</td>
      <td style="padding: 20px 24px; vertical-align: middle; font-weight: bold;">¥2,980/月</td>
      <td style="padding: 20px 24px; vertical-align: middle; font-weight: bold;">全ての機能、電話サポート</td>
    </tr>
  </tbody>
</table>
解説
  • HTMLタグの説明
    • 表全体→<table>
    • ヘッダー(見出し)エリア→<thead>
    • ボディ(中身)エリア→<tbody>
    • 行(横の並び)→<tr>
    • データセル→<td>
  • インラインCSSの説明
    • 全体の横幅→width: 100%
    • 枠線の隙間をなくす→border-collapse: collapse
    • 文字の横方向の配置→text-align: left
    • 外枠の設定→border: 1px solid #e9ecef
    • 背景色→background-color: #f8f9fa
    • ヘッダー下の線→border-bottom: 2px solid #dee2e6
    • 内側の余白→padding: 20px 24px
    • 縦方向の配置→vertical-align: middle
    • 文字の折り返しを禁止→white-space: nowrap
    • この列の幅を優先的に広げる→width: 100%
    • 文字を太くする→font-weight: bold

↓実際の表示画面


ボックス1

コード
<div style="display: flex; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); font-family: sans-serif; overflow: hidden;">
  <div style="background-color: #4caf50; padding: 16px; color: white;">
    <strong style="font-size: 24px;">✓</strong>
  </div>
  <div style="padding: 12px 16px; color: #388e3c; line-height: 1.6;  background-color: #e8f5e9;">
    <strong>分析完了:</strong> アップロードされたPDFの読み込みが完了しました。この内容について質問できます。
  </div>
</div>
解説
  • HTMLタグの説明
  • ブロック→<div>
  • 強調→<strong>
  • インラインCSSの説明
    • 要素を横並びにする→display: flex
    • 角を丸くする→border-radius: 8px
    • 影をつける→box-shadow: 0 2px 4px rgba(...)
    • フォントの設定→font-family: sans-serif
    • 枠からはみ出た部分を隠す→overflow: hidden
    • 背景色→background-color: #4caf50
    • 内側の余白→padding: 16px
    • 文字色→color: white
    • 文字サイズ→font-size: 24px
    • 行の間隔→line-height: 1.6

↓実際の表示画面


ボックス2

コード
<div style="border: 1px solid #dc3545; border-radius: 8px; margin-bottom: 15px; font-family: sans-serif; line-height: 1.6; overflow: hidden; box-shadow: 0 4px 8px rgba(220, 53, 69, 0.1);">
  <div style="background-color: #dc3545; color: white; padding: 10px 15px; font-weight: bold;">
    🚫 エラーが発生しました
  </div>
  <div style="padding: 15px; color: #721c24; background-color: #f8d7da;">
    APIキーが無効です。設定を確認し、再度お試しください。
  </div>
</div>
解説
  • HTMLタグの説明
    • ブロック→<div>
  • インラインCSSの説明
    • 枠線→border: 1px solid #dc3545
    • 角を丸くする→border-radius: 8px
    • 下側の余白→margin-bottom: 15px
    • フォントの設定→font-family: sans-serif
    • 行の間隔→line-height: 1.6
    • 枠からはみ出た部分を隠す→overflow: hidden
    • 影をつける→box-shadow: 0 4px 8px ...
    • 背景色→background-color: #dc3545
    • 文字色→color: white
    • 内側の余白→padding: 10px 15px
    • 文字を太くする→font-weight: bold

↓実際の表示画面


カード

コード
<div style="display: flex; gap: 20px; align-items: stretch; font-family: sans-serif;">
  <div style="flex: 1; background-color: #ffffff; border: 1px solid #e0e0e0; border-radius: 12px; padding: 24px; text-align: center; display: flex; flex-direction: column;">
    <div style="text-align: right; margin: -12px -12px 12px 0;">
      <span style="background-color: #007bff; color: white; padding: 4px 10px; font-size: 12px; font-weight: bold; border-radius: 12px; visibility: hidden">おすすめ</span>
    </div>
    <h3 style="margin: 0 0 8px 0; font-size: 20px; color: #333;">💬 ベーシックモード</h3>
    <div style="font-weight: bold; color: #111; margin: 0 0 24px 0;">
      やさしく案内
    </div>
    <ul style="text-align: left; list-style-type: none; padding: 0; margin: 0 0 32px 0; color: #555; line-height: 2;">
      <li>✅ シンプルでわかりやすい回答</li>
      <li>✅ 丁寧なガイドつき説明</li>
      <li>✅ 難しい専門用語は使わない</li>
    </ul>
    <div style="margin-top: auto;">
      <button data-message="basic mode">
        このモードで会話する
      </button>
    </div>
  </div>
  <div style="flex: 1; background-color: #ffffff; border: 2px solid #007bff; border-radius: 12px; padding: 24px; text-align: center; display: flex; flex-direction: column; box-shadow: 0 8px 16px rgba(0,123,255,0.1);">
    <div style="text-align: right; margin: -12px -12px 12px 0;">
      <span style="background-color: #007bff; color: white; padding: 4px 10px; font-size: 12px; font-weight: bold; border-radius: 12px;">おすすめ</span>
    </div>
    <h3 style="margin: 0 0 8px 0; font-size: 20px; color: #333;">⚡ プロモード</h3>
    <div style="font-weight: bold; color: #007bff; margin: 0 0 24px 0;">
      高速・詳細応答
    </div>
    <ul style="text-align: left; list-style-type: none; padding: 0; margin: 0 0 32px 0; color: #555; line-height: 2;">
      <li>✅ より深い専門知識に対応</li>
      <li>✅ 高速な応答と正確な出力</li>
      <li>✅ テクニカルな話題や開発支援に最適</li>
    </ul>
    <div style="margin-top: auto;">
      <button data-message="pro mode">
        このモードで会話する
      </button>
    </div>
  </div>
</div>
解説
  • HTMLタグの説明
    • ブロック→<div>
    • 見出し→<h3>
    • 「おすすめ」などのバッジ→<span>
    • 特徴の箇条書きリスト→<ul>
    • リストの各項目→<li>
    • ボタン→<button>
      • 送信するメッセージの設定→data-message="basic mode"
  • インラインCSSの説明
    • レイアウト関連
      • 要素を横並びにする→display: flex
      • カードの高さを揃える→align-items: stretch
      • カード間の隙間→gap: 20px
      • 均等な幅で広げる→flex: 1
      • カードの中身を縦積みにする→flex-direction: column
      • 要素を下端に押し下げる→margin-top: auto
    • 装飾・表示関連
      • 影をつける→box-shadow: 0 8px 16px ...
      • 角を丸くする→border-radius: 12px
      • 要素を隠すが場所は確保する(高さ揃え用)→visibility: hidden
      • 枠線の設定→border: ...
      • リストの・(点)を消す→list-style-type: none

↓実際の表示画面

6. 応用編:動的UIの作成方法

ここまで、様々なHTML・CSSの使い方を解説しました。これらを活用するだけでも表現の幅は大きく広がりますが、Difyの他の機能と組み合わせることで、さらに高度な動的UIを作成することが可能になります。

動的UIとは?

「動的UI」とは、ユーザーの入力内容に応じて、表示される内容やデザインがその都度変化するインターフェースのことです。
例えば、以下のようなものが作れるようになります。

  1. 英単語学習カード
    • ユーザーが入力した「単語」に対し、AIが生成した「意味」「発音記号」「例文」を、カード形式のデザインに当てはめて出力する。
  2. AIレシピ提案カード
    • 冷蔵庫にある食材を入力すると、「料理名」「調理時間」「難易度」に加え、材料リストを綺麗に整形して表示する。

これらは単にテキストを表示するだけでなく、LLMが生成したデータをHTMLのテンプレートに流し込むことで実現します。

実現するための3つのステップ

動的UIを作るための基本的な流れは以下の通りです。

  1. LLMノード: ユーザーの入力を受け取り、JSON形式で構造化データを出力する。
  2. テンプレートノード: Jinja2を使って、HTMLの中にデータを埋め込む。
  3. 回答ノード: 完成したHTMLをユーザーに表示する。

今回は、英単語学習カードを作成するための具体的な手順を見ていきましょう。


STEP 1:LLMノードで「構造化データ」を作る

通常のチャットではLLMは文章を返しますが、今回はデータを扱いやすくするために、JSON(ジェイソン) というデータ形式で出力させます。

DifyのLLMノードの設定で、「出力変数」の「構造化出力」(モデルによっては「JSONモード」)をONに設定し、どのようなキー(項目)で出力するかをプロンプトで指示します。


LLMノードでの出力変数の設定画面

【用語解説】構造化出力とは?

構造化出力とは、AIの回答を「文章」ではなく、「タイトル」「本文」「スコア」といった決まった項目ごとのデータとして出力させる技術です。これにより、デザインの決まった場所に決まった内容を確実に表示できるようになります。
詳しくは弊社の構造化出力解説記事(こちら)をご覧ください。


STEP 2:テンプレートノードでHTMLとデータを合体させる

次に、「テンプレートノード」を使用します。ここで登場するのが Jinja2(ジンジャーツー) です。Jinja2を使うと、{{ word }} のように二重の中括弧で囲んだ部分を、実際のデータ(例:apple)に置き換えることができます。

コード例:英単語カードのテンプレート

以下は、LLMから受け取った word(単語)、meaning(意味)、example(例文)というデータを埋め込むためのHTMLコードです。

<div style="border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; background-color: #ffffff; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); font-family: sans-serif; max-width: 400px;">
  <div style="border-bottom: 2px solid #3b82f6; padding-bottom: 10px; margin-bottom: 15px;">
    <h2 style="margin: 0; color: #1f2937; font-size: 24px;"> {{ word }} </h2>
  </div>
  <div style="margin: 0 0 15px 0; color: #4b5563; font-weight: bold;">
    意味: <span style="color: #111827;">{{ meaning }}</span>
  </div>
  <div style="background-color: #f3f4f6; padding: 12px; border-radius: 8px; font-size: 14px; color: #374151;">
    <strong>例文:</strong>
    <br>
    <em>{{ example }}</em>
  </div>
</div>


テンプレートノードの設定画面

【用語解説】Jinja2とは?

Jinja2とは、Pythonでよく使われる「テンプレートエンジン」です。あらかじめ用意したHTMLの雛形(テンプレート)の中に、データを埋め込むための穴を作ることができます。
詳しくは弊社のJinja2解説記事(こちら)をご覧ください。


STEP 3:回答ノードで出力する

最後に、テンプレートノードの出力を「回答ノード」に接続して完了です。
以下のように、ユーザー側にはHTMLタグやJinja2の記号は表示されず、デザインされたきれいなカードだけを表示することができます。


実際の出力画面


7.すぐ作れる!UI生成プロンプト & デザイン見本帳🎨

ここまでHTMLやCSSの解説をしてきましたが、正直なところ「Dify特有の制約(pタグ禁止、インラインCSS限定など)を守りながらコードを書くのは面倒!」と感じた方も多いはずです。
そこで最後に、皆さんがすぐにリッチなDifyアプリを作れるよう、2つの強力なツールをご用意しました。

1. Dify専用 UI生成プロンプト

これはChatGPTやGeminiなどのAIに、「こんなデザインを作って」と頼むだけで、Difyの仕様に準拠したHTMLコードを一発で生成するプロンプトです。
通常、Dify用のコードを書くには様々な細かいルールを守る必要がありますが、このプロンプトを使えばAIがそれらを全て自動で処理してくれます。

📌 Dify専用HTML生成プロンプト(クリックしてコピー)
# 命令
あなたはHTMLベースのUIを生成するエンジンです。ユーザーから与えられる指示に基づき、単一のHTMLフラグメントだけを出力してください。説明文やマークダウン、プレーンテキストは一切出力せず、常にHTMLのみを返してください。以下の制約を厳密に守ってください。

## 全体ルール
- 出力は必ずMarkdownのコードブロックとして返すこと。先頭行に「```html」、最後の行に「```」のみを出力し、その間にHTMLフラグメントを書くこと
- コードブロックの外側には、いかなるテキスト(説明文・空行・コメントなど)も出力してはならない
- コードブロック内では、すべての行に対して、タグの親子関係(ネストの深さ)に応じたインデントを必ず行うこと。親要素よりも1段ネストが深い要素は、行頭に親要素より2文字以上多い半角スペースを追加し、さらにネストが1段深くなるごとに2文字以上の半角スペースを追加すること
- **重要**: 視認性のために改行は使用してもいいが、空行は一切使用してはならない(空行を表示する場合は<br>を使う)
- HTMLコメント(<!-- -->)を一切使用してはならない
- pタグ(<p>〜</p>)を一切使用してはならない。テキストはspan、div、label、buttonなどで表現すること
- htmlタグ(<html>〜</html>)およびbodyタグ(<body>〜</body>)は一切使用してはならない
- CSSは必ずインラインCSS(style属性)だけを使用し、<style>タグや外部CSSは使用しないこと
- 必要に応じてdiv、span、h1〜h6、ul、ol、li、img、a、button、table、thead、tbody、tr、th、tdなどは使用してよいが、pタグ・htmlタグ・bodyタグは禁止とする
- JavaScriptは一切出力しないこと(<script>タグやインラインイベントハンドラonclickなどは使用しない)

## フォームに関するルール
- formタグを使用するときは、必ず <form data-format="json"> の形で開始し、data-format属性は"json"固定とする
- formタグとその中の子タグはすべてインラインCSS(style)を一切使用してはいけない
- formタグの中では、以下に挙げるタグのみを使用してよい
  - <textarea>
  - <label>
  - <input>
  - <button>
- formの子要素としてdivやspanなどを追加してはならない(ネストも含めて禁止)
- formタグ内で使用可能な要素は次のとおり(必要に応じて繰り返し使用してよい)。type属性は変更してはならないが、for/name/data-options/data-tip/data-size/data-variantなどは要件に応じて変更してよい。
  - <label for="username">Username:</label>
  - <input type="text" name="username" />
  - <label for="password">Password:</label>
  - <input type="password" name="password" />
  - <label for="content">Content:</label>
  - <textarea name="content"></textarea>
  - <label for="date">Date:</label>
  - <input type="date" name="date" />
  - <label for="time">Time:</label>
  - <input type="time" name="time" />
  - <label for="datetime">Datetime:</label>
  - <input type="datetime" name="datetime" />
  - <label for="select">Select:</label>
  - <input type="select" name="select" data-options='["hello","world"]'/>
  - <input type="checkbox" name="check" data-tip="By checking this means you agreed"/>
  - <button data-size="small" data-variant="primary">Login</button>

### フォーム要素のカスタマイズルール
- label要素のfor属性、およびテキスト内容("Username:"など)は、画面仕様に合わせて自由に変更してよい
- input/textarea要素のname属性も、画面仕様に合わせて変更してよい
- select用input(type="select")のdata-options属性は、有効なJSON配列文字列として変更してよい(例: data-options='["option1","option2"]')
- checkboxのdata-tip属性も、説明文に応じて変更してよい
- buttonのテキスト("Login"など)、data-size、data-variantも、用途に応じて変更してよい
  - buttonタグ内で使えるdata-sizeは[small, medium, large]
  - buttonタグ内で使えるdata-variantは[primary, secondary, tertiary, warning]

## 表(table)のデザイン
- 表を作成する場合は、必ず<table>、<thead>、<tbody>、<tr>、<th>、<td>を使用すること
- table要素には、次のstyle属性を基本として指定すること: style="width: 100%; border-collapse: collapse; text-align: left; border: 1px solid #e9ecef;"
- thead内のヘッダー行(<tr>)には、次のstyle属性を指定すること: style="background-color: #f8f9fa; border-bottom: 2px solid #dee2e6;"
- ヘッダーセル(<th>)には、次のスタイルを基本とすること: padding: 18px 24px; color: #495057; font-weight: 600; font-size: 15px; white-space: nowrap;
- 列ごとの整列や幅が必要な場合は、以下を適宜追加してよい:
  - 中央揃えにしたい列: text-align: center;
  - 内容を広くとりたい列: width: 100%;
- 本文行(<tbody>内の<tr>)では、次のスタイルを基本とすること:
  - 通常行: <tr> または <tr style="">(style省略可)
  - 強調したい行・ハイライト行: style="background-color: #f8f9fa;"
- データセル(<td>)には、次のスタイルを基本とすること: padding: 20px 24px; border-bottom: 1px solid #f1f3f5; vertical-align: middle;
  - テキストを標準で表示するセル: color: #555; または color: #333; を適宜使用
  - 金額や数値など中央揃えにしたいセル: text-align: center; font-size: 16px; を指定
  - 強調したいセル(重要な行・プラン名など)は font-weight: 500 または bold を指定してよい
- 列数やヘッダ名、セルのテキスト内容は、画面仕様に合わせて自由に変更してよいが、上記のスタイル方針(余白・境界線・背景色・フォントの雰囲気)に沿って統一感のある表を作成すること

## レイアウトとスタイル
- レイアウトやデザインが必要な場合は、すべて各要素のstyle属性にインラインCSSで指定すること
- 文字色、背景色、余白、フォントサイズ、幅、高さ、ボーダー、配置などのスタイル調整はすべてインラインCSSで行う
- form外ではdivやtableなどを自由に使用してレイアウトしてよいが、form要素の内側では前述の許可されたタグ以外を使用してはならない

## 出力フォーマット
- 出力は常に1つのHTMLフラグメントのみとし、余計な説明文やサマリーテキストを含めない
- <html>、<body>、<!DOCTYPE html> などのドキュメント全体に関するタグは出力せず、部分的なHTMLフラグメントとして出力すること

ユーザーから画面仕様やフィールド定義が与えられた場合は、上記の制約を守りながら、その仕様に最も合うUIをHTMLで構築してください。

💡 おすすめの使い方

【基本の使い方】
以下のプロンプトをコピーして、AIとのチャットの一番最初に貼り付けてください。その後に、「青いボタンがついたログインフォームを作って」などと指示すれば、すぐに使えるコードが生成されます。

【もっと便利に】
もしChatGPTのGPTs、GeminiのGems、ClaudeのProjectsなどの機能をお使いの場合は、このプロンプトをカスタム指示(Instructions)として登録してDify UI生成ボットを作成してしまうのが最もおすすめです。こうすることで、毎回プロンプトをコピペする手間が省け、いつでも呼び出してUIを作れるようになります。

たとえばこのプロンプトに、「ファーストフード店の注文画面のようなUIを作成して」と指示をするだけで、以下のようにDify上で表示することのできる綺麗なUIを作成してくれます。

2. そのまま使えるデザイン見本帳(DSL)

ここでは、本記事で紹介したMarkdown・HTML・CSSなどのデザイン事例を詰め込んだDifyアプリのDSLファイルを用意しました。

https://gist.github.com/kawawa222/60e5686c0b98b22b14dd7ead38bdf756

これをDifyにインポートするだけで、あなたのDify環境に「デザイン見本帳」アプリが立ち上がります。実際に動く画面を見ながらコードをコピーできるので、辞書代わりにお使いください!


DSLファイルの実用例

8. まとめ🎯

今回は、Markdownの限界を超え、DifyアプリのUIを劇的に向上させるためのHTMLとCSS活用術を、具体的なレシピとともに紹介しました。
この記事のポイント:

  • HTMLでレイアウトを自在に構築<div><table> を活用すれば、より複雑で柔軟な構造が作れます。
  • CSSでリッチなデザインを実現:色・余白・配置を細かく調整でき、UIの印象を大きく向上させられます。
  • 応用テクニックを用いて動的UIを作成:LLMの出力に合わせてUIの中身を変化させることで、より実用的なアプリが作れます。

まずはUI生成プロンプトデザイン見本帳をぜひ試してみてください。
テキストや配色を変えてみるだけでも、UIを考える楽しさを感じられると思います!

UPGRADE tech blog

Discussion