📑

印刷時にabsoluteで配置した要素が切れる問題と解決方法

に公開

はじめに

Webページで「NEW」や「SALE」などのバッジをカードの角に配置することはよくありますよね。
その場合はCSSのposition: absoluteを使えば簡単に実装できます。
また、印刷時にコンテンツが途中で切れる問題は、通常以下のCSSで解決できます:

@media print {
  .no-break {
    page-break-inside: avoid;
    break-inside: avoid;
  }
}

しかし、position: absoluteで配置した要素(バッジなど)は、このCSSでは保護されず切れてしまうという問題がたまにあります。
この記事では、その原因と解決方法を紹介します。

問題例

印刷プレビューで見ると、バッジ(NEW)が切れています。

原因

  • position: absoluteで配置された要素は、親要素のボックスモデルの外側に配置される
    印刷時の改ページ処理は、親要素のボックスサイズしか考慮しない
    そのため、はみ出したバッジが切れてしまう

  • break-inside: avoidは親要素の分割は防ぎますが、親要素の外側にあるabsolute要素は保護してくれません

解決方法

対応策:印刷時用のcssにpadding + margin で物理的なスペースを確保する

/* 印刷時のスタイル(解決版) */
@media print {
  .card-wrapper-fixed {
    page-break-inside: avoid;
    break-inside: avoid;
    
    /* ★ ここがポイント ★ */
    padding-top: 30px !important;     /* バッジが入るスペースを確保 */
    margin-top: -15px !important;     /* 視覚的な位置を調整 */
  }

解決のポイント

padding-topでバッジが入る物理的なスペースを確保
margin-topで視覚的な位置を調整(完全にpaddingの値を打ち消さないのがコツ)

この2つの組み合わせで、デザインを崩さずに印刷時もバッジが切れなくなります(値はデザインによって調整)。

以下のサイトで実際にコードを確認できます:
🔗 StackBlitz: https://stackblitz.com/edit/vitejs-vite-znzszkqj?file=src%2FApp.css

Discussion