
ChatGPTで生成したHTMLは正しいのか、それとも“たまたま動いているだけ”なのか?
ChatGPTで生成したHTML、表示は崩れていない。エラーも出ていない。
それなのに、いまいち腑に落ちない。コードを読むのに時間がかかる。余計なコードが多くて、触るのが少し面倒。
そんな瞬間はありませんか?
ChatGPTで生成したHTMLには、「divが多い」「クラスが多い」「構造の意図が見えない」。
どれも致命的なバグではないのに、保守や拡張の場面でじわじわ効いてくるケースがあります。
この記事では、HTML / CSS / Bootstrap を実務で触っている人が感じがちな違和感を、
“生成AIの出力を採用していいか判断するための整理軸”としてまとめます。
今回の記事ではプロンプトやコーディングの技術的な解説の前に、
ChatGPTといった生成AIとコーディング業務を組み合わせる実務を行う場合に「この状況なら、こう考えると楽になる」という判断の仕方を一緒に整理していく内容です。
ChatGPTのHTMLが「読みにくくなる」構造的な理由
まず押さえておきたいのは、ChatGPTが出力するHTMLは
「コードを成立させること」を起点に組み立てられやすいという点です。
実務でHTMLを書くときは、情報の構造化を整理するため
「これは何の情報か」「どこまでが1つの意味か」を決めることが多いです。
たとえば、カードなのか、見出し+本文のセットなのか、
一覧の1項目なのか。ここが決まると、自然にタグや階層が固まっていきます。
一方で生成AIは、要求されたレイアウトを成立させるために、
要素を“箱”として足し引きしながら形にしていくことがあります。
その結果、見た目は整っていても、
情報のまとまり(意味の単位)がHTMLから読み取りにくい状態になりやすいです。
ここで地味に困るのが、保守のタイミングです。
「このブロックだけ余白を変える」「このパーツだけ別ページに持っていく」「この要素だけA/Bで差し替える」など、
実務の変更は“部分的”に起きます。
意味の単位が曖昧なHTMLだと、その部分的な変更がしにくくなります。
私自身、生成AIを利用してHTMLのコーディングを受け取ったときは、
コードがすっきりしていないから修正が面倒。このコードは不要ではないかと思う箇所が多く感じられ、
保守や修正時にあとで必ず迷うので、生成AIへプロンプトを与える前に構造を整えることから作業を進めたほうが結果的に楽でした。
divだらけのHTMLが生まれる思考のズレ
生成AIのコーディングで「動くけど読みにくい」HTMLの代表格が、divのネストが増えていくパターンです。
これは、生成AIがHTMLを“箱を重ねて形を作る道具”として扱いやすいことが背景にあります。
例えば、生成AIで「料金プランのセクションをコーディングしてほしい。」とだけプロンプトで指示した場合、以下のようなコードを生成する場合があります。
<div class="wrap">
<div class="price">
<div class="inner">
<div class="head">
<h3>料金プラン</h3>
</div>
<div class="body">
<div class="text">
<div><p>月額プランの説明が入ります。</p></div>
</div>
</div>
<div class="foot">
<div class="btn-wrap">
<a href="#" class="btn">詳しく見る</a>
</div>
</div>
</div>
</div>
</div>
例のようなコードで、実際に問題は無いのですが、余分なコードや、使わないクラスのコンテナもみられます。
生成AIの場合、明確な指示がなければ、生成AIが学習している確率と可能性を軸としてコードを積み重ねるため、divが積み重なる場合が多くなる傾向があります。
なぜ“箱を増やす”と読みにくくなりやすいのか
コードとして問題がなければいいのではないか。納期や修正の連続が続くと、納品してしまえば完了だからそのままにしてしまうケースもみられますが、保守や修正になるとコストがかかってしまう可能性もあります。
箱が増えるほど、人の目でみたときに、どこからどこまでが1セットなのかが曖昧になります。
さらに、責務が曖昧な中間divが増えると、CSSの当て先も曖昧になりやすく、迷いが多くなり余分な作業を増やしてしまう原因となってしまう可能性が高くなります。
そのまま進むと実務で起きやすいのは、修正のたびに「どこを触ればよいか」の探索コストが増えることです。
見た目の微調整が来たときに、深い階層を行ったり来たりしながら安全な当て先を探す。これが積み上がると、保守が重くなります。
普段エディターでコーディングしていると「divを足す前に、これは構造として必要な要素か?」を一度止まって考えるようにしている場合が多いと思います。
ここが曖昧なままだと、HTML側でレイアウトを解決してしまい、後からCSS側での整理がしにくくなることが多いのではないでしょうか。
具体的にどのパターンが“箱が増えやすい地雷”になりやすいかは、別の記事で例をまとめて整理します。
この記事ではまず「箱の増殖は、表示のための問題はないが、制作リソースを考慮すると遠回りになりやすい」という感覚を共有しておきたいです。
クラス設計に表れる「意図の欠落」
次に、見た目は整っているのに読みにくい理由として多いのが、クラス名から意図が読み取りにくいケースです。
生成AIの出力は、クラス名が“それっぽい”ことが多い分、逆に判断が難しくなることがあります。
実務で迷いやすいのは、クラスが「役割」「見た目」「状態」で混ざっているときです。
役割(この要素は何か)と、見た目(どう見せるか)と、状態(強調・選択・アクティブなど)が混ざると、再利用の判断がつきにくくなります。
具体的に生成されたコードをみるとこのようなケースがあります。
- content-box / title / text / btn が 抽象すぎて意味が読めない
- big-text / small-text / gray は見た目
- primary-btn はデザイン要素っぽい
- btn は役割
→ 命名思想がバラバラ
新しく「別のサービスカード」を追加した瞬間に「このクラス流用していい?」問題が発生したり、他のコンテンツとクラスが被るなどCSSによる拡張性が低いといった課題が出ていくる可能性が高くなります。
<div class="content-box text-center mt-3 mb-3 p-3">
<h3 class="title big-text mb-2">サービス名</h3>
<p class="text small-text gray mb-3">
サービス説明が入ります。テキスト量で高さが変わります。
</p>
<a href="#" class="btn primary-btn">お問い合わせ</a>
</div>
なぜ“混ざる”と判断が止まりやすいのか
たとえば、同じ見た目でも意味が違うことがあります。逆に、同じ意味でもページによって見た目が違うこともあります。
このとき、クラスが見た目に寄りすぎていると「別ページでも流用していいのか」が判断しにくくなります。
そのまま進むと実務で起きやすいのは、似たコンポーネントが増えるたびにクラスが増殖することです。
しかも、増えていくクラスが“どれも似た名前”になりやすく、後から読む人ほど迷います。これが「読みにくさ」の正体として現れます。
コードを読み解きながらクラス名を見た瞬間に「これは何の役割?」が言葉にならない場合、クラスの分解や命名の見直しから入ることが多いです。
ここを整えると、CSSの当て方も自然に整理されて、結果的に修正が速くなることが多かったです。
命名ルールそのもの(BEMや独自ルール)を押しつけたいわけではなく、
「意図が伝わる単位でクラスを付ける」ほうが、生成AIの出力を実務に持ち込みやすい、という整理です。具体的な命名の型は別の記事でまとめます。
Bootstrapと生成AIの相性が悪く見える理由
Bootstrapを使っている現場ほど、「読みにくさ」を強く感じることがあります。
それはBootstrapが単なる部品集ではなく、ユーティリティとコンポーネントの思想を含んだ設計だからです。
生成AIは、今このプロジェクトが「Bootstrapの思想に寄せるのか」「独自CSS中心でいくのか」を、会話の流れから完全には保持できないことがあります。
その結果、Bootstrapのクラスと独自クラスが混ざり、直し方の判断が止まりやすくなります。
具体的に生成されたコードをみるとこのようなケースがあります。
container / row / col-md-6 / d-flex / me-3 / p-3 といった Bootstrapの文脈がある
なのに service-area / service-box / service-left / service-right が入り、
Bootstrapコンポーネントとして揃えるのか、独自CSSでいくのか判断が曖昧で、CSS反映時に整理するのが面倒になる可能性が高くなります。
<div class="container my-4">
<div class="service-area row">
<div class="col-md-6">
<div class="service-box d-flex align-items-center p-3">
<div class="service-left me-3">
<img src="#" alt="icon">
</div>
<div class="service-right">
<h3 class="service-title h5 mb-1">サービスA</h3>
<p class="service-text mb-0">説明文が入ります。</p>
</div>
</div>
</div>
</div>
</div>
思想が混ざると、どこで直すかが決めにくい
たとえば、余白や配置の修正が来たとき、Bootstrapのユーティリティで整えるのか、独自CSSでコンポーネント側に閉じ込めるのか。
ここに一貫性がないと、修正のたびに「今回どっちでいく?」が発生します。これが読みにくさにも、保守コストにもつながります。
そのまま進むと実務で起きやすいのは、上書きが増えることです。
ユーティリティで作った見た目を、独自CSSで上書きして、さらにユーティリティを追加して…という往復が起きると、コードの意図が読めなくなります。
「このサイトはBootstrap寄せで作るのか、独自寄せで作るのか」を早めに決めた方が迷いが減ると感じています。
途中で混ざってしまった場合でも、まずは“どこから先をBootstrap側に寄せるか”を決めるだけで整理が進むことが多かったです。
生成AIのHTMLを実務で使うための判断の整理軸
生成AIは、最終成果物を自動で完成させる道具というより、判断材料を早く集める道具として使うと噛み合いやすいです。
その前提に立つと、「採用するか/手で直すか」の判断がしやすくなります。
生成AIでコーディングをする場合に整理の起点にしているのは、次の3点です。
完璧に満たす必要はなく、引っかかった箇所を“直す候補”として浮かび上がらせる目的で見ています。
- 意味の単位が読めるか(この塊は何を表しているかが言葉になるか)
- 責務が分かれているか(構造で解決しているのか、見た目で解決しているのかが混ざっていないか)
- 直し方が決められるか(Bootstrap寄せ/独自寄せなど、どの思想で触るかが決まるか)
この3点のうち、どれかが曖昧なときは、HTMLをそのまま採用しても「あとで迷う確率が高い」と判断しやすいです。
逆に、多少冗長でも意図が読めるなら、手で整える余地があり、保守の負担も読みやすくなります。
「どこまで直すと楽になるか」は、案件の規模や更新頻度で変わります。
ここは別の記事で、更新頻度やチーム体制ごとの線引きの考え方を整理します。シリーズとして読むと判断がしやすくなるように組み立てる予定です。
まとめ|HTMLは「読むための設計」として扱うと楽になる
ChatGPTが書いたHTMLが読みにくいと感じるのは、気のせいではありません。
表示の成立と、意図の伝達は別の問題で、実務では後者が効いてきます。
- divが増えると、意味の単位がぼやけやすい
- クラスが混ざると、再利用の判断が止まりやすい
- Bootstrapと独自CSSが混ざると、直し方の方針が揺れやすい
生成AIは便利ですが、最終判断は人が握る前提で考えると、使い方が安定します。
「動くかどうか」だけでなく、「読めるかどうか」を判断基準に入れると、保守・拡張のフェーズで楽になることが多いです。
次の記事では、生成AIの出力を“読めるHTML”に寄せる具体的な直し方を、手順として整理します。
この記事で紹介した判断の整理軸を、まずはあなたの手元のHTMLに当てはめてみてください。どこを直すと効くかが見えてくるはずです。




