【CSS】コツはパーセント計算!positionをレスポンシブで使うとズレるときに気を付けること

  • URLをコピーしました!

「position レスポンシブ」「position レスポンシブ ずれる」などの検索キーワードで当ブログを訪れてくださる方がいることに気づいたのですが、【css】position:absolute怖くなくなるまで徹底解剖!の記事では「基準位置の要素の大きさも、配置する要素の大きさも、そして位置の指定もすべて%で計算して配置してみましょう。」としか書いていなかったので、詳しく説明します。

※2025年9月に、以降の内容を全面的に改訂しました→旧バージョンはこちら

作るのはコチラ→比率を保ったままレスポンシブするデモ

長方形の中にハート型の要素配置されているデザインを、全体の要素の位置関係・大きさの関係性・縦横比を保ったまま、画面幅にあわせて拡縮できるように気を付けながら、positionを使って実装してみましょう。

白とピンクのグラデーション背景で塗られた縦長長方形の左上にピンクのハートが配置されている

※この記事ではvw (vi) やcqw(cqi)ではなく % 単位を使って要素を配置しますが、相対的な単位を使う場合は同じ考え方が使えます!

目次

ステップ1 デザイン上の要素の大きさ・位置を測る

今回は横1000px縦1200pxの長方形の中に、横300px縦260pxのハート型の要素を配置したデザインを実装します。
ハート型の要素は、長方形の上から100px、左から100pxの位置に配置されています。

このデザインデータを、長方形の要素は position:relative ハート形の要素はposition:absolute で配置して、長方形の横幅を画面いっぱい width:100% で実装することにしましょう。

デザインデータ上に書く要素のサイズを書き込みした画像

ステップ2. 各要素の縦横比を確認する

position:absolute を使うとき、最初のハードルは position:relative の要素の高さが消滅することです。

高さを消滅させたくない場合、今回のように「縦横比を保ちたい」場合は aspect-ratio が便利です。

aspect-ratio: [横幅(単位無し)] / [高さ(単位無し)];

この書き方だと aspect-ratio : 1000 / 1200; のように、約分したくなる見た目になりますが、このままで大丈夫です。

要素の大きさを改めて確認して、縦横比設定のために使う数値を取得しましょう。

長方形の幅1000pxと高さ1200pxに注目して aspect-ratio: 1000 / 1200 を導き出している様子
ハートの幅260pxと高さ300pxに注目して aspect-ratio: 300 / 260 を導き出している様子

※ 今回は例示としてハート形の要素にも aspect-ratio を書いていますが、今回のハート型の要素のように画像単体を配置するときは、画像部分は aspect-ratioを使わなくても縦横比維持できます。実際の実装では、必要に応じて調整してください。

ステップ3. 要素の横方向の位置と大きさの計算式を確認する

position:absolute で配置するハート形の要素の横幅と、左端からの距離について計算式を考えます。

デザインデータ上の長方形(position:relative にする親要素)の幅1000pxを基準に、ハート型の要素の幅300pxと左端からの距離100pxが何パーセントになるかを計算します。

要素の横の位置と幅は描画領域の幅を基準に計算する

長いので

  • ハート型の要素=要素
  • 長方形=親要素

と呼ぶことにして、

計算式は以下のようになります。

[要素の幅(単位無し)] ÷ [親要素の幅(単位無し)] × 100%

これを電卓で計算するのではなく、CSS上に計算式をそのまま入れて使います。

width: calc(100 / 1000 * 100%);
left: calc(300 / 1000 * 100%);
100pxの部分は 100 / 1000 * 100%、300pxの部分は 300 / 1000 * 100%になる

ステップ4. 縦方向の位置の計算式を確認する

ステップ3と同様に、続いて上端からの距離について計算式を考えます。

デザインデータ上の長方形(position:relative にする親要素)の高さ1200pxを基準に、ハート型の要素の上端からの距離100pxが何パーセントになるかを計算します。

