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

2020年9月2日

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

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

大きさを測る

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

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

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

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

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指定を使いながらのレスポンシブ対応も実現できますよ!