2024.12.26 Web制作
Scss/flocssで自作ユーティリティー width編
u-w-fullやu-w-50pなど「u-w」の接頭辞がついた、ユーティリティーを作成します
フォルダ構成やutilityの適用順などはflocssを基準にしています
社内のコーディング共通フォーマットとして少しずつ独自の改良をしてきた設定です
下記もあわせてご覧ください
- Scss/floccsで自作ユーティリティー margin / padding編
- Scss/floccsで自作ユーティリティー display / gap編
- Scss/floccsで自作ユーティリティー font-size / font-weight編
- Scss/floccsで自作ユーティリティー border編
- Scss/floccsで自作ユーティリティー width編
- Scss/floccsで自作ユーティリティー color / background-color編
ゴール
- media queryのサイズによる階層的な適用が確実にされること
- オリジナル名称の設定を作成すること
- 100% / fit-content設定ができること
- ピクセル単位で設定ができること
- %で設定ができること
前提
foundation/variable
使用しないbreak pointを入れておくと無駄な設定ができてしまいますので、注意してください
$break-points: (
all: '',
lg: 'screen and (max-width: 1024px)',
md: 'screen and (max-width: 820px)',
) !default;
$widths: (
sm: (100, 98, 96),
md: (150, 148, 146),
lg: (200, 198, 196),
);
foundation/mixin
@use 'sass:map';
@use 'sass:math';
@function Rem($size) {
@return math.div($size, 10) + rem;
}
@mixin mq($breakpoint: md) {
@if($breakpoint == 'all') {
@content;
} @else {
@media #{map.get($break_points, $breakpoint)} {
@content;
}
}
}
使用法
オリジナル名称の設定
.u-w-{$widths}
100%設定
.u-w-full
.u-w-{$break-points}-full
fit-content設定
.u-w-fit
.u-w-{$break-points}-fit
ピクセル設定
.u-w-{数値}
.u-w-{$break-points}-{数値}
%設定
.u-w-{%数値}p
.u-w-{$break-points}-{%数値}p
パラメータ
{数値} … 0~1000
{%数値} … 1~99
{$widths}は、上記前提を参照
使用例
<div class="u-w-50p u-w-lg-80p u-w-md-full">
・・・
</div>
上記では、画面幅により下記のようになります
- 1025px以上:widthが50%
- 821~1024px:widthが80%
- 820px以下:widthが100%
<button type="button" class="u-w-sm">
・・・
</div>
上記では、画面幅により下記のようになります
- 1025px以上:widthが10rem
- 821~1024px:widthが9.8rem
- 820px以下:widthが9.6rem
$widths: (
sm: (100, 98, 96),
md: (150, 148, 146),
lg: (200, 198, 196),
);
$widthsの設定は、この名称は自由に作成できるため、例えば、button-submitやbutton-returnなどの設定を作成することで、複数の幅設定も作成できます。
<button type="button" class="u-w-sm u-w-md-full">
・・・
</div>
break pointのmdだけ100%にしたい場合は、試していませんが、上記で書き順的には行けると思います
最終形
上記の前提は、各環境にあわせ別ファイルとして振り分け、下記ファイルで読み込んでください
@use 'sass:map';
@use '../../foundation/variable' as *;
@use '../../foundation/mixin' as *;
.u-w {
@each $breakpoint, $query in $break-points {
// $widthsのkey名で設定
@each $name, $values in $widths {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
width: #{Rem(nth($values, $num))} !important;
}
}
// 100% / fit
@include mq($breakpoint) {
@if $breakpoint=='all' {
&-full {
width: 100% !important;
}
&-fit {
width: fit-content !important;
}
} @else {
&-#{$breakpoint}-full {
width: 100% !important;
}
&-#{$breakpoint}-fit {
width: fit-content !important;
}
}
}
// 0~100rem
@for $i from 0 through 1000 {
@if $breakpoint=='all' {
&-#{$i} {
width: Rem($i) !important;
}
} @else {
&-#{$breakpoint}-#{$i} {
width: Rem($i) !important;
}
}
}
// 1~99%
@for $i from 1 through 99 {
@if $breakpoint=='all' {
&-#{$i+"p"} {
width: #{$i+"%"} !important;
}
} @else {
&-#{$breakpoint}-#{$i+"p"} {
width: #{$i+"%"} !important;
}
}
}
}
}
解説
上記最終系を一つずつ見ていきます。
ループ設定
$break-points: (
all: '',
lg: 'screen and (max-width: 1024px)',
md: 'screen and (max-width: 820px)',
) !default;
上記$break-pointsをループして展開していきます
.u-w {
@each $breakpoint, $query in $break-points {
・・・
}
展開されるイメージは下記の通りです
.u-w {
// all
// lg
@media 'screen and (max-width: 1024px)' {
}
// md
@media 'screen and (max-width: 820px)' {
}
}
最初の$breakpointは「all」となりますが、下記mixinでは、allの場合は、特に処理を行っていませんので空になります
@mixin mq($breakpoint: md) {
@if($breakpoint == 'all') {
@content;
} @else {
@media #{map.get($break_points, $breakpoint)} {
@content;
}
}
}
ここでのポイントは、「$break-points」を大きいサイズから設定していことです
詳細クラスの設定
オリジナル名称の設定
配列「$font-sizes」を展開していきます
$widths: (
sm: (100, 98, 96),
md: (150, 148, 146),
lg: (200, 198, 196),
);
$widthsにある各変数のカッコ内の数字は、$break-pointsの数と同じ数設定しています
したがって、ここは、左から「all」「lg」「md」のpxサイズを数値のみで設定しています
.u-w {
@each $breakpoint, $query in $break-points {
@each $name, $values in $widths {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
width: #{Rem(nth($values, $num))} !important;
}
}
}
}
上記ブロックの真ん中の部分を解説していきます
@each $name, $values in $widths {
$widthsをeach文で展開していますが、ここでは、最初は「$name」に「sm」が、「$values」には「(100, 98, 96)」が入ることになります
$num: index(map.keys($break-points), $breakpoint);
map.keysで$break-pointsのkeyだけの配列を作成しています。結果は「all, lg, md」となります
そしてindex関数で、「all, lg, md」の中でall(二つ目のループで最初の$breakpointは「all」)の位置を取得しています。ここでは「1」が$numとして設定されます
&-#{$name} {
「&-#{$name} {」は、$marginsの最初のキーのsmを使用して「&-sm {」となり、結果として「.u-w-sm」が作成されます
width: #{Rem(nth($values, $num))} !important;
「nth($values, $num)」では、nth関数で、$values、つまり「(14, 13, 12)」のうち、$numの値の順番(最初は「1」)にある値を取得し、Rem関数でremの値に変換しています
結果として「width: 20rem !important;」という記述が作成されます
下記が展開イメージとなります
// all
.u-w-sm {
width: 10rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-w-sm {
width: 9.8rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-w-sm {
width: 9.6rem !important;
}
}
・・・
100% / fit-content 設定
したがって、ここは、左から「all」「lg」「md」のpxサイズを数値のみで設定しています
.u-w {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@if $breakpoint=='all' {
&-full {
width: 100% !important;
}
&-fit {
width: fit-content !important;
}
} @else {
&-#{$breakpoint}-full {
width: 100% !important;
}
&-#{$breakpoint}-fit {
width: fit-content !important;
}
}
}
}
}
下記が展開イメージとなります
// all
.u-w-full {
width: 100% !important;
}
.u-w-fit {
width: fit-content !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-w-lg-full {
width: 100% !important;
}
.u-w-lg-fit {
width: fit-content !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-w-md-full {
width: 100% !important;
}
.u-w-md-fit {
width: fit-content !important;
}
}
ピクセルごとの設定
次にピクセル単位の設定を行います
下記のループ部分は、上記と同じです。2番目のブロックについて解説します
.u-w {
@each $breakpoint, $query in $break-points {
@for $i from 0 through 1000 {
@if $breakpoint=='all' {
&-#{$i} {
width: Rem($i) !important;
}
} @else {
&-#{$breakpoint}-#{$i} {
width: Rem($i) !important;
}
}
}
}
}
今回は、10~1000の数値で設定しています
@for $i from 1 through 1000 {
「@for $i from 1 through 1000」が0~1000までの数値をループし$iに1から順に数字を代入しています
@if $breakpoint=='all' {
上記同様allの場合の振り分けをしています
下記が展開イメージです
// all
.u-w-1 {
width: 0.1rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-w-lg-1 {
width: 0.1rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-fs-md-1 {
width: 0.1rem !important;
}
}
・・・
%設定
次にピクセル単位の設定を行います
下記のループ部分は、上記と同じです。2番目のブロックについて解説します
.u-w {
@each $breakpoint, $query in $break-points {
@for $i from 1 through 99 {
@if $breakpoint=='all' {
&-#{$i+"p"} {
width: #{$i+"%"} !important;
}
} @else {
&-#{$breakpoint}-#{$i+"p"} {
width: #{$i+"%"} !important;
}
}
}
}
}
今回は、1~99の数値で設定しています
@for $i from 1 through 99 {
「@for $i from 1 through 1000」が0~1000までの数値をループし$iに1から順に数字を代入しています
@if $breakpoint=='all' {
上記同様allの場合の振り分けをしています
下記が展開イメージです
// all
.u-w-1p {
width: 1% !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-w-lg-1p {
width: 1% !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-fs-md-1p {
width: 1% !important;
}
}
・・・
まとめ
以上でwidthのユーティリティーの完成となります
全設定が吐き出されてしまうと膨大な量になってしまいますが、弊社では、vite+@fullhuman/postcss-purgecssなどを使って、余計なclassは入らないようにしていますので、そういった工夫も必要になるかと思います
コーディングの省力化に貢献できれば幸いです
文責:フライング・ハイ・ワークス代表 松田 治人(まつだ はるひと)
会社では、Laravelを中心としたエンジニアとして働いており、これまでに50本以上のLaravelによるWebアプリケーションの構築や東京でホームページ制作をしています。
エンジニアとして弊社で働きたい方、お仕事のご相談など、お待ちしております。
WEBサイト・ホームページの制作をご検討の方
フライング・ハイ・ワークスの紹介
フライング・ハイ・ワークスは、東京のホームページ制作・Web制作会社・システム開発会社です。東京都及びその近郊(首都圏)を中心として、SEO対策を意識したPC及びスマホのサイトをワンソース(レスポンシブ対応)で制作します。
実績
デザイナーチームは、グラフィックデザインやイラストの制作も得意としており、著作権を意識しない素材の提供が可能です。システム・コーディングチームでは、Laravelなどを使用したスクラッチからのオリジナルシステム開発を始め、WordPressのカスタマイズを得意としております。
また、SEOやランディングページ(LP)、広告向けバナーなどを他社様でやっていた作業の引継ぎでも問題ありません。制作実績は多数ございますので、お客様に合わせたご提案が可能です。
500点以上のフライング・ハイ・ワークスの制作実績ページをご覧ください。