SASSを使ってpxからvwに変換できる関数を作ってみた

今までpxで指定していた要素をvw指定にしてviewportに応じて広げる必要が出てきたので、pxからvwに変換する関数をSASSを使って実装してみました!

はじめに

仕事をしていたら、デザイナーさんから

横幅変えた時に、画像に合わせて文字も大きくしたいな〜

との依頼が!!

せや!vw(Viewport Width)使ったろ!!
でも、今の画像の比率と文字の比率を担保させたまま実装するのダルいな〜
計算しなきゃいけない箇所も結構あるし・・・。

というわけで、今回は元サイズ(px)を指定するだけで、新サイズ(vw)に変換してくれる関数を作って行きます!!

とりあえず完成形

// pxをvw単位に変換
// @param: $size 変換前のサイズ(px) $std_width 基本となるViewPort
@function px_to_vw($size, $std_width: 375)
  $no_unit_size: $size / ($size * 0 + 1)
  @return (100 / $std_width) * $no_unit_size * 1vw

前提条件

これらを実装するための前提条件としては、

  • SASSを使用している(SCSSでもOK!)
  • 基準となる横幅がある
  • サイトのviewportの設定がwidth=device-widthになっている

となります。

2つ目の「基準となる横幅」というのは、元のピクセル数が14pxとした場合、vwに変換したときに実際の大きさが14pxになる画面幅になります。

僕の場合は、横幅375pxの端末を使っているユーザが一番多いので、「基準となる端末幅」は「375px」に設定しました。
※375pxは最近のiPhoneで使われている幅なので割とメジャーな気がします。

vwを算出するときの計算式

実際に関数を作る前にpxからvwに変換するための計算式を確認しましょう!

結論から言うと、下のようになります。

 ( 100 / 基準となる横幅 ) * 元サイズ(px)

割と簡単!!

中身を解説して行きます!

viewport widthの特性としてviewportの値(基準となる横幅)と「100vw」はイコールになります。

例えば、基準となる横幅が375pxだった場合、以下の式になります。

375px = 100vw

これを踏まえて、考えると・・・

1px = ( 100vw / 375px ) = 0.2666vw

となります。

つまり、基準となる横幅が375pxの場合、14pxになるviewport widthの値

( 100vw / 375px ) * 14px = 3.733vw

になりますね!

ここまでくれば、あとは変数などを使ってSASSの関数に落とし込むだけです!!

実際に作ってみよう!

上で解説した式を実際にSASSで実装して行きます!

( 100 / 基準となる横幅 ) * 元サイズ(px)

とりあえず、実装したものを見ながら…

@function px_to_vw($size, $std_width: 375)
  $no_unit_size: $size / ($size * 0 + 1)
  @return (100 / $std_width) * $no_unit_size * 1vw

こんな感じになります〜

@function px_to_vw($size, $std_width: 375)

まずは、1行目。

この関数に渡す引数は、「元のサイズ」と「基準となる横幅」になります。

基準となる横幅」は使用している人が多いと思われる、「375px」にしてみました。最近のiPhoneで使われている画面幅ですね!

もちろんここは、他のサイズに変更してしまっても大丈夫です!

あまりないと思いますが、もし一部分だけ基準となる横幅を変える必要がある場合は、引数で別の幅を渡してあげてください。

$no_unit_size: $size / ($size * 0 + 1)

次は2行目ですね!

ここでは、引数で受け取った元サイズから単位を取り除いています。

単位がついていると計算できなくなってしまうので数値だけにします。

具体的に何をやっているかは、ここでは割愛します。(別記事にして紹介しますね!)

@return (100 / $std_width) * $no_unit_size * 1vw

最後は3行目!

ここでは実際に変換の処理を行っています!

引数で受け取った「基準となる横幅」と先ほど求めた、「単位を取り除いた元サイズ」を使って、pxからvwの値に変換しています。

というわけで、今回はこんな感じで終わりたいと思います!!

最後までありがとうございました!!!