JavaScript | DOM 操作:要素の位置・サイズ・スクロール – 画面中央配置

JavaScript JavaScript
スポンサーリンク

画面中央配置とは何か

「画面中央配置」は、要素をビューポート(今見えている画面)のちょうど真ん中に置くことです。モーダル、ダイアログ、ロード中インジケーターなどで頻繁に使います。ここが重要です:中央は「画面の中心」と「親の中心」の2種類があり、さらに“スクロールの影響を受けない中央(position: fixed)”と“ページレイアウトに従う中央(position: absolute)”で手法が変わります。目的に合う基準を先に選ぶと、実装がシンプルになります。


CSSだけで中央に置く基本(固定配置と通常配置)

画面中央に固定表示(スクロールしても中央のまま)

<div id="modal" class="center">モーダル</div>
<style>
  .center {
    position: fixed;         /* 画面(ビューポート)基準 */
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%); /* 要素の中心を座標原点に合わせる */
    background: #fff;
    border: 1px solid #ccc;
    padding: 16px;
    box-shadow: 0 12px 24px rgba(0,0,0,.2);
  }
</style>
HTML

ここが重要です:left/top を 50% にすると「要素の左上」が画面中央に来ます。transform で左上基準から“要素の中心基準”へ補正するのが定石です。position: fixed なのでスクロールしても中央に留まります。

親の中で中央に置く(レイアウト基準の中央)

<div class="wrap">
  <div class="box">親の中心</div>
</div>
<style>
  .wrap {
    position: relative;       /* 基準となる親 */
    height: 300px;
    border: 1px solid #ccc;
  }
  .box {
    position: absolute;       /* 親を基準に配置 */
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background: #fff;
    padding: 12px;
  }
</style>
HTML

ここが重要です:親の中で中央にしたい場合は、親に position: relative を付け、子を absolute+50%+translate で配置します。親がスクロールやリサイズで動いても、親内の中央にとどまります。


FlexとGridで「簡単で崩れにくい」中央配置

Flexで中央(縦横のど真ん中)

<div class="center-flex">
  <div class="content">中央</div>
</div>
<style>
  .center-flex {
    display: flex;
    justify-content: center;  /* 横方向中央 */
    align-items: center;      /* 縦方向中央 */
    height: 60vh;             /* デモ用に高さ確保(任意) */
    border: 1px solid #ccc;
  }
</style>
HTML

ここが重要です:Flex の中央寄せは“中身のサイズが変わっても崩れにくい”。ダイアログやローダーを包む外側のコンテナに使うと、レスポンシブでも安定します。

Gridで中央(シンプルな1行)

<div class="center-grid">
  <div class="content">中央</div>
</div>
<style>
  .center-grid {
    display: grid;
    place-items: center;      /* 縦横中央を一発指定 */
    height: 60vh;
    border: 1px solid #ccc;
  }
</style>
HTML

ここが重要です:Grid の place-items: center は最短記法。複雑なレイアウトで“特定のセル中央”に置きたいときも使いやすいです。


サイズが大きいときのはみ出し対策(最大寸法とスクロール)

モーダルの最大サイズと内側スクロール

<div class="modal">とても長いコンテンツ...</div>
<style>
  .modal {
    position: fixed;
    left: 50%; top: 50%; transform: translate(-50%, -50%);
    max-width: min(90vw, 640px);  /* 画面に合わせて最大幅 */
    max-height: 80vh;             /* 高さも制限 */
    overflow: auto;               /* 中身をスクロール */
    background: #fff; border: 1px solid #ccc; padding: 16px;
  }
</style>
HTML

ここが重要です:コンテンツが大きくても“箱自体は画面に収める”。max-width/max-height と overflow: auto をセットにし、モーダル内だけスクロールさせると見やすさが保てます。

モバイルでのセーフエリア意識(余白を残す)

.modal {
  padding: 16px;
  margin: 0; /* fixed なので margin は不要だが、周囲の見切れを防ぐなら内側余白で調整 */
  max-width: min(92vw, 640px);
  max-height: 84vh;
}
CSS

ここが重要です:上下左右に少し余白を残すと、指で操作しやすく、端の見切れや閉じるボタンのタップミスが減ります。


JavaScriptで正確に中央へ(座標計算とスクロール補正)

現在の画面中央へ要素を動かす(固定配置)

<div id="dialog" style="position:fixed">ダイアログ</div>
<script>
  function centerFixed(el) {
    const vw = window.innerWidth;
    const vh = window.innerHeight;
    const w = el.offsetWidth;
    const h = el.offsetHeight;
    el.style.left = (vw - w) / 2 + "px";
    el.style.top  = (vh - h) / 2 + "px";
  }
  centerFixed(dialog);
  window.addEventListener("resize", () => centerFixed(dialog), { passive: true });
</script>
HTML

ここが重要です:画面サイズ(innerWidth/innerHeight)と要素の見た目サイズ(offsetWidth/offsetHeight)から“中央座標”を計算します。リサイズで再計算すると常に中央を維持できます。

親内の中央へ(相対配置)

<div id="wrap" style="position:relative; width:420px; height:300px; border:1px solid #ccc">
  <div id="box" style="position:absolute; background:#fff; padding:12px; border:1px solid #ccc">中央</div>
</div>
<script>
  function centerInParent(el) {
    const parent = el.offsetParent;
    const w = el.offsetWidth, h = el.offsetHeight;
    const pw = parent.clientWidth, ph = parent.clientHeight;
    el.style.left = (pw - w) / 2 + "px";
    el.style.top  = (ph - h) / 2 + "px";
  }
  centerInParent(box);
  window.addEventListener("resize", () => centerInParent(box), { passive: true });
</script>
HTML

ここが重要です:parent.clientWidth/Height(内側の見える領域)を基準にすると、スクロールバーや枠の影響を正しく避けられます。

画面中央までスクロールしてから表示(固定ヘッダ補正付き)

<header style="position:sticky; top:0; height:64px; background:#fff"></header>
<section id="target" style="margin-top:1000px">目的地</section>
<script>
  function scrollTargetToCenter(el, offset = 0) {
    const rect = el.getBoundingClientRect();
    const y = window.scrollY + rect.top - (window.innerHeight - rect.height) / 2 - offset;
    window.scrollTo({ top: Math.max(y, 0), behavior: "smooth" });
  }
  scrollTargetToCenter(target, 64); // ヘッダ分の補正
</script>
HTML

ここが重要です:getBoundingClientRect().top は“画面基準”。“画面中央(viewport 半分)に目的の要素中心が来る”座標を計算し、固定ヘッダ分を差し引いてちょうどよい位置で止めます。


モーダルの振る舞いとアクセシビリティ(フォーカス・閉じ方・トラップ)

開いたら中央にフォーカス(キーボード操作に優しく)

<div id="modal" role="dialog" aria-modal="true" tabindex="-1" class="center">内容</div>
<script>
  function openModal() {
    modal.style.display = "block";
    modal.focus(); // 初期フォーカスでキーボード操作可能に
  }
  function closeModal() {
    modal.style.display = "none";
  }
  document.addEventListener("keydown", (e) => { if (e.key === "Escape") closeModal(); });
</script>
HTML

ここが重要です:tabindex=-1 と focus() で“モーダル内に操作の起点”を作ります。Esc で閉じる導線を用意すると体験が安定します。

フォーカストラップ(閉じるまで外に出ない)

<script>
  function trapFocus(e) {
    if (modal.style.display === "block" && !modal.contains(e.target)) {
      e.stopPropagation();
      modal.focus();
    }
  }
  document.addEventListener("focusin", trapFocus, { capture: true });
</script>
HTML

ここが重要です:開いている間は外へフォーカスが逃げないようにします。中央配置のモーダルは“視覚と操作の中心”になるため、フォーカス制御まで含めると本物の使いやすさになります。


よくある落とし穴と回避策

transform を忘れて“左上が中央”になる

left/top を 50% にするだけだと、要素の左上が中央に来ます。translate(-50%, -50%) の補正が必須です。見た目中心に合わせることを意識しましょう。

スクロールで位置がズレる

画面中央に固定したいのに absolute を使うと、ページスクロールで位置が動きます。スクロール非依存の中央は position: fixed を選びます。

要素が大きくて中央でもはみ出す

max-width/max-height と overflow: auto を併用します。視認性と操作性のために、上下左右へ少し余白を残す設計が安全です。

リサイズや向き変更で中央が崩れる

JavaScriptで中央計算する場合は resize イベントで再計算します。CSS中心の実装(Flex/Grid/transform)なら自動で追従しやすく、保守性が高いです。

親基準と画面基準の混同

親内中央は absolute+relative、画面中央は fixed。どの“基準”で中央にしたいかを先に決めると、計算や指定が一貫します。


まとめ

中央配置は「どの基準で中央にするか」を決めるのが第一歩です。画面中央なら position: fixed+50%+translate、親内中央なら position: absolute+relative+50%+translate、複雑なレイアウトなら Flex/Grid の中央寄せが簡潔で崩れにくい選択です。大きなコンテンツには max-width/max-height と overflow を併用してはみ出しを防ぎ、固定ヘッダやスクロールの影響は rect と座標計算で丁寧に補正します。フォーカスや閉じ方まで整えると、初心者でも気持ちよく使える“真ん中の体験”を自信をもって作れます。

タイトルとURLをコピーしました