しんたろーのITアカデミー
開発日記

「動く」と「使える」の絶望的な距離。Claude Codeの1人開発でスマホUIの違和感を潰した44連発の記録。

「動く」と「使える」の絶望的な距離。Claude Codeの1人開発でスマホUIの違和感を潰した44連発の記録。
しんたろーしんたろー
13分で読めます
この記事の内容(目次)

SNS運用を自動化しませんか?

ThreadPostなら、投稿作成・画像生成・スケジュール管理までAIがサポート。

無料で始める

核心回答:スマホUIの「使える」の壁

※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。

「動く」と「使える」の距離を埋めるUI修正
「動く」と「使える」の距離を埋めるUI修正

結論から。10本の投稿候補、やっと人に見せられるUIになった。

機能自体は2時間で完成した。でも、それをスマホで「使える」状態にするのに12時間かかった。

PCの広い画面では「ちゃんと動いてる」と思っていた。

スマホの実機で開いたら、パディングがはみ出し、文字が重なり、ボタンが消えていた。

Tailwind CSSでレスポンシブ対応をしたつもりだった。

だが、実際のスマホの画面幅は想定以上に狭く、情報量の多いSaaSの管理画面を押し込むのは至難の業だ。

地味でしんどいUI修正44連発の記録だ。

「動く」と「使える」の間には、絶望的な距離があった。

深掘り1:PC画面での快進撃とClaudeの魔法

開発の始まりは順調そのものだった。

「feat: 投稿候補の詳細検索機能を実装」

未承認、承認済み、却下済みの基本フィルターを作った。

キーワード検索も入れた。ペルソナ名や記事タイトルで一発で探せる。

S/A/Bのランクフィルターも追加した。

Claude Codeの生成速度は異常だ。数分で複雑なUIコンポーネントが組み上がる。

「feat: 詳細検索機能を大幅に拡充」

さらに欲が出た。文字数フィルターを追加した。

短文、標準、長文で絞り込めるようにする。

品質評価フィルターも一気に突っ込んだ。

リポスト、フック、反応予測、実用性、炎上リスク。

これら全てをチェックボックスで複数選択可能にした。

通常、これだけのフィルター条件を掛け合わせると、Reactのステート管理はしんどい。

複数の状態が絡み合い、再レンダリングの制御がカオスになる。

企業開発なら、要件定義とテストケース作成だけで数日は飛ぶと言われている。

僕はそれを数十分で突破した。

ただし、この後スマホUIで地獄を見る。

Zustandを使った状態管理のコードを、AIが一瞬で書き上げたからだ。

しんたろーしんたろー:
フィルターの状態管理、Redux時代ならボイラープレートだけで日が暮れてた。今はZustandとClaudeで一瞬。開発速度バグってる。

フィルターの状態はURLのクエリパラメータと同期させる必要があった。

ユーザーがページをリロードしても、検索条件を維持するためだ。

Zustandのミドルウェアを使って、URLとステートを自動同期させる仕組みを入れた。

これもClaude Codeに頼めば一瞬だ。

PCのブラウザで動かす。

完璧だ。サクサク絞り込める。

複数の条件を重ねても、瞬時にリストが絞り込まれる。

「fix: ensure loading state is reset in fetchCandidates using try-catch-finally」

ローディング状態のバグも潰した。

非同期処理のエラーハンドリングも完璧だ。

「feat: 投稿作成モーダルを統一しUX改善」

ついでに投稿作成のUIも改善した。

AI生成モードとテキスト入力モードを統一する。

モーダルの使い勝手が上がった。

「feat: 投稿作成をダイアログ形式に変更」

画面遷移なしで操作が完結する。シームレスな体験だ。

PCの広い画面の上では、世界最強のSaaSが完成したかのように思えた。

スマホで開くまでは。

深掘り2:スマホ実機確認で起きたUI崩壊

