[Sass] 横幅/高さ、margin/padding、絶対位置などの px(ピクセル)値指定を %(パーセント)値に変換して指定する mixin スペニット

横幅やマージンなどを % で指定したい場合、親ボックスの横幅などから % の値を計算する必要があります。複数の値を % 値で指定するとなると計算がめんどくさく、また計算ミスの可能性も出てきます。そこで、Sass の mixin 機能を使えば簡単に変換することができて便利かなと思い px 値を % に変換して指定する mixin を考えてみました。

%指定の計算の仕方や考え方などはこちらの記事が大変参考になります。
レスポンシブWebデザインでハマりがちな%指定 │ Design Spice

全体のコードにおいて、小数点以下の数値になった場合は小数点第三以下を切り捨てという形にしています。

値が小数点以下になった場合のブラウザの挙動はこちらの記事が細かく検証されていて参考になりました。
CSSで指定した小数点以下の値はどのようにpxにまるめられるか – Coding Design's Tumblr
CSS の小数点以下の数値を各ブラウザはどのように解釈するか | Unformed Building

<目次>

横幅を px → % へ変換して指定する mixin

計算式

横幅を px → % へ変換する計算式は次のようになります。(親要素幅はmargin、padding、borderを含まない値

%指定したい要素の横幅(px) ÷ 親要素の横幅(px) × 100

例えば 300px 幅の要素の親が 960px だった場合次のような計算です。

300 ÷ 960 × 100 = 31.25 → width: 31.25%

定義

上記の式から mixin は以下のように定義します。第一引数に、%指定したい要素の親ボックスの横幅(px)、第二引数に要素の横幅(px)を指定します。

@mixin widtnPercent( $parentPxWidth, $pxWidth ){
	width: floor((( $pxWidth / $parentPxWidth ) * 10000% )) / 100;
}

呼び出し

.example の横幅を % 指定したいとします。.example の親要素の横幅が 960px 、.example が 300px とすると以下のように呼び出します。

.example{
	@include widtnPercent(960, 300);
}

これで、以下のように % 変換されたCSSが書き出されます。

横幅を px → % へ変換して指定したCSSコード

高さを px → % へ変換して指定する mixin

計算式

高さを px → % へ変換する計算式は次のようになります。(親要素高さはmargin、padding、borderを含まない値

%指定したい要素の高さ(px) ÷ 親要素の高さ(px) × 100

定義

上記の式から mixin を以下のように定義します。第一引数に、%指定したい要素の親ボックスの高さ(px)、第二引数に要素の高さ(px)を指定します。

@mixin heightPercent($parentPxHeight, $pxHeight){
	height: floor((($pxHeight / $parentPxHeight) * 10000%)) / 100;
}

呼び出し

.example の高さを % 指定したいとします。.example の親要素の高さが 500px、.example が 300px とすると以下のように呼び出します。

.example{
	@include heightPercent(500, 300);
}

これで、以下のようなCSSが書き出されます。
.example の高さを % 指定したCSSコード

margin を px → % へ変換して指定する mixin

計算式

margin を px → % へ変換する計算式は次のようになります。(親要素幅はmargin、padding、borderを含まない値

%指定したい要素のmargin(px) ÷ 親要素の横幅(px) × 100

定義

上記の式から mixin を以下のように定義します。第一引数に、%指定したい要素の親ボックスの幅(px)、第二引数にmargin-top(px)、第三引数に margin-right、第四引数に margin-bottom、第五引数に margin-left を指定します。

@mixin marginPercent($parentPxWidth, $mTop, $mRight, $mBottom, $mLeft){
	margin : floor((($mTop / $parentPxWidth) * 10000%)) / 100 floor((($mRight / $parentPxWidth) * 10000%)) / 100 floor((($mBottom / $parentPxWidth) * 10000%)) / 100 floor((($mLeft / $parentPxWidth) * 10000%)) / 100;
}

呼び出し

.example の margin を % 指定したいとします。.example の親要素の横幅が 500px として、上下を 20px 左右に 5px の margin を付けたいという場合以下のように呼び出します。

.example{
	@include marginPercent(500, 20, 5, 20, 5);
}

これで、以下のようなCSSが書き出されます。
.example の margin を % 指定したCSSコード

padding を px → % へ変換して指定する mixin

計算式

padding を px → % へ変換する計算式は次のようになります。(親要素幅はmargin、padding、borderを含まない値

%指定したい要素の padding(px) ÷ 親要素の横幅(px) × 100

定義

上記の式から mixin を以下のように定義します。第一引数に、%指定したい要素の親ボックスの幅(px)、第二引数にpadding-top(px)、第三引数に padding-right、第四引数に padding-bottom、第五引数に padding-left を指定します。

@mixin paddingPercent($parentPxWidth, $pTop, $pRight, $pBottom, $pLeft){
	padding : floor((($pTop / $parentPxWidth) * 1000%)) / 100 floor((($pRight / $parentPxWidth) * 10000%)) / 100 floor((($pBottom / $parentPxWidth) * 10000%)) / 100 floor((($pLeft / $parentPxWidth) * 10000%)) / 100;
}

呼び出し

.example の padding を % 指定したいとします。.example の親要素の横幅が 500px として、上下を 20px 左右に 5px の padding を付けたいという場合以下のように呼び出します。

.example{
	@include paddingPercent(500, 20, 5, 20, 5);
}

これで、以下のようなCSSが書き出されます。
.example の padding を % 指定したCSSコード

position: absolute の絶対値を px → % へ変換して指定する mixin

left right の計算式

left right の値を px → % へ変換する計算式は次のようになります。(親要素幅は padding を含む値。margin、border は含まない

%指定したい要素の left 又は right 値(px) ÷ 親要素の横幅(px) × 100

top bottom の計算式

top bottom の値を px → % へ変換する計算式は次のようになります。(親要素高さは padding を含む値。margin、border は含まない

%指定したい要素の top 又は bottom 値(px) ÷ 親要素の高さ(px) × 100

定義

上記の式から mixin を以下のように定義します。第一引数に、%指定したい要素の親ボックスの高さ又は幅(px)、第二引数に 絶対値(px) を指定します。

// left値
@mixin posiLeftPercent($parentPxWidth, $pxLeft){
    left: floor((($pxLeft / $parentPxWidth) * 10000%)) / 100;
}
// top値
@mixin posiTopPercent($parentPxHeight, $pxTop){
    top: floor((($pxTop / $parentPxHeight) * 10000%)) / 100;
}
// right値
@mixin posiRightPercent($parentPxWidth, $pxRight){
    right: floor((($pxRight / $parentPxWidth) * 10000%)) / 100;
}
// bottom値
@mixin posiBtmPercent($parentPxHeight, $pxBottom){
    bottom: floor((($pxBottom / $parentPxHeight) * 10000%)) / 100;
}

呼び出し

.example を position: absolute し、left と top で位置指定したいとします。.example の親要素の横幅が 500px、高さが 300px とします。その中で .example の位置を left: 50px / top: 50px に指定したい場合以下のように呼び出します。

.example{
	position: absolute;
	@include posiLeftPercent(500, 50);
	@include posiTopPercent(300, 50);
}

これで、以下のようなCSSが書き出されます。
.example を position: absolute し、left と top で%位置指定したCSSコード

上記と同じ条件で .example の位置を right: 50px / bottom: 50px に指定したい場合は以下のように呼び出します。

.example{
	position: absolute;
	@include posiRightPercent(500, 50);
	@include posiBtmPercent(300, 50);
}

これで、以下のようなCSSが書き出されます。
.example の位置を right: 50px / bottom 50px に%指定したCSSコード


ただ、ブラウザ毎による小数点以下の扱いの違いにより、カラム落ちなどの不具合が起こる可能性があるかもしれないので、そのような場合は随時調整して頂ければと思います。

Comments 2

  • はじめまして。

    とても便利に使わせていただておりとても感謝しております。

    質問があるのですが、marginのパーセント指定で左右はautoにする方法ってありますでしょうか。
    ボックスを中央にする場合いつも下記のようにパーセント指定の後にrightとleftをautoで上書きしております。
    もし一行で完結できる方法があれば教えていただけると幸いです。
    .example{
    @include paddingPercent(500, 20, 0, 20, 0);
      margin-right: auto;
    margin-left: auto;
    }

  • すみません、後もう一つ質問なのですが。
    各mixin スペニットの「!important」指定もすることは可能でしょうか。
    よろしくお願いいたします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です