catch

レスポンシブWebデザインでハマりがちな%指定

レスポンシブWebデザインでは要素を可変にするために数値を%で指定することが多いですが、%指定の仕様を理解してないとハマることがあります。自分もそのような経験があったので備忘録としてまとめました。

要素の幅と高さの%指定

レスポンシブWebデザインのように、ある要素の幅を一定の比率を保ったまま可変するようにするには、通常、値を%で指定します。この時の値は、

求める要素の幅÷親要素のコンテンツ幅×100%

の式で求められます。

例えば求める要素の幅が20px、親要素のコンテンツ幅が200pxの場合は、10%となります。
また、ここで言うコンテンツ幅とはmargin、padding、borderを含まない幅です。

同様に高さを%で指定する場合は、

求める要素の高さ÷親要素のコンテンツの高さ×100%

となります。

要素の幅と高さの%指定

marginとpaddingの%指定

左右のmargin、paddingを%で指定する時は、同じような考え方で

求めるmargin(padding)の幅÷親要素のコンテンツ幅×100%

で求められます。
例えばmargin-left:20px、親要素のコンテンツ幅が200pxの場合は、10%となります。

上下のmargin、paddingは

求めるmargin(padding)の高さ÷親要素のコンテンツ幅÷100%

で求められます。

親要素の高さでなくて幅が相対の基準となる点に注意してください。

‘margin-top’, ‘margin-bottom’
Percentages:refer to width of containing block

Box model

marginとpaddingの%指定

一見、意味不明な仕様に思えますが、実はこれは理にかなってて、親要素の幅を基準とすることで広い幅のウインドウサイズでは上下のマージンも大きく、狭い幅では小さくなるので幅に応じて適切な余白を取ることができます。

ウインドウ幅に応じて余白の量が変わる
ウインドウ幅に応じて縦の余白量も変化する

絶対配置(position:absolute)の%指定

幅と高さの%指定

絶対配置の要素の幅は、

求める要素の幅÷基準となる親要素のpaddingを含めた幅×100%

高さは、

求める要素の高さ÷基準となる親要素のpaddingを含めた高さ×100%

となります。

まず、基準となる親要素はpositionプロパティにstatic以外の値が指定されている一番最初の親要素になります。そして、その要素の値にはpaddingの幅を含んだ値で計算します。(borderは含みません)

Note: For absolutely positioned elements whose containing block is based on a block container element, the percentage is calculated with respect to the width of the padding box of that element.

Visual formatting model details

position:absoluteの高さと幅の%指定

位置の%指定

絶対配置の左右の位置の%指定は、

求める要素のleft(right)の数値÷基準となる親要素のpaddingを含めた幅×100%

上下の場合は、

求める要素のtop(bottom)の数値÷基準となる親要素のpaddingを含めた高さ×100%

となります。

位置の指定も基準となる親要素のpaddingを含んだ値が基準となります。

position:absoluteの位置の%指定

これらの仕様を利用したTips

代表的な例としては、Youtubeやgoogle mapなどの埋め込みでiframeを使用する時に使えます。

例えば640×360のYoutubeの動画をiframeで埋め込むとします。
しかしiframeに下記のようなfluid Imageと同じスタイルを適用しても幅は可変しますが高さは一定のままです。

img{
	max-width: 100%;
	height: auto;
}

そこで、まずiframeを要素で囲みます。

<div class="iframe-wrapper">
	<iframe width="640" height="360" src="//www.youtube.com/embed/6Qk5Fc1Vdqk?rel=0" frameborder="0" allowfullscreen=""></iframe>
</div>

そして下記のCSSを指定します。

.iframe-wrapper{
	position: relative;
	height: 0;
	overflow: hidden;
	padding-top: 56.25%;
}
iframe{
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

iframeを囲った要素、つまりiframeから見た親要素のpadding-top(またはpadding-bottom)にiframeの幅に対する高さの比率を指定します。つまり、

高さ÷幅×100%=360÷640×100%=56.25%

となります。
そしてheightには0を指定します。

これで縦横比を保ったまま可変する要素を実装することができます。

そしてiframeに絶対配置で基準点を親要素の左上にし、幅と高さが親要素と同じになるように指定すればウインドウ幅に応じて可変するiframeを実装できます。

レスポンシブiframe

この考え方はiframeだけでなく、ちょっとした時に使えることがあるので覚えておくといいでしょう。

余談

親要素がbox-sizing:border-boxを指定していた場合も計算の方法は同様です。
幅と高さはpaddingを含めないコンテンツ幅となりますし、絶対配置の場合はpadding(borderは含まない)を含んだ値になります。

Add Comment

本文

  1. […] を一定の比率を保ったまま可変するようにするには、通常、値を%で指定します。この時の値は、 求める要素の幅÷親要素のコンテンツ幅×1…[ このサイトへ ] [ ニコニコ風に見る ] […]

  2. […] 2. CSS:レスポンシブWebデザインでハマりがちな%指定 […]

  3. 匿名

    iframe-wrapperの記述、クラスと間違っている気が。

  4. hiro

    ご指摘ありがとうございます!
    修正しました。

  5. asi

    はじめまして。
    absoluteの指定箇所について質問です。

    width:180px + padding-left:20px + padding-right:20pxですと、absoluteをかけている要素のwidthは50%だと110pxになると思うのですが・・・

  6. hiro

    そうですね、width:180px + padding-left:20px + padding-right:20px = 220pxなので、50%だと110PXですね。
    計算が間違ってましたので修正しました。
    ご指摘ありがとうございます。

  7. asi

    お返事ありがとうございました。
    このページのおかげで%指定でぴったりページ作成できました!
    いつもサイト、本を拝見していますが分かりやすくて勉強になります。
    ありがとうございました。

  8. hiro

    こちらこそありがとうございました!
    お役に立てたみたいで幸いですm(__)m

PAGE TOP