本日の開発スタッツ:UI微調整が大部分を占める
本日の開発スタッツ:UI微調整が大部分を占める

スマホで実機確認をした。

画面が崩壊していた。

「fix: Improve mobile UI for post candidates: fix image size, add sorting buttons, limit swipe」

フィルターのパネルが画面外に突き抜けている。

iOS Safari特有のボトムナビゲーションバーが計算を狂わせていた。

スクロールしようとしても、背景が固定されて動かない。

文字は無惨に折り返され、ボタンは重なり合って押せない。

機能を作る前に、スマホで崩れていないか確認しなかった僕のミスだ。

順番を完全に間違えていた。

僕は絶望しながらターミナルに戻った。

「fix: 投稿候補・スケジュール・履歴画面のフィルターをスクロール可能に改善」

フィルターの最大高さを画面の80vhに制限した。

オーバーフロー時にスクロールできるように修正する。

Claude Codeに「ここのマージン直して」と指示を出した。

直したという返答が来る。

スマホをリロードする。

隣のカードのレイアウトが完全に崩壊していた。

CSSの「flex」や「grid」は、親要素のコンテキストに強く依存する。

しんたろーしんたろー:
Claude、お前さぁ。直したって言ったじゃん。なんでヘッダーのボタン消えてるの?視力どうなってんの。

局所的なパディング調整が、子要素の計算幅を狂わせる。

"ここのマージン直して"→"直しました"。いや、隣のカード崩れてるじゃん。

あいつ、指定したコンポーネントしか見ていない。

「fix: スマホ表示の最適化とスケジュール日時の表示追加」

パディングを削る。アイコンのサイズを調整する。

「fix: アカウントバッジからプラットフォームアイコンを削除し、画像サイズを最適化」

余計な装飾を捨てた。画像サムネイルをコンパクトにした。

「fix: スマホ表示の余白を最小化と評価項目名を明確化」

評価項目の名前が長すぎた。

「リポスト可能性」を「拡散性」に縮めた。

「フック強度」を「掴み力」に変えた。「エンゲージメント予測」は「反応率」にした。

文字数を減らさないと、スマホの横幅には絶対に収まらない。

日本語は漢字の密度が高く、変な場所で折り返される。

「fix: 評価項目名を設計書通りに修正」

設計書の定義とずれたので、再度修正した。

「リポスト」「フック」「炎上」など、極限まで短い単語に切り詰めた。

ラベル幅を固定して、レイアウトのガタつきを防ぐ。

「fix: 詳細評価を右寄せに変更」

スマホでは縦に並べ、PCでは左右に分ける。レスポンシブの泥沼だ。

「fix: 詳細評価の間隔を修正」

バッジとラベルの間隔を1ピクセル単位で調整する。

「fix: 投稿先ラベルの改行を防ぐ」

「fix: 生成日時の改行を削除」

改行をひたすら潰していく。

機能実装の爽快感はとうに消え失せていた。

「fix: 承認/却下ボタン押下時の画面再読み込み問題を修正」

ボタンを押すたびに画面が真っ白になる現象も直した。

全データの再取得をやめる。

ステートの更新だけで画面を書き換える。

ただひたすら、1ピクセルのズレと戦う虚無の時間。

44回のコミット。そのほとんどが、この地味で泥臭いUI調整だった。

落とし穴:省略表示の罠とパディングの限界

スマホでアカウント名が長すぎてレイアウトが崩れるのを防ごうとした。

CSSの「truncate」をかけた。

テキストがコンテナ幅を超えたら「...」で省略する便利なプロパティだ。

今度はアカウント名が短すぎて何のアカウントか判別不能になった。

「ThreadPost...」なのか「ThreadPost_Dev...」なのか分からない。

複数アカウントを運用するSaaSで、アカウント名が読めないのは致命的だ。

さらに、flexboxの子要素で「truncate」を効かせるには「min-width: 0」が必要になる。

