1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CSSのフレックスボックスを使って複数iframeを1枚に印刷する

Last updated at Posted at 2024-12-13

はじめに

iframeを使ったページを印刷するときに、複数ページに分かれて困ったことはありませんか?これをCSSのフレックスボックスで解決できたので共有します。

※この記事はCSSやiframeの知識が初心者を想定して書いてあります。

ブラウザ環境

Chrome バージョン: 131.0.6778.140(Official Build) (64 ビット)を使って検討しました。Edgeではうまく動作しませんでした。

実行結果

次に示すコードを使うと、4つのiframeを縦に2つ、横に2つならべて表示します。印刷したときも同様のレイアウトで1ページに印刷します。

できあがったコード

まずは全体でどのようなコードになったのか示します。

<!DOCTYPE html>
<html>
<head>
    <title>Embed map</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { margin: 0; padding: 0; }
        .container {
            display: flex;
            flex-direction: column; /* 縦方向に配置 */
            height: 100vh;
        }
        .row {
            display: flex;
            flex-direction: row; /* 横方向に配置 */
            width: 100%;
            height: 50%; /* 高さを50%に設定 */
        }
        iframe {
            width: 100%;
            height: 50vh; /* 縦並びのiframeの高さを設定 */
            border: none;
        }
        .half-width-iframe {
            width: 50%; /* 横並びにするための幅 */
            height: 100%; /* 高さを100%に設定 */
            page-break-inside: avoid; /* ページ内での分割を避ける */
        }
        @media print {
            .container {
                height: auto;
                display: block; /* 印刷時にブロック要素として扱う */
            }
            .row {
                display: flex;
                flex-direction: row; /* 印刷時にも横方向に配置 */
                height: auto; /* 高さを自動調整 */
                page-break-inside: avoid;
                page-break-after: auto;
            }
            iframe {
                width: 100%; /* 縦並びのiframeの幅を100%に設定 */
                height: auto; /* 印刷時に高さを自動調整 */
                page-break-inside: avoid; /* ページ内での分割を避ける */
            }
            .half-width-iframe {
                width: 50%; /* 横並びのiframeの幅を設定 */
                height: auto; /* 高さを自動調整 */
            }
        }
    </style>
</head>
<body>
    <h3>名前:〇〇〇〇 xxxx年xx月レポート</h3>
    <div class="container">
        <iframe src="./map_tate.html"></iframe>
        <iframe src="./graph_tate.html"></iframe>
        <div class="row">
            <iframe src="./map_yoko.html" class="half-width-iframe"></iframe>
            <iframe src="./graph_yoko.html" class="half-width-iframe"></iframe>
        </div>
    </div>
</body>
</html>

コードの説明

ポイントを説明します。

<!DOCTYPE html>
  • HTML5以降を使用していることを宣言

<head>セクション

<meta charset="utf-8">
  • 文字エンコーディングをUTF-8に設定
<meta name="viewport" content="width=device-width, initial-scale=1.0">
  • レスポンシブデザインのためにビューポート設定
  • content=width=device-width:ページがデバイスの画面幅に合わせて表示
  • initial-scale=1.0:初期表示は100%表示

<style> セクション

        body { margin: 0; padding: 0; }
  • body:デフォルトのマージンを削除、ページ全体の余白とパディングを0に設定
        .container {
            display: flex;
            flex-direction: column; /* 縦方向に配置 */
            height: 100vh;
        }
  • .container:縦方向のフレックスボックスレイアウトを設定し、コンテンツ全体の高さをビューポートの高さに設定
        .row {
            display: flex;
            flex-direction: row; /* 横方向に配置 */
            width: 100%;
            height: 50%; /* 高さを50%に設定 */
        }
  • .row:横方向のフレックスボックスレイアウトを設定し、行の高さをビューポートの50%に設定
        iframe {
            width: 100%;
            height: 50vh; /* 縦並びのiframeの高さを設定 */
            border: none;
        }
  • ifram:各iframeの幅を100%に設定、高さを50vh(ビューポート高さの50%)に設定
        .half-width-iframe {
            width: 50%; /* 横並びにするための幅 */
            height: 100%; /* 高さを100%に設定 */
            page-break-inside: avoid; /* ページ内での分割を避ける */
        }
  • .half-width-iframe:横並び用のiframeの幅を50%に設定、高さを100%に設定、ページ内での分割を避ける

@ media print セクション

印刷時のスタイルを指定します。

            .container {
                height: auto;
                display: block; /* 印刷時にブロック要素として扱う */
            }
  • .container:高さを自動調整、ブロック要素として表示
            .row {
                display: flex;
                flex-direction: row; /* 印刷時にも横方向に配置 */
                height: auto; /* 高さを自動調整 */
                page-break-inside: avoid;
                page-break-after: auto;
            }
  • .row:横方向のフレックスボックスを維持、高さを自動調整、ページ内での分割を避ける設定
            iframe {
                width: 100%; /* 縦並びのiframeの幅を100%に設定 */
                height: auto; /* 印刷時に高さを自動調整 */
                page-break-inside: avoid; /* ページ内での分割を避ける */
            }
  • iframe:幅を100%に設定、高さを自動調整、ページ内での分割を避ける設定
            .half-width-iframe {
                width: 50%; /* 横並びのiframeの幅を設定 */
                height: auto; /* 高さを自動調整 */
            }
  • .half-width-iframe:幅を50%に設定、高さを自動調整

ページのメインコンテンツ

    <div class="container">
        <iframe src="./map_tate.html"></iframe>
        <iframe src="./graph_tate.html"></iframe>
  • 縦方向のレイアウトコンテナ、縦並びのiframeを表示
        <div class="row">
            <iframe src="./map_yoko.html" class="half-width-iframe"></iframe>
            <iframe src="./graph_yoko.html" class="half-width-iframe">/iframe>
  • 横方向のレイアウトコンテナ、横並びのiframeを表示

まとめ

この構造により、画面上では縦並びと横並びのiframeを実現し、印刷時はすべてが1ページに収まりました。

※Edgeだとうまくいかないので、どなたか教えてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?