2024.12.26 Web制作
Scss/flocssで自作ユーティリティー display / gap編
displayでは、u-d-blockやu-d-md-noneなど、「u-d」の接頭辞で、また、flex / gridで使用するgapは、u-gap-48やu-gap-r-60など「u-gap」の接頭辞で、各ユーティリティーを作成します
フォルダ構成や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のサイズによる階層的な適用が確実にされること
- display
- grid系で均等分割の設定が行えること
- gap
- オリジナル名称の設定を作成すること
- ピクセルごとの設定を作成すること
前提
foundation/variable
使用しないbreak pointを入れておくと無駄な設定ができてしまいますので、注意してください
$break-points: (
all: '',
lg: 'screen and (max-width: 1024px)',
md: 'screen and (max-width: 820px)',
) !default;
$gaps: (
sm: (48, 46, 44),
md: (60, 58, 56),
lg: (80, 78, 76),
);
foundation/mixin
@use 'sass:map';
@mixin mq($breakpoint: md) {
@if($breakpoint == 'all') {
@content;
} @else {
@media #{map.get($break_points, $breakpoint)} {
@content;
}
}
}
使用法
display
基本
.u-d-{display値}
.u-d-{$break-points}-{display値}
grid / inline-grid
.u-d-{display値}-{均等分割数}
.u-d-{$break-points}-{display値}-{均等分割数}
パラメータ
{display値} … 'none', 'block', 'inline', 'flex', 'inline-flex', 'grid', 'inline-grid'
{均等分割数} … grid / inline-gridの場合のみ有効 で、1及び3~10まで。指定ない場合は均等2分割
gap
オリジナル名称の設定
.u-gap-{$gaps}
ピクセルごとの設定
.u-gap-{サイズ}
.u-gap-{$break-points}-{サイズ}
.u-gap-{タイプ}-{サイズ}
.u-gap-{タイプ}-{$break-points}-{サイズ}
パラメータ
{display値} … 'none', 'block', 'inline', 'flex', 'inline-flex', 'grid', 'inline-grid'
{タイプ} … c: column-gap、r: row-gap
{$gaps} は、上記前提を参照
使用例
display
<div class="u-d-grid-4 u-d-grid-lg-3 u-d-grid-md-1">
・・・
</div>
上記では、画面幅により下記のようになります
- 1025px以上:「u-d-grid-4」で4分割
- 821~1024px:「u-d-grid-lg-3」で3分割
- 820px以下:「u-d-grid-md-1」で1分割
<br class="u-d-none u-d-block u-d-none" />
上記では、画面幅により下記のようになります
- 1025px以上:改行なし
- 821~1024px:改行あり
- 820px以下:改行なし
gap
<div class="u-d-grid-3 u-gap-r-36 u-gap-c-24">
・・・
</div>
上記では、gridの3分割の状態になり、下記のようになります
- 縦方向のgap:row-gapが3.6rem
- 横方向のgap:column-gapが2.4rem
<div class="u-d-grid-3 u-gap-sm">
・・・
</div>
上記では、gridの3分割の状態になり、画面幅により下記のようになります
- 1025px以上:gapが縦横4.8rem
- 821~1024px:gapが縦横4.6rem
- 820px以下:gapが縦横4.4rem
$gapsの設定は、現在下記となっていますが、この自由に設定を追加できます。また、後からそれぞれの設定を変更すれば、一気に更新することもできます。
$gaps: (
sm: (48, 46, 44),
md: (60, 58, 56),
lg: (80, 78, 76),
);
最終形
上記の前提は、各環境にあわせ別ファイルとして振り分け、下記ファイルで読み込んでください
display
@use '../../foundation/variable' as *;
@use '../../foundation/mixin' as *;
// -----------------------------------------------------------------
// Display
// -----------------------------------------------------------------
$array: ('none', 'block', 'inline', 'flex', 'inline-flex', 'grid', 'inline-grid');
.u-d {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@each $key in $array {
@if $breakpoint=='all' {
&-#{$key} {
display: #{$key} !important;
@if $key == 'grid' or $key=='inline-grid' {
@for $i from 2 through 10 {
@if $i==2 {
grid-template-columns: repeat($i, 1fr) !important;
} @else {
&-#{$i} {
display: #{$key};
grid-template-columns: repeat($i, 1fr) !important;
}
}
}
}
}
} @else {
&-#{$breakpoint}-#{$key} {
display: #{$key} !important;
@if $key == 'grid' or $key=='inline-grid' {
@for $i from 2 through 10 {
@if $i==2 {
grid-template-columns: repeat($i, 1fr) !important;
} @else {
&-#{$i} {
display: #{$key};
grid-template-columns: repeat($i, 1fr) !important;
}
}
}
}
}
}
}
}
}
}
gap
@use 'sass:map';
@use '../../foundation/variable' as *;
@use '../../foundation/mixin' as *;
// -----------------------------------------------------------------
// Gap
// -----------------------------------------------------------------
$array: (
c: 'column',
r: 'row'
);
.u-gap {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
// オリジナル名称の設定
@each $name, $values in $gaps {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
#{gap}: #{Rem(nth($values, $num))} !important;
}
@each $key, $type in $array {
&-#{$key}-#{$name} {
#{$type}-gap: #{Rem(nth($values, $num))} !important;
}
}
}
// ピクセルごとの設定
@for $i from 1 through 100 {
@if $breakpoint == 'all' {
&-#{$i} {
gap: Rem($i) !important;
}
@each $key, $type in $array {
&-#{$key}-#{$i} {
#{$type}-gap: Rem($i) !important;
}
}
} @else {
&-#{$breakpoint}-#{$i} {
gap: Rem($i) !important;
}
@each $key, $type in $array {
&-#{$key}-#{$breakpoint}-#{$i} {
#{$type}-gap: Rem($i) !important;
}
}
}
}
}
}
}
解説
上記最終系を一つずつ見ていきます。下記はdisplay及びgapで同じです
ループ設定
$break-points: (
all: '',
lg: 'screen and (max-width: 1024px)',
md: 'screen and (max-width: 820px)',
) !default;
上記$break-pointsをループして展開していきます(gapの場合は、u-dの部分はu-gapとなります。以下同様)
.u-d {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
・・・
}
}
展開されるイメージは下記の通りです
.u-d {
// 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」を大きいサイズから設定していことです
これにより、画面幅が小さくなるにつれ、後述の設定が生きてくることになります。
詳細クラスの設定
display
$array: ('none', 'block', 'inline', 'flex', 'inline-flex', 'grid', 'inline-grid');
上記$arrayを展開し、各classを作成していきます
.u-d {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@each $key in $array {
@if $breakpoint=='all' {
&-#{$key} {
display: #{$key} !important;
@if $key == 'grid' or $key=='inline-grid' {
@for $i from 1 through 10 {
@if $i==2 {
grid-template-columns: repeat($i, 1fr) !important;
} @else {
&-#{$i} {
display: #{$key};
grid-template-columns: repeat($i, 1fr) !important;
}
}
}
}
}
} @else {
&-#{$breakpoint}-#{$key} {
display: #{$key} !important;
@if $key == 'grid' or $key=='inline-grid' {
@for $i from 1 through 10 {
@if $i==2 {
grid-template-columns: repeat($i, 1fr) !important;
} @else {
&-#{$i} {
display: #{$key};
grid-template-columns: repeat($i, 1fr) !important;
}
}
}
}
}
}
}
}
}
上記ブロックの真ん中の部分を解説していきます
@each $key in $array {
displayプロパティの値の一覧です。よく使う値があれば、追加してください
@if $breakpoint=='all' {
・・・
} @else {
・・・
}
$break-points配列のキーがallの場合とそれ以外に振り分けています
allは、media queryに左右されない値を設定するために、独自に設定したものです
@if $breakpoint=='all' {
&-#{$key} {
display: #{$key} !important;
・・・
}
} @else {
&-#{$breakpoint}-#{$key} {
display: #{$key} !important;
}
・・・
}
上記で、をつかった「文字列補間(String Interpolation)」の「&-#{$key}」は、「#{$key}」の$keyに$arrayの値が一つずつ設定されます。
また、「display: #{$key} !important;」も同様に$keyに$arrayの値が一つずつ設定されます。
下記のように展開されるイメージです
// all
.u-d-none {
display: none !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-d-none {
display: none !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-d-none {
display: none !important;
}
}
・・・
// all
.u-d-inline-grid
display: inline-grid !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-d-inline-grid
display: inline-grid !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-d-inline-grid
display: inline-grid !important;
}
}
さらに「grid」と「inline-grid」の場合のみ分割数を設定できるようにしています
@for $i from 1 through 10 {
@if $i==2 {
grid-template-columns: repeat($i, 1fr) !important;
} @else {
&-#{$i} {
display: #{$key};
grid-template-columns: repeat($i, 1fr) !important;
}
}
}
上記のループは1~10としています。1は狭いサイズの場合に使用することを想定しています
また、「2」をデフォルトとして設定し、1及び3~10が「-3」のように設定できるようにしています
下記が展開イメージとなります
・・・
// all
.u-d-grid-1 {
display: grid !important;
grid-template-columns: repeat(1, 1fr) !important;
}
.u-d-grid {
display: grid !important;
grid-template-columns: repeat(2, 1fr) !important;
}
.u-d-grid-3 {
display: grid !important;
grid-template-columns: repeat(3, 1fr) !important;
}
.u-d-grid-4 {
display: grid !important;
grid-template-columns: repeat(4, 1fr) !important;
}
・・・
// lg
@media 'screen and (max-width: 1024px)' {
.u-d-lg-grid-1 {
display: grid !important;
grid-template-columns: repeat(1, 1fr) !important;
}
.u-d-lg-grid {
display: grid !important;
grid-template-columns: repeat(2, 1fr) !important;
}
.u-d-lg-grid-3 {
display: grid !important;
grid-template-columns: repeat(3, 1fr) !important;
}
.u-d-lg-grid-4 {
display: grid !important;
grid-template-columns: repeat(4, 1fr) !important;
}
・・・
}
// md
@media 'screen and (max-width: 820px)' {
.u-d-md-grid-1 {
display: grid !important;
grid-template-columns: repeat(1, 1fr) !important;
}
.u-d-md-grid {
display: grid !important;
grid-template-columns: repeat(2, 1fr) !important;
}
.u-d-md-grid-3 {
display: grid !important;
grid-template-columns: repeat(3, 1fr) !important;
}
.u-d-md-grid-4 {
display: grid !important;
grid-template-columns: repeat(4, 1fr) !important;
}
}
・・・
gap
オリジナル名称の設定
配列「$gaps」を展開していきます
$gaps: (
sm: (48, 46, 44),
md: (60, 58, 56),
lg: (80, 78, 76),
);
$gapsにある各変数のカッコ内の数字は、$break-pointsの数と同じ数設定しています
したがって、ここは、左から「all」「lg」「md」のpxサイズを数値のみで設定しています
.u-gap {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@each $name, $values in $gaps {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
gap: #{Rem(nth($values, $num))} !important;
}
@each $key, $type in $array {
&-#{$key}-#{$name} {
#{$type}-gap: #{Rem(nth($values, $num))} !important;
}
}
}
}
}
}
上記ブロックの真ん中の部分を解説していきます
@each $name, $values in $gaps {
$gapsをeach文で展開していますが、ここでは、最初は「$name」に「sm」が、「$values」には「(48, 46, 44)」が入ることになります
$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} {」は、$gapsの最初のキーのsmを使用して「&-sm {」となり、結果として「.u-gap-sm」が作成されます
gap: #{Rem(nth($values, $num))} !important;
「nth($values, $num)」では、nth関数で、$values、つまり「(48, 46, 44)」のうち、$numの値の順番(最初は「1」)にある値を取得し、Rem関数でremの値に変換しています
結果として「gap: 4.8rem !important;」という記述が作成されます
次にcolumとrowの設定を追加しています
$array: (c: 'column', r: 'row');
@each $key, $type in $array {
&-#{$key}-#{$name} {
#{$type}-gap: #{Rem(nth($values, $num))} !important;
}
}
下記が展開イメージとなります
// all
.u-gap-sm {
gap: 4.8rem !important;
}
.u-gap-c-sm {
gap: 4.8rem !important;
}
.u-gap-r-sm {
gap: 4.8rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-gap-sm {
gap: 4.6rem !important;
}
.u-gap-c-sm {
gap: 4.6rem !important;
}
.u-gap-r-sm {
gap: 4.6rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-gap-sm {
gap: 4.4rem !important;
}
.u-gap-c-sm {
gap: 4.4rem !important;
}
.u-gap-r-sm {
gap: 4.4rem !important;
}
}
・・・
ピクセルごとの設定
次にピクセル単位の設定を行います
下記のループ部分は、上記と同じです。2番目のブロックについて解説します
.u-gap {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@for $i from 1 through 100 {
@if $breakpoint == 'all' {
&-#{$i} {
gap: Rem($i) !important;
}
@each $key, $type in $array {
&-#{$key}-#{$i} {
#{$type}-gap: Rem($i) !important;
}
}
} @else {
&-#{$breakpoint}-#{$i} {
gap: Rem($i) !important;
}
@each $key, $type in $array {
&-#{$key}-#{$breakpoint}-#{$i} {
#{$type}-gap: Rem($i) !important;
}
}
}
}
}
}
}
今回は、0~100の数値で設定しています
@for $i from 1 through 100 {
「@for $i from 0 through 180」が0~100までの数値をループし$iに0から順に数字を代入しています
@if $breakpoint=='all' {
上記同様allの場合の振り分けをしています
下記が展開イメージです
// all
.u-gap-1 {
gap: 0.1rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-gap-lg-1 {
gap: 0.1rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-gap-md-1 {
gap: 0.1rem !important;
}
}
・・・
// all
.u-gap-100 {
gap: 10rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-gap-lg-100 {
gap: 10rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-gap-md-100 {
gap: 10rem !important;
}
}
まとめ
以上でdisplayとgapのユーティリティーの完成となります
全設定が吐き出されてしまうと膨大な量になってしまいますが、弊社では、vite+@fullhuman/postcss-purgecssなどを使って、余計なclassは入らないようにしていますので、そういった工夫も必要になるかと思います
コーディングの省力化に貢献できれば幸いです
文責:フライング・ハイ・ワークス代表 松田 治人(まつだ はるひと)
会社では、Laravelを中心としたエンジニアとして働いており、これまでに50本以上のLaravelによるWebアプリケーションの構築や東京でホームページ制作をしています。
エンジニアとして弊社で働きたい方、お仕事のご相談など、お待ちしております。
WEBサイト・ホームページの制作をご検討の方
フライング・ハイ・ワークスの紹介
フライング・ハイ・ワークスは、東京のホームページ制作・Web制作会社・システム開発会社です。東京都及びその近郊(首都圏)を中心として、SEO対策を意識したPC及びスマホのサイトをワンソース(レスポンシブ対応)で制作します。
実績
デザイナーチームは、グラフィックデザインやイラストの制作も得意としており、著作権を意識しない素材の提供が可能です。システム・コーディングチームでは、Laravelなどを使用したスクラッチからのオリジナルシステム開発を始め、WordPressのカスタマイズを得意としております。
また、SEOやランディングページ(LP)、広告向けバナーなどを他社様でやっていた作業の引継ぎでも問題ありません。制作実績は多数ございますので、お客様に合わせたご提案が可能です。
500点以上のフライング・ハイ・ワークスの制作実績ページをご覧ください。