min-margin、max-margin、min-padding、max-paddingをSassとメディアクエリで実装。

レスポンシブデザインでサイトを制作していると、
「max-margin、min-margin、max-padding、min-padding」があればなと思う事がよくあります。

今のところそのようなcssプロパティは存在しないので、
Sass関数を使ってメディアクエリでいい感じに実装したいと思います。

使い方にもよりますが、
ブレイクポイントに来てカクンとデザインが変わるのを、ウィンドウサイズに応じて余白を徐々に変化することができるので
A型の私はとても重宝しています。

メディアクエリで代替え案を考える

ウィンドウの横幅を100として、何%(vw)で伸縮するかを決め、
最小値と、最大値からブレイクポイントを計算します。

例)

  • 最大値: 32px;
  • 最小値: 8px;
  • 流動値: 2vw;

最小値のに対してのブレイクポイントの求め方

※数値に単位があるためこのままでは利用できません。

1
@media (max-width: (100 / 2vw) * 8px - 0.02) {
2
    property: 8px;
3
}

流動値(2%)の範囲のブレイクポイントの求め方

※数値に単位があるためこのままでは利用できません。

1
@media (min-width: (100 / 2vw) * 8px) and (max-width: (100 / 2vw) * 32px) {
2
    property: 2%;
3
}

Sass関数(min-margin、max-margin, min-padding、max-padding)

最大値をベースに先ほどの式を当てはめていきます。
単位があると計算できないので、単位を削除する関数とブレイクポイントをpxで計算しているのでem、remをpxに変換する関数も一緒に用意します。

1
// 値から単位を削除
2
@function strip-unit($number) {
3

4
    @if type-of($number) == "number" and not unitless($number) {
5
        @return $number / ($number * 0 + 1);
6
    }
7
    @return $number;
8
}
9

10
// pxに変換
11
$base-size: 16px; // 1emのpxサイズ
12
@function topx($size, $base-size: $base-size) {
13
    $unit: unit($size);
14

15
    @if $unit == "em" {
16
        @return strip-unit($size) * $base-size;
17
    }
18
    @else if $unit == "rem" {
19
        @return strip-unit($size) * $base-size;
20
    }
21
    @else {
22
        @return $size;
23
    }
24
}

min-margin、max-margin

1
@mixin minax-margin($prop: margin, $min: 8px, $max: 32px, $vw: 2vw) {
2
    $min: topx($min); $max: topx($max);
3

4
    #{$prop}: $max;
5
    @media (min-width: strip-unit(100 / $vw) * $min) and (max-width: strip-unit(100 / $vw) * $max) {
6
        #{$prop}: $vw;
7
    }
8
    @media (max-width: strip-unit(100 / $vw) * $min - 0.02) {
9
        #{$prop}: $min;
10
    }
11
}

min-padding、max-padding

1
@mixin minax-padding($prop: padding, $min: 8px, $max: 32px, $vw: 2vw) {
2
    $min: topx($min); $max: topx($max);
3
    
4
    #{$prop}: $max;
5
    @media (min-width: strip-unit(100 / $vw) * $min) and (max-width: strip-unit(100 / $vw) * $max) {
6
        #{$prop}: $vw;
7
    }
8
    @media (max-width: strip-unit(100 / $vw) * $min - 0.02) {
9
        #{$prop}: $min;
10
    }
11
}