flexboxの仕様上、子要素はコンテンツの最小幅より小さくならないからだ。

いくら「truncate」をかけても、テキストの長さに合わせて親要素ごと押し広げられてしまう。

この仕様を忘れていて、レイアウトがさらに崩壊する二次災害も起きた。

「fix: アカウント名の省略表示を削除」

結局、省略せずに全文表示する。

その代わり、青い背景部分のパディングを極限まで削るという「力技」に落ち着いた。

「fix: 青い背景部分のパディングを最小化」

外側のコンテナのパディングを極限まで薄くする。

スマホの貴重な横幅を、1ミリでも多くコンテンツに割り当てる。

一般的に、モバイルデザインでは画面端に最低でも16pxの余白を取るのがセオリーと言われている。

だが、情報量が多いSaaSの管理画面では、そのセオリーが足枷になる。

セオリーを捨てて、実用性を取った。

スマートな解決策ではない。

ただ、ユーザーにとっては「読める」ことが全てだ。

しんたろーしんたろー:
truncate使えば一発解決だと思った僕が浅はかだった。結局パディング削る力技。スマートさゼロで泣ける。

ここまで読んだあなたに

今なら無料で全機能をお試しいただけます。設定後はAIが投稿案を毎日生成。確認して選ぶだけ。

無料で始める

今日の数字

| 項目 | 今回の数字 | 比較対象 |

|---|---|---|

| 機能実装 | 2時間 | 企業なら1週間 |

| UI微調整 | 12時間 | 機能実装の6倍 |

| コミット数 | 44件 | 通常の機能追加は5-10件 |

44回のUI修正は、小規模アプリの画面全体をリニューアルする工数に匹敵する。

機能実装が2時間。UIの微調整が12時間。比率にして1:6だ。

バックエンドのロジックやAIの連携は、驚くほどの速度で作れる。

だが、最後の1ミリの違和感を潰す作業は、人間の目と手でやるしかない。

「動く」を作るのは一瞬。

「使える」にするのは泥臭い。

未解決の伏線

画像サムネイルの読み込み速度がまだ怪しい。

10枚の画像をグリッド表示すると、スクロールが一瞬カクつく。

DOMの再描画コストがどこかで跳ねている気がする。

FAQ

Q: APIの負荷軽減のためにどのような工夫をしていますか?

A: 画面更新時の全データ再取得を廃止し、フロントエンドのステート更新のみに変更した。これにより不要なネットワークリクエストが消え、バックエンドのDBクエリ負荷も下がった。UX向上とインフラコスト削減を同時に実現できる。

Q: CSSの設計思想において、コンポーネントの再利用性をどう保っていますか?

A: 余白をコンポーネント内部に持たせず、親要素のレイアウトコンテナで制御している。内部に余白をハードコードすると、別の文脈で配置した途端にレイアウトが破綻する。一般的に、コンポーネントは自身の外側の空間に関与しない設計が良いと言われている。

Q: モバイルファーストの判断基準として何を最も重視していますか?

A: ユーザーの親指が届く範囲と、スクロールを阻害しない要素の配置だ。特にフィルターやモーダルは、画面高の80%以内に収めないとOS標準のジェスチャーと衝突する。企業開発でも、このタップ領域の設計ミスが離脱率悪化の最大要因と言われている。

まとめ

機能を作るより、余白を1ピクセル削る方が時間がかかる。

👉 ThreadPostでSNS運用を自動化する

ThreadPost — SNS投稿をAIが自動化

この記事が参考になったら、ThreadPostを試してみませんか?投稿作成・画像生成・スケジュール管理まで、AIがサポートします。

無料で始める

この記事をシェア

XはてブLINE
しんたろー

ThreadPost開発者・個人開発エンジニア

AI × SaaS個人開発者。Cursor / Claude Code を使った効率的開発、SNS自動化について実体験から発信。

人気の記事