要素の縦の位置は描画領域の高さを基準に計算する

考え方はステップ4と同じで

[上端からの距離(単位無し)] ÷ [親要素の高さ(単位無し)] × 100%

となるので、CSSで書くと以下のようになります。

top: calc(100 / 1200 * 100%);

ステップ5. 実際にCSSで書いてみる

いままで確認してきた要素の大きさや計算式をもとに、実際に全体のCSSを書いてみます。

実装サンプルコード

HTML

<div class="position-container">
    <div class="img-box">
        <img src="heart.png" alt="ハートマーク" width="600" height="520">
    </div>
</div>

CSS

.position-container {
  position: relative;
  width: 100%; /* 領域を画面幅にあわせて拡縮させる */
  aspect-ratio: 1000 / 1200; /* デザイン通りの縦横比で固定 */
  background: linear-gradient(132deg, #ffffff, #ffccff);
}

.img-box {
  position: absolute;
  aspect-ratio: 300 / 260; /* デザイン通りの縦横比で固定 */
  width: calc(300 / 1000 * 100%); /* 要素の幅の%を計算 */
  left: calc(100 / 1000 * 100%); /* 要素の位置の%を計算 */
  top: calc(100 / 1200 * 100%); /* 要素の位置の%を計算 */
}

.img-box img{
  width: 100%;
  height: 100%;
  object-fit: contain;
}

※ 今回は例示としてハート形の要素にも aspect-ratio を書いていますが、今回のハート型の要素のように画像単体を配置するときは、画像部分は aspect-ratioを使わなくても縦横比維持できます。実際の実装では、必要に応じて調整してください。

ステップ6. 本当にサイズの計算が合っているか確認する

これで画面の幅にあわせて拡縮できていそうな実装になりましたが、本当にデザイン通りの実装になったでしょうか?

ブラウザ上で長方形の横幅=デザイン上の幅になる画面サイズで確認してみましょう。

実際の動作はこちらで確認できます→比率を保ったままレスポンシブするデモ

6-1. Chrome DevToolsのElementsパネルを開いた状態で、画面のサイズを調整

  1. Elementsパネルで長方形の要素を選択
  2. Computedタブの要素の大きさ、または要素の端に表示される要素の大きさが、デザイン上の幅になるように画面のサイズを調整
Chrome DevToolsのElementsパネルComputedタブに1000×1200と表示されている

6-2. Computedタブで要素の大きさ・位置を確認

  1. Elementsパネルでハート型の要素の方を選択
  2. Computedタブで position と 要素の大きさを確認

これで表示される数値が、デザイン上の数値と一致していたら成功です!

Computedタブにposition 上100左100、要素の大きさ300×260と表示されている

まとめ

計測&計算式の確認をして、その数値のとおりにCSSを書いて、結果が合っているかを確認する。
この基本の流れを守れば、position配置をレスポンシブ対応するのも簡単です!

各所の大きさをすべて%にして配置するために、以下の流れで上手に要素を配置してみましょう。

まずは計測&計算式の確認

  • デザイン上の要素の大きさ・位置を測る
    • デザインデータを忠実に計測!
  • 各要素の縦横比を確認する
    • 計測した数値を使って aspect-ratio: 横 / 縦
  • 要素の横方向の位置と大きさの計算式を確認する
    • 横方向の計算は、親要素の「幅」を基準にcalc(要素の幅 / 親要素の幅 * 100%)
  • 要素の縦方向の位置の計算式を確認する
    • 縦方向の計算は、親要素の「高さ」を基準にcalc(上端からの距離 / 親要素の高さ * 100%)

確認した数値どおりにCSSを書いて、結果が合っているかを確認

  • 実際にCSSで書いてみる
    • 確認した縦横比や計算式をそのまま書くだけ!
  • 本当にサイズの計算が合っているか確認する
    • Chrome DevTools の ElementsパネルComputedタブを使うと確認しやすい!

position指定を使いながらのレスポンシブ対応が必要な時は、この方法を試してみてくださいね✨



【旧バージョンの記事】2020年時点の古い内容はここから

内容を確認する場合はアコーディオンを展開してください。

作るのはコチラ→ 比率を保ったままレスポンシブするデモ

大きさを測る

今回は四角の中にハートを配置したデザインを、比率を保ったままレスポンシブさせます。

まずはデザインデータの各所の大きさを測ります。

【重要】各所のパーセントを計算する

はかったピクセルをもとに%を計算するのですが、ここにクセがあるので注意が必要です。

注目してほしいのは「上の余白100pxと、左の余白100pxで、パーセントの値が違うこと」です。

position配置する要素の横幅は、基準の要素(position:relativeにする要素)の横幅を100%としたときの横幅で計算

青色の文字で書いた%は、基準の要素の横幅(今回は1000px)を100%としたときの横幅で計算します。

100(余白の横幅) ÷ 1000(基準の要素の横幅) × 100=10(%) という感じです。

余白だけではなく、positionを指定する要素そのものの横幅もしっかり%にしておきましょう。

高さは基準の要素の高さを100%としたときの高さで計算

パーセント配置したときにずれやすいポイントその1です。

先ほど100pxの余白(横)を10%と計算したばかりだったので、縦の余白も10%としてしまいそうですが、ここは

100(余白の高さ) ÷ 1200(基準の要素の高さ) × 100=8.33333(%) となります。

基準の要素の高さは、基準の要素がwidth:100%になるなら基準の要素が100%の時の高さで計算

これは非常にわかりづらいのですが……
今回のデザインのように「デザイン幅=画面幅=基準の要素の横幅」であれば、基準の要素の横幅=100%として計算してください。

1200 ÷ 1000 × 100 = 120(%)

計算した%の値を使ってCSSで指定する

実際に指定するとこのようになります。

#position-base{/*基準の要素*/
  width: 100%;
  height: 0;
  padding-top: 120%;
  position: relative;
  border: solid 1px #000;
}
#position-base .img01{/*ハートの画像*/
  position: absolute;
  width: 30%;
  height: auto;
  top: 8.3%;
  left: 10%;
}

