Prettier で HTML を整形しただけでデザインが崩れることがある

1 min読了の目安(約1400字TECH技術記事 2

概要

コードフォーマッタの Prettier (v2.2.1) でコードを整形しただけで、Web上でのデザインが崩れてしまった事例を紹介します。

元 HTML

<body>
  <div class="content">
    <div class="div-a">A</div><div class="div-b">B</div>
  </div>
</body>

オリジナルの HTML は div 内に div が複数あるだけのシンプル構造です。

Prettier 適用後

<body>
  <div class="content">
    <div class="div-a">A</div>
    <div class="div-b">B</div>
  </div>
</body>

デフォルト設定の Prettier を HTML に実行すると、1行に複数の div を記述していた箇所が、改行で分割されます。

フォーマット前後でデグレが発生

フォーマッターを適用しただけなら挙動は変わらないと思い込んでいましたが、動作を確認してみると、フォーマット前後で以下のようなデグレが発生していました。

フォーマット前

フォーマット後

原因

A B が横並びで表示されている時点で察した方もいると思いますが、この HTML ファイルは以下のようなスタイルが適用されていました。

<style>
  .div-a,
  .div-b {
    display: inline;
  }
</style>

これによって、 .div-a .div-b は、インライン要素となってしまい、改行が半角スペースとして扱われるようになってしまいました。

Prettier から見れば、 div はブロック要素なのだから改行してフォーマットを整えても影響は無いと判断していたようです。

解決策

要素のデフォルトの display 属性を無闇矢鱈を変えるものじゃないなと学んだので、 display: inline の設定を削除し、横並びのスタイルを維持するために flex を活用するようにすることで、デザインを維持しながらコードのスタイルを自動修正できるようにしました。

<style>
  .content {
    display: flex;
  }
</style>

学んだこと

ただのフォーマッタだからって、プロジェクト全体に Prettier をまとめて実行すると事故ることがある。

  • 本業では、ここまで単純な話ではなく、入り組んだコードの中でこのような問題が意図せず発生していました
  • ちなみにスナップショットテストがちゃんと機能して差分を検知してくれたので、デグレがリリースされることはありませんでした。