2024.12.26 Web制作
Scss/floccsで自作ユーティリティー margin / padding編
u-mt-20やu-pb-30など、marginでは「u-m」、paddingでは「u-p」の接頭辞がついた、margin又はpadding用ユーティリティーを作成します
フォルダ構成や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のサイズによる階層的な適用が確実にされること
- オリジナル名称の設定を作成すること
- ピクセルごとの設定を作成すること
前提
foundation/variable
使用しないbreak pointを入れておくと無駄な設定ができてしまいますので、注意してください
$break-points: (
all: '',
lg: 'screen and (max-width: 1024px)',
md: 'screen and (max-width: 820px)',
) !default;
$margins: (
base: (80, 78, 76),
sm: (50, 48, 46),
lg: (120, 118, 116),
);
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;
}
}
}
使用法
左右auto設定
.u-mx-auto
オリジナル名称の設定
.u-{マージン/パディング方向}-{$margins}
ピクセルごとの設定
.u-{マージン/パディング方向}-{数値}
.u-{マージン/パディング方向}-{$break-points}-{数値}
パラメータ
{マージン方向} … m: margin / mt: margin-top / mb: margin-bottom / mr: margin-right / ml: margin-left / my: margin-block / mx: margin-inline
{パディング方向} … p: padding / pt: padding-top / pb: padding-bottom / pr: padding-right / pl: padding-left / py: padding-block / px: padding-inline
{$margins}{$break-points}は、上記前提を参照
使用例
<div class="u-mb-30 u-mb-lg-40 u-mb-md-50">
・・・
</div>
上記では、画面幅により下記のようになります
- 1025px以上:「u-mb-30」でmargin-bottomが3rem
- 821~1024px:「u-mb-lg-40」でmargin-bottomが4rem
- 820px以下:「u-mb-md-50」でmargin-bottomが5rem
<div class="u-mt-sm">
・・・
</div>
上記では、画面幅により下記のようになります
- 1025px以上:margin-topが8rem
- 821~1024px:margin-topが7.8rem
- 820px以下:margin-topが7.6rem
$margins: (
base: (80, 78, 76),
sm: (50, 48, 46),
lg: (120, 118, 116),
);
上記$marginsの配列の名称(キー)とbreak pointごとの設定は、自由に作成できるので、例えば、buttonやblockなどの設定を作成することで、パターンにあわせた設定を作成することができる上、のち変更があれば、それぞれのmarginやpaddingを一気に更新することもできます。
また、これらは、下記すべてに設定を作成していますので、様々なオリジナルの設定が可能となります
$array: (
mt: 'margin-top',
mb: 'margin-bottom',
mr: 'margin-right',
ml: 'margin-left',
my: 'margin-block',
mx: 'margin-inline',
m: 'margin',
);
$array: (
pt: 'padding-top',
pb: 'padding-bottom',
pr: 'padding-right',
pl: 'padding-left',
py: 'padding-block',
px: 'padding-inline',
p: 'padding',
);
最終形
上記の前提は、各環境にあわせ別ファイルとして振り分け、下記ファイルで読み込んでください
margin
@use 'sass:map';
// 上記前提が記載されたファイル
@use '../../foundation/variable' as *;
@use '../../foundation/mixin' as *;
$array: (
mt: 'margin-top',
mb: 'margin-bottom',
mr: 'margin-right',
ml: 'margin-left',
my: 'margin-block',
mx: 'margin-inline',
m: 'margin',
);
@each $key, $property in $array {
.u-#{$key} {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
// オリジナル名称設定
@each $name, $values in $margins {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
#{$property}: #{Rem(nth($values, $num))} !important;
}
}
// ピクセルごとの設定
@for $i from 0 through 180 {
@if $breakpoint=='all' {
@if $i==0 {
&-#{$i} {
#{$property}: 0 !important;
}
} @else {
&-#{$i} {
#{$property}: Rem($i) !important;
}
}
} @else {
@if $i==0 {
&-#{$breakpoint}-#{$i} {
#{$property}: 0 !important;
}
} @else {
&-#{$breakpoint}-#{$i} {
#{$property}: Rem($i) !important;
}
}
}
}
}
}
}
}
.u-mx-auto {
margin-inline: auto !important;
}
padding
@use 'sass:map';
// 上記前提が記載されたファイル
@use '../../foundation/variable' as *;
@use '../../foundation/mixin' as *;
$array: (
pt: 'padding-top',
pb: 'padding-bottom',
pr: 'padding-right',
pl: 'padding-left',
py: 'padding-block',
px: 'padding-inline',
p: 'padding',
);
@each $key, $property in $array {
.u-#{$key} {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
// オリジナル名称設定
@each $name, $values in $margins {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
#{$property}: #{Rem(nth($values, $num))} !important;
}
}
// ピクセルごとの設定
@for $i from 0 through 180 {
@if $breakpoint=='all' {
@if $i==0 {
&-#{$i} {
#{$property}: 0 !important;
}
} @else {
&-#{$i} {
#{$property}: Rem($i) !important;
}
}
} @else {
@if $i==0 {
&-#{$breakpoint}-#{$i} {
#{$property}: 0 !important;
}
} @else {
&-#{$breakpoint}-#{$i} {
#{$property}: Rem($i) !important;
}
}
}
}
}
}
}
}
解説
上記最終系を一つずつ見ていきます
ループ設定
今回のmarginとpaddingは、「m」と「p」の違いくらいでほとんど差異がないので、marginの設定で確認していきます
$array: (
mt: 'margin-top',
mb: 'margin-bottom',
mr: 'margin-right',
ml: 'margin-left',
my: 'margin-block',
mx: 'margin-inline',
m: 'margin',
);
接頭辞「u-」に続く名称をキーとして、それぞれにcssのプロパティ名を記載した配列となります
@each $key, $property in $array {
.u-#{$key} {
・・・
}
}
設定した配列をeach文でループし、一行ずつ設定していきます
#をつかった「文字列補間(String Interpolation)」を使うことで、$arrayのキーで、class名を作成していきます。下記のように展開されるイメージです
.u-mt {
}
.u-mb {
}
・・・
.u-m {
}
次にmedia queryを設定していきます
$break-points: (
all: '',
lg: 'screen and (max-width: 1024px)',
md: 'screen and (max-width: 820px)',
) !default;
foundation/variableに設定している上記配列を前提にeach分で展開していきます
@each $key, $property in $array {
.u-#{$key} {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
・・・
}
}
}
}
最初の$breakpointは「all」となりますが、下記mixinでは、allの場合は、特に処理を行っていませんので、そのまま設定されます
@mixin mq($breakpoint: md) {
@if($breakpoint == 'all') {
@content;
} @else {
@media #{map.get($break_points, $breakpoint)} {
@content;
}
}
}
上記により下記のように展開されます
.u-mt {
// all
// lg
@media 'screen and (max-width: 1024px)' {
}
// md
@media 'screen and (max-width: 820px)' {
}
}
・・・
.u-m {
・・・
}
ここでのポイントは、「$break-points」を大きいサイズから設定していことです
これにより、画面幅が小さくなるにつれ、後述の設定が生きてくることになります。
オリジナル名称設定
ここまでで、最終的な各cssを記述する準備が整いました。次に配列「$margins」を展開していきます
$margins: (
base: (80, 78, 76),
sm: (50, 48, 46),
lg: (120, 118, 116),
);
$marginsにある各変数のカッコ内の数字は、$break-pointsの数と同じ数設定しています
したがって、ここは、左から「all」「lg」「md」のpxサイズを数値のみで設定しています
@each $key, $property in $array {
.u-#{$key} {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@each $name, $values in $margins {
$num: index(map.keys($break-points), $breakpoint);
&-#{$name} {
#{$property}: #{Rem(nth($values, $num))} !important;
}
}
}
}
}
}
上記ブロックの真ん中の部分を解説していきます
@each $name, $values in $margins {
$marginsをeach文で展開していますが、ここでは、最初は「$name」に「base」が、「$values」には「(80, 78, 76)」が入ることになります
$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の最初のキーのbaseを使用して「&-base {」となり、結果として「.u-mt-base」が作成されます
#{$property}: #{Rem(nth($values, $num))} !important;
「nth($values, $num)」では、nth関数で、$values、つまり「(80, 78, 76)」のうち、$numの値の順番(最初は「1」)にある値を取得し、Rem関数でremの値に変換しています
結果として「margin-top: 8rem !important;」という記述が作成されます
下記が展開イメージとなります
// all
.u-mt-base {
margin-top: 8rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-mt-base {
margin-top: 7.8rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-mt-base {
margin-top: 7.6rem !important;
}
}
・・・
// all
.u-m-base {
margin: 8rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-m-base {
margin: 7.8rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-m-base {
margin: 7.6rem !important;
}
}
ピクセルごとの設定
次にピクセル単位の設定を行います
下記のループ部分は、上記と同じです。2番目のブロックについて解説します
@each $key, $property in $array {
.u-#{$key} {
@each $breakpoint, $query in $break-points {
@include mq($breakpoint) {
@for $i from 0 through 180 {
@if $breakpoint=='all' {
@if $i==0 {
&-#{$i} {
#{$property}: 0 !important;
}
} @else {
&-#{$i} {
#{$property}: Rem($i) !important;
}
}
} @else {
@if $i==0 {
&-#{$breakpoint}-#{$i} {
#{$property}: 0 !important;
}
} @else {
&-#{$breakpoint}-#{$i} {
#{$property}: Rem($i) !important;
}
}
}
}
}
}
}
}
今回は、0~180の数値で設定しています
@for $i from 0 through 180 {
「@for $i from 0 through 180」が0~180までの数値をループし$iに0から順に数字を代入しています
@if $breakpoint=='all' {
上記同様allの場合の振り分けをしています
@if $i==0 {
$iの値が0の場合の設定を振り分けています
下記が展開イメージです
// all
.u-mt-0 {
margin-top: 0 !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-mt-lg-0 {
margin-top: 0 !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-mt-md-0 {
margin-top: !important;
}
}
・・・
// all
.u-m-180 {
margin: 18rem !important;
}
// lg
@media 'screen and (max-width: 1024px)' {
.u-m-lg-180 {
margin: 18rem !important;
}
}
// md
@media 'screen and (max-width: 820px)' {
.u-m-md-180 {
margin: 186rem !important;
}
}
上記で特殊なのは「0」設定です。全部のマージンを消したい場合には「u-m-0」が使用できます
marginの追加設定
marginのみ下記設定を追加しています
block要素などのセンター寄せなどで利用できます
.u-mx-auto {
margin-inline: auto !important;
}
まとめ
以上でmarginとpaddingのユーティリティーの完成となります
全設定が吐き出されてしまうと膨大な量になってしまいますが、弊社では、vite+@fullhuman/postcss-purgecssなどを使って、余計なclassは入らないようにしていますので、そういった工夫も必要になるかと思います
コーディングの省力化に貢献できれば幸いです
文責:フライング・ハイ・ワークス代表 松田 治人(まつだ はるひと)
会社では、Laravelを中心としたエンジニアとして働いており、これまでに50本以上のLaravelによるWebアプリケーションの構築や東京でホームページ制作をしています。
エンジニアとして弊社で働きたい方、お仕事のご相談など、お待ちしております。
WEBサイト・ホームページの制作をご検討の方
フライング・ハイ・ワークスの紹介
フライング・ハイ・ワークスは、東京のホームページ制作・Web制作会社・システム開発会社です。東京都及びその近郊(首都圏)を中心として、SEO対策を意識したPC及びスマホのサイトをワンソース(レスポンシブ対応)で制作します。
実績
デザイナーチームは、グラフィックデザインやイラストの制作も得意としており、著作権を意識しない素材の提供が可能です。システム・コーディングチームでは、Laravelなどを使用したスクラッチからのオリジナルシステム開発を始め、WordPressのカスタマイズを得意としております。
また、SEOやランディングページ(LP)、広告向けバナーなどを他社様でやっていた作業の引継ぎでも問題ありません。制作実績は多数ございますので、お客様に合わせたご提案が可能です。
500点以上のフライング・ハイ・ワークスの制作実績ページをご覧ください。