SASSにおけるミックスイン
この記事ではSASSにおけるミックスインについて説明します。
SASSにおけるミックスインについて実際的なサンプルを含めて解説します。
YouTube Video
SASSにおけるミックスイン
概要 - ミックスインとは何か
ミックスインは、よく使うスタイルプロパティのセットを再利用可能な関数のように定義して、必要な場所で呼び出せる仕組みです。CSSクラスや複数のプロパティをDRYに保つのに非常に便利です。
例:最も単純なミックスイン
以下は単純なミックスインの例で、角丸と影をまとめて再利用します。このミックスインを呼ぶだけで同じ見た目を複数要素に適用できます。
1// Simple mixin that applies border-radius and box-shadow
2@mixin card-style {
3 border-radius: 8px;
4 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
5 background: #fff;
6}
7
8.card {
9 @include card-style;
10 padding: 1rem;
11}- このミックスインを使うと、スタイルを直接繰り返す必要が無くなります。
- 呼び出しは
@include card-style;の1行で済みます。
引数付きミックスイン(パラメータ)
ミックスインは関数のように引数を受け取れます。これにより、同じロジックで見た目を変えられます。次は色を引数に取る例です。
1// Mixin with parameters: accepts a color and optional radius
2@mixin colored-box($bg-color, $radius: 4px) {
3 background-color: $bg-color;
4 border-radius: $radius;
5 padding: 0.75rem;
6}
7
8.box-primary {
9 @include colored-box(#007acc);
10}
11
12.box-custom {
13 @include colored-box(#ffcc00, 12px);
14}- デフォルト値を与えることで、引数を省略したときの振る舞いも制御できます。
- この例ではデフォルト半径が使われ、背景色のみ上書きしています。
可変長引数(...)を使うケース
複数の値を受け取りたいときは可変長引数($args...)が使えます。これはユーティリティクラス生成やフォールバックのリスト渡しに便利です。
複数のフォントファミリーや複数のシャドウ値を渡す場面で役立ちます。
1// Mixin that accepts variable arguments and forwards them to box-shadow
2@mixin multi-shadow($shadows...) {
3 box-shadow: $shadows;
4}
5
6.panel {
7 @include multi-shadow(0 2px 4px rgba(0,0,0,0.08), 0 8px 16px rgba(0,0,0,0.06));
8}- 呼び出し側で複数のシャドウをカンマ区切りで渡せます。
- これにより、同じミックスインで単純〜複雑なシャドウを共通化できます。
@content を使ったミックスイン — ブロックを受け取る
@contentを使うと、ミックスインは呼び出し側からスタイルのブロックを受け取ることができます。これにより、ミックスインが共通の外枠を提供し、内部の詳細を呼び出し側で指定できます。
1// Mixin that sets up a responsive container and yields to caller via @content
2@mixin responsive-container($max-width: 1200px) {
3 margin-left: auto;
4 margin-right: auto;
5 padding-left: 1rem;
6 padding-right: 1rem;
7 max-width: $max-width;
8
9 @content; // place where caller's styles are inserted
10}
11
12.header {
13 @include responsive-container(1000px) {
14 display: flex;
15 align-items: center;
16 justify-content: space-between;
17 }
18}- 呼び出し側では
@includeにブロックを付けて、中のスタイルを差し込みます。 - このパターンはレイアウトの共通枠(グリッド、カード、フォーム)で便利です。
条件分岐やループを使った高度なミックスイン
@ifや@forなどの制御構造はミックスイン内でも使えます。これを利用してユーティリティの自動生成やレスポンシブ設定をまとめます。
以下は、生成するユーティリティクラスの幅を自動で作る例です。
1@use 'sass:math';
2
3// Mixin that generates width utility classes from a list of fractions
4@mixin generate-widths($fractions) {
5 @each $name, $fraction in $fractions {
6 .w-#{$name} {
7 width: math.percentage($fraction);
8 }
9 }
10}
11
12$widths: (
13 '1-4': 0.25,
14 '1-3': 0.3333,
15 '1-2': 0.5,
16 '3-4': 0.75
17);
18
19@include generate-widths($widths);- 呼び出し側で生成したい分数のマップを渡すだけで、対応するユーティリティクラスをまとめて自動生成できます。
- この方法を使うことで、設計上の一貫性を保ちながら、手作業によるスタイル定義を減らせるという利点があります。
ミックスイン vs プレースホルダー(%placeholder)の使い分け
ミックスインはプロパティのセットをそのまま挿入するのに対し、プレースホルダーは @extend を使ってスタイルを継承するときに利用します。ミックスインは場合によっては重複したCSSを生成しますが、@extend は特定のケースでよりコンパクトなCSSを生成できます。
それぞれの用途や生成されるCSSの違いを理解することで、最適な方法を選択できるようになります。
1// Placeholder example (for comparison)
2%btn-base {
3 display: inline-block;
4 padding: 0.5rem 1rem;
5 border-radius: 4px;
6}
7
8.btn-primary {
9 @extend %btn-base;
10 background: #007acc;
11 color: #fff;
12}
13
14.btn-secondary {
15 @extend %btn-base;
16 background: #e0e0e0;
17}- プレースホルダーを
@extendすると、複数のセレクタが1つのルールに統合され、よりコンパクトなCSSになる場合があります。 - 一方、ミックスインは必要な場所へプロパティを直接挿入するため、柔軟に使える上に、意図しないセレクタ統合が起きにくいという利点があります。
よくある実践パターン(レスポンシブ、ベンダープレフィックスなど)
実務ではベンダープレフィックスやレスポンシブの共通処理をミックスインにしておくと便利です。以下はトランスフォームとプレフィックスをまとめた例です。ブラウザ互換のための記述を1箇所にまとめられ、保守が楽になります。
1// Mixin for transform with vendor prefixes
2@mixin transform($value) {
3 -webkit-transform: $value;
4 -ms-transform: $value;
5 transform: $value;
6}
7
8.icon-rotate {
9 @include transform(rotate(45deg));
10}- 使い方はシンプルで、どこでも
@include transform(rotate(10deg));のように利用できます。 - 将来的にプレフィックスが不要になった場合も、ミックスインを更新するだけで全体へ反映されるため、メンテナンスが容易になります。
カードとボタンをまとめた実用例
以下は、カード内で使用するボタンスタイルをミックスインで共通化し、テーマカラーに合わせて切り替えられるようにした例です。
実務で頻繁にある「カード+ボタン」パターンをミックスインで整理しています。
1// Simple mixin that applies border-radius and box-shadow
2@mixin card-style {
3 border-radius: 8px;
4 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
5 background: #fff;
6}
7
8// Mixin for transform with vendor prefixes
9@mixin transform($value) {
10 -webkit-transform: $value;
11 -ms-transform: $value;
12 transform: $value;
13}
14
15// Button mixin with theme and size parameters
16@mixin btn($bg, $color: #fff, $padding: 0.5rem 1rem) {
17 display: inline-block;
18 padding: $padding;
19 background: $bg;
20 color: $color;
21 border-radius: 6px;
22 text-decoration: none;
23 cursor: pointer;
24 @include transform(translateY(0)); // reuse earlier transform mixin
25}
26
27// Card mixin that accepts inner button styling via @content
28@mixin card($gap: 1rem) {
29 @include card-style; // reuse earlier card-style mixin
30 padding: $gap;
31 @content;
32}
33
34.card-feature {
35 @include card {
36 .title { font-size: 1.125rem; margin-bottom: 0.5rem; }
37 .cta {
38 @include btn(#007acc);
39 }
40 }
41}
42
43.card-warning {
44 @include card {
45 .title { font-weight: bold; }
46 .cta {
47 @include btn(#ff6600);
48 }
49 }
50}- このミックスイン群を使って、コンポーネントを簡潔に記述できます。
パフォーマンスと生成されるCSSに注意する
ミックスインは呼び出すたびにプロパティが挿入されるため、同じルールを大量に @include すると最終的なCSSが大きくなります。必要に応じてプレースホルダーやコンポーネント設計と組み合わせて最適化できます。
さらに、次のような対策も有効です。
- 使用頻度の高いスタイルはクラス化して再利用します。
- 共通のパターンは
@contentでまとめるようにします。 - 複雑なユーティリティ生成はビルド時にだけ行うようにします。
デバッグしやすくするコツ
ミックスインを活用する際は、デバッグや保守性を高めるための工夫も重要です。ミックスイン内で明確な変数名を使ったり、要所にコメントを追加したりすると、後から読み返すときに理解しやすくなります。また、機能が複雑になってきた場合は、ミックスインを小さな単位に分割すると、テストしやすくなり、保守性も向上します。
さらに、ソースマップを有効にしておくと「どのミックスインがどのCSSを生成したか」を簡単に追跡できるため、問題の切り分けがスムーズになります。
以下は、ドキュメントコメントを備えたわかりやすいミックスインの例です。
1// Example: readable mixin with clear param names and comments
2/// Adds a subtle focus ring for accessibility
3/// $color - ring color
4/// $size - thickness of the ring
5@mixin focus-ring($color: #007acc, $size: 2px) {
6 outline: none;
7 box-shadow: 0 0 0 $size rgba(blue($color), 0.15);
8}- このように整理されたドキュメントコメントがあると、チーム内で共有する際にも理解が進みやすくなります。
- SASSのドキュメントコメントは対応ツールで自動抽出できるため、スタイルガイドなどのドキュメント生成にも活用しやすくなります。
まとめ
ミックスインは、よく使うスタイルをひとまとめにして再利用できるため、コードの重複を減らし保守性を高めるのに役立ちます。また、複数のセレクタが同じルールを共有する場合は、ミックスインだけでなく @extend(プレースホルダー)を使う方法も検討できます。さらに、@content を利用するとレイアウトの枠と中身を分けて柔軟にデザインできる一方で、@include の使いすぎは生成CSSの肥大化につながるため注意が必要です。引数やデフォルト値、可変長引数を適切に活用し、ミックスインを汎用的で拡張しやすい形に整えておくことが重要です。
YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。