先ほど計算した通りの数字で指定されていますね。

実際の動作はコチラで確認できます→ 比率を保ったままレスポンシブするデモ

基準の要素の高さをpadding-topで指定しているのは何?

先ほど挙げたCSSは、全体的に測った通りの数字で指定されているかと思いますが、positionとレスポンシブ対応に慣れていない人には見慣れない記述があったかと思います。

height: 0;
padding-top: 120%;

「paddingを%指定したとき、親要素の横幅が基準になる」という仕様を利用した小技です。

今回は#position-baseにwidth:100%を指定していますので、親要素の横幅=#position-baseの横幅となり、結果的に#position-baseの横幅に対して120%の大きさの高さが実現されています。

(height:0は指定しなくても同じ結果になりますが、「今回の要素の高さは全部paddingで作ったからね!」ということを明示しています)

まとめ

position配置をレスポンシブ対応するときは、各所の大きさをすべて%にして配置する!ときの%計算のポイントは下記の通り。

  • position配置する要素の横幅は、基準の要素(position:relativeにする要素)の横幅を100%としたときの横幅で計算
  • 高さは基準の要素の高さを100%としたときの高さで計算
  • 基準の要素の高さは、基準の要素がwidth:100%になるなら基準の要素が100%の時の高さで計算

そしてCSSで配置するときは下記のように配置しましょう。

  • position:absoluteで配置する要素にはwidthやtopやleftなどを、計算した通りの%で設定していく
  • 基準の要素(position:relativeの要素)の高さについては、padding-topを利用して%で設定する

これでposition指定を使いながらのレスポンシブ対応も実現できますよ!

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

目次