[Sass]泣くほど早い…今すぐ使える便利なmixin集

  • あとで読みたい人は…
 [Sass]泣くほど早い…今すぐ使える便利なmixin集

こんにちは、@cappeeです。

本格的にSass(SCSS)を仕事で使うようになってから早半年。

色々と試行錯誤しながら効率的にコーディングできるように工夫してきましたが、やっとこさある程度カタチになってきました。

これからSassを導入するというデザイナーさんもいるかと思うので、コピペで今すぐ使える便利なmixinをまとめて公開したいと思います。

泣くほどコーディングが早くなりますよ。

※Sass+Compassのインストールがまだの方はこちらをご覧ください!
Sublime Text 2 + Sass + Compass + Emmet 最強説!導入方法と自動アップロードの設定まとめ

フォントサイズ

CSS3の新しい単位 rem でフォントサイズを指定するmixinです。(IE9以降対応)
相対指定の em や % 、絶対指定の px が一般的だと思いますが、
rem は親の影響を受けずにフォントサイズを指定することができます。
[参考]フォントサイズの指定はCSS3の「rem」が便利そう

@mixin font-size($size, $base: 16) {
  font-size: $size + px;
  font-size: ($size / $base) + rem;
}

テキストシャドウ

文字に1pxの黒いシャドウ

文字に簡単にシャドウをかけることができます。
シャドウの距離やぼかしはサイトのデザインに合わせて変更します。
色の指定を透過で調整することで濃度を簡単に調整できるので便利です。

@mixin text-shadow-black($opacity: .4){
  text-shadow: 0 1px 0 rgba(#000, $opacity);
}

文字に1pxの白いシャドウ

最近よく見る文字に立体感のでるズルいアレです。

@mixin text-shadow-white($opacity: 1){
  text-shadow: 0 1px 0 rgba(#FFF, $opacity);
}

ポジション

ポジションは結構多様するので下の4つをmixinにしました。
pxも一緒に書いてますが縦中央にする際パーセント指定(50%)をする場合もあるのでmixinに入れなくてもOKです。

@mixin absolute-top-left($top: 0, $left: 0) {
  position: absolute;
  top: $top + px;
  left: $left + px;
}
@mixin absolute-top-right($top: 0, $right: 0) {
  position: absolute;
  top: $top + px;
  right: $right + px;
}
@mixin absolute-bottom-left($bottom: 0, $left: 0) {
  position: absolute;
  bottom: $bottom + px;
  left: $left + px;
}
@mixin absolute-bottom-right($bottom: 0, $right: 0) {
  position: absolute;
  bottom: $bottom + px;
  right: $right + px;
}

グラデーション

上下に明→暗

lighten を使うことでメインのカラーを指定すれば簡単にグラデーションがつくれます。
$hogeにはデフォルトのカラーを指定することも可能です。変数でも16進数でも大丈夫です。
デフォルトのカラーを指定しない場合は「:$hoge」の部分を削除してください。

@mixin gradient-top-lighten($color:$hoge, $lighten:10){
  background-color: $color;
  @include background-image(linear-gradient(lighten($color, $lighten) 0%, $color 100%));
}

上下に暗→明

darken を使うことで上とは逆の暗→明のグラデーションがつくれます。

@mixin gradient-top-darken($color:$hoge, $darken:10){
  background-color: $color;
  @include background-image(linear-gradient(darken($color, $darken) 0%, $color 100%));
}

IE8~9に対応する

上記のmixinだとグラデーション非対応のIE8~9では適用されません。
受託の場合は対応ブラウザによって適用したいケースもあるかと思うので、下を上記mixinに追加すればIE8~9にもグラデーションが表示されます。
ただし、その分重くなるので個人的にはプログレッシブ・エンハンスメントを推奨します。
(古いブラウザでデザインが適用されなくてもコンテンツが問題なく見えていれば問題なしという考え)

@include filter-gradient(lighten($color, $lighten), $color, vertical);

IE9に対応する

IE9だけに対応すればOKという場合はmixinではなく、Compassにあるブラウザーサポートの変数で設定します。
どこでもいいですが、設定用のscssファイルがある場合はそこに下記の一行を追加すれば大丈夫です。
[参考]Compassでベンダープレフィックスなどのブラウザーサポートを制御する

$experimental-support-for-svg: true;

背景画像

CSS Spriteの設定

mixinの前にCSS Spriteを出力する設定をします。
私はSprite画像を主に以下の2つに分けて書き出しています。

  1. 文字を置換する画像文字の背景に入れる画像
  2. アイコン画像(文字の左側に配置)

マジックインポートというCSS Spriteのcssをすべて自動で書き出してくれるとても便利な機能もありますが、実際はbackground-position,width,heightなど変更したい場合が多いので今回は sprite-map で指定します。

1)文字の背景に入れる画像と文字を置換する画像

sprite-mapを指定します。
文字の背景に入れる画像と文字を置換する画像の場合は、スプライト画像のレイアウトを「$layout: smart」にして余白なく画像を配置するように指定します。
なぜなら画像サイズが大きくなりすぎるとiOSで表示の制限がかかるからです。

$replace: sprite-map("replace/*.png", $layout:smart);
$replace-img: sprite-url($replace);

※iOS(iPhone,iPad)での注意
Spriteなどの画像が大きくなりすぎるとiOSで表示の制限がかかるので気をつけましょう。
3メガピクセル以上の画像は縮小されて表示されるので、その場合は各画像を敷き詰めてレイアウトする($layout:smart)か、小分けにSprite画像を書き出すなどの対処が必要です。

2)アイコンなど文字の左側に配置する画像

アイコンのレイアウトは何も指定しなければ縦一列に並びます。
アイコンの場合は余白がほしいので「$spacing」に余白分のpxを指定します。

$icon: sprite-map("icon/*.png", $spacing:50px);
$icon-img: sprite-url($icon);

プレースホルダーセレクタの指定

さらにmixinで使うextend専用のプレースホルダーセレクタの記述(%セレクタの部分)をしておきます。
extendを使わないとmixinを使ったすべてのセレクタで同じbackground-imageの指定がされてしまうので、記述が同じ部分はextendを使って簡潔にします。

%sprite-background {
  background-image: $replace-img;
  background-repeat:no-repeat;
}
%sprite-replace {
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

※extend多用の注意
extendを使うとどうしてもセレクタの数が増えてしまいます。
IE9以下では1つのCSSファイルにつき4,095個までしかセレクタを認識しないという制限がありますので気をつけましょう。

文字の背景に画像を入れる

文字の後ろに背景画像を表示するmixinです。
background-position,width,heightが自動で出力されるためこのmixinを使うと画像の位置やサイズが簡単に指定できます。

@mixin sprite-bg-dimensions($name) {
  @extend %sprite-background;
  @include sprite($replace, $name, true);
}

以下のようにセレクタ内でincludeしてください。

.selecter {
  @include sprite-bg-dimensions(filename);
}

CSSの出力結果です。

background-image: url('../img/replaces.png');
background-repeat: no-repeat;
background-position: -16px -42px;
height: 16px;
width: 60px;

画像位置を手動で指定したい場合

デザインによってはwidth,heightを指定せず、画像位置も手動で調整したい場合があります。
下のような柔軟なmixinも用意しておくと便利です。使用頻度は少ないかな。
background-position はデフォルトでSpriteのXとYが入るので、そこを基準に●px移動したいなど微調整をすることができます。

@mixin sprite-bg-position($name, $x: 0, $y: 0) {
  @extend %sprite-background;
  @include sprite-background-position($replace, $name, $x, $y);
  background-repeat: no-repeat;
}

文字を画像で置換する

ナビゲーションや見出しなど文字を画像で置換するためのmixinです。
上の「sprite-bg-dimensions」mixinをまるっとincludeして、文字を隠すプロパティだけ指定すればOKです。

@mixin sprite-replace($name) {
  @include sprite-bg-dimensions($name);
  @extend %sprite-replace;
}

以下のようにセレクタ内でincludeしてください。

.selecter {
  @include sprite-replace(filename);
}

CSSの出力結果です。

background-image: url('../img/replaces.png');
background-repeat: no-repeat;
background-position: -16px -42px;
height: 16px;
width: 60px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;

上記のようなmixinをつくらずにCompassのmixinで画像置換を指定することも可能です。
個人的にはtext-indentをネガティブ(マイナス)で指定しなくないので自分でmixinをつくっています。
(SEO的にGoogleからスパムとされる可能性があるという噂もあったので一応。。経験上から言ってもマイナスでも問題ないとは思います!)

SCSS

@include sprite-replace-text($replace, name, true);

※true/falseは画像サイズの出力を指定できます。

CSS

text-indent: -119988px;
overflow: hidden;
text-align: left;
background-position: -60px 0;
height: 96px;
width: 96px;
background-image: url(/assets/sp/replace-sf0d9e3bfd2.png);
background-repeat: no-repeat;

アイコン画像(左側)

文字の左側にアイコン画像を表示するためのmixinです。
background-positionはアイコンのサイズによって変更したいので、上記と同じくデフォルトの位置を基準に微調整できるようにしてます。
また、私はpadding-leftも自動的に出力するようにしています。これでかなり楽できますよ。
デフォルトは「画像の横幅+4px」分が出力されるようにしていますが、デザインによっては調整したい場合もあるので手動でもpadding-leftを指定することが可能です。

@mixin sprite-icon($name, $x: 0, $y: 0, $pl: 4) {
  @include sprite-background-position($icons, $name, $x, $y);
  padding-left: image-width(sprite-file($icons, $name)) + $pl;
}

以下のように任意のセレクタでincludeして使ってください。
アイコンはclass名を「icon-xx」と先頭部分を共通化し、属性セレクタでスプライト画像のパスを指定すると便利です。
class名を共通化できない場合は、extend化してmixinにしてもOKです。

[class*="icon-"]{
  background-image: $icon-img;
  background-repeat: no-repeat;
}
.icon-home {
  @include sprite-icon(home);
}
.icon-li {
  @include sprite-icon(li, 0, 2, 12);
}

CSSの出力結果です。

[class*="icon-"]{
  background-image: $icon-img;
  background-repeat: no-repeat;
}
.icon-home {
  background-position: 0 0;
  padding-left: 21px;
}
.icon-li {
  background-position: 0 -66px;
  padding-left: 12px;
}

アイコン画像(右側)

まれにハテナマークなど文字の右側に画像を表示したいケースもあります。
下記のように画像の位置を右基準でCSS Spriteを指定してもいいのですが
IE9+なのとどっちにしてもSprite画像では位置調整に無理がでてきてしまいます。

background-position: bottom 10px right 10px;

なので、右側に表示したいアイコンに関してはSprite画像を使用せずに個別に指定するようにしています。
さらに inline-image にすることで dataURI で出力されるためこれならリクエスト数も減らせます。
(使いすぎると逆に表示が重くなる場合もあるので注意です)

@mixin icon-right($name, $pl: null) {
  background: inline-image("icons/#{$name}.png") no-repeat 100% 50%;
  @if $pl {
    padding-right: $pl + px;
  } @else {
    padding-right: image-width("icons/#{$name}.png") + 4;
  }
}

アニメーション

animationプロパティを使用する場合に便利なmixinです。
ペンダープレフィックスをmixinの方で指定するので、includeがとても簡潔になります。

$prefixes: ("-webkit-", "-moz-", null);
@mixin keyframes($name){
  @-webkit-keyframes $name {
    @content;
  }
  @-moz-keyframes $name {
    @content;
  }
  @keyframes $name {
    @content;
  }
}
@mixin animation($name, $duration, $timing, $delay, $count, $direction: null) {
  @each $prefix in $prefixes {
      #{$prefix}#{animation}: $name $duration $timing $delay $count $direction;
  }
}

以下のようにセレクタ内でincludeしてください。

.selecter {
  @include animation(opacity, 3s, ease, 0s, 1);
}
@include keyframes(opacity) {
  0% {
    @include opacity(0);
  }
  100% {
    @include opacity(1);
  }
}

CSSの出力結果です。

.selecter {
  -webkit-animation: opacity 3s ease 0s 1;
  animation: opacity 3s ease 0s 1;
}
@-webkit-keyframes opacity {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@-moz-keyframes opacity {
  0% {
    opacity: 0;
    }
  100% {
    opacity: 1;
  }
}
@keyframes opacity {
  0% {
    opacity: 0;
    }
  100% {
    opacity: 1;
  }
}

長々と見ていただいてありがとうございます!
使えそうなmixinはありましたか?

スマホサイト制作で使えるRetina対応のmixinはこちらをご覧ください!
[決定版]Retina対応したスプライト画像のmixin

サイト毎に調整してうまくmixinを活用してくださいね。
泣いちゃうくらいコーディングが倍速になります。

もっといいmixinがあるよ!って方はお気軽にコメントください!
まだまだ改良もできる気がするので都度更新していきたいと思いますー。

[14.01.09]「文字を画像で置換する」に追記しました。
[14.01.23]「グラデーション」に補足を追記しました。
[14.02.27]「アイコン画像」のpaddingもinclude時に調整できるように変更し、全体的にcssの出力結果などを追加しました。
[14.03.04]「アイコン画像」のpaddingの指定方法を変更しました。

Pocket
article clipper [Sass]泣くほど早い…今すぐ使える便利なmixin集

2 thoughts on “[Sass]泣くほど早い…今すぐ使える便利なmixin集

  1. Pingback: Compass: CSS3 animation の prefix 付きコードを生成する | deadwood

  2. Pingback: SASS導入のために役立つサイトをピックアップ | 楽天ティップスRakutenTips

コメントを残す

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>