Blog : web

Sass(Scss) : メディアクエリ用のミックスイン

、『Sass入門 〜より効率的なCSSコーディング』(※電子書籍のみです)にSass 3.2の内容を追加したので、記念にメディアクエリ用のミックスインを作りました。

@mediaルールを都度記述するのは面倒ですし、同じ要素やモジュールのスタイルを各@mediaルールに分けて書くことも面倒です。今回作ったミックスインを使えば、これらの問題を解決することができます。

出力したいCSSの例

例えば次のようなCSSを出力したい場合があるとします。

CSS
/* 全てに適用 */
h1 { width: 100%; }
p { line-height: 1.4; }

/* 主にPC用 */
@media only screen and (min-width: 801px) {
  h1 { color: red; }
  p { margin: 1em 0; }
}

/* タブレット用 */
@media only screen and (min-width: 481px) and (max-width: 800px) {
  h1 { color: blue; }
  p { margin: 0.8em 0; }
}

/* スマートフォン用 */
@media only screen and (max-width: 480px) {
  h1 { color: green; }
  p { margin: 0.6em 0; }
}

これを2種類の方法で書くことができます。

  1. 要素やモジュール単位で書く方法
  2. メディア特性ごとにスタイルを書く方法

両方とも@include mq {}の中にスタイルを書き、@mediaの代わりに@ifで分けます。

1. 要素やモジュール単位でスタイルを書く方法

Scss
@include mq {
    h1 {
        @if $mq-all { // 全てに適用
            width: 100%;
        }
        @if $mq-default { // 主にPC用
            color: red;
        }
        @if $mq-tablet { // タブレット用
            color: blue;
        }
        @if $mq-sp { // スマートフォン用
            color: green;
        }
    }
    p {
        @if $mq-all {
            line-height: 1.4;
        }
        @if $mq-default {
            margin: 1em 0;
        }
        @if $mq-tablet {
            margin: 0.8em 0;
        }
        @if $mq-sp {
            margin: 0.6em 0;
        }
    }
}

2. メディア特性ごとにスタイルを書く方法

Scss
@include mq {
    @if $mq-all { // 全てに適用
        h1 {...}
        p {...}
    }
    @if $mq-default { // 主にPC用
        h1 {...}
        p {...}
    }
    @if $mq-tablet { // タブレット用
        h1 {...}
        p {...}
    }
    @if $mq-sp { // スマートフォン用
        h1 {...}
        p {...}
    }
}

1つの要素やモジュールのスタイルを一箇所に記述できるので、どちらかと言えば1つ目の方法が好みですが、場合によっては2つ目の方法も使うと良いと思います。

実は、この2つの方法を一緒に使うこともできます。

2つの方法を一緒に使う

例えば、スマートフォン向けにスタイルの追加や上書きをまとめて書きたい場合は@if $mq-sp {}の中にまとめてスタイルを書いたほうがラクです。

次のコードではh1は1つ目の方法で、それ以外は2つ目の方法で書いています。

Scss
@include mq {
    h1 {
        @if $mq-tablet {
            color: blue;
        }
        @if $mq-sp {
            color: green;
        }
    }
    @if $mq-sp {
        header { background: url(...); }
        p { margin: 0.6em 0; }
        nav { width: 100%; }
            :
    }
}

これをコンパイルすると次のようになります。

CSS
@media only screen and (min-width: 481px) and (max-width: 800px) {
  h1 {
    color: blue;
  }
}
@media only screen and (max-width: 480px) {
  h1 {
    color: green;
  }

  header {
    background: url(...);
  }

  p {
    margin: 0.6em 0;
  }

  nav {
    width: 100%;
  }
    :
}

h1の中で書いたスマートフォン用のスタイルも同じ@mediaルール内に出力されています。

このように、スタイルを書く場所が仮にバラバラであっても、メディア特性ごとの@mediaルール内にまとめられるのもこのミックスインの特長です。無駄な@mediaルールが出力されないのでCSSのファイルサイズを減らすことができます。

スタイルの出力を変数で制御しているので、@if文で2つ以上の変数を利用することで次のようなことができるのもこのミックスインの特長です。

2つの任意のメディア特性に同じスタイルを適用したい場合

同じコードを2箇所以上に書くのは避けたいところですが、タブレットとスマートフォンに同じスタイルを適用したいといった場合は次のようにします。

Scss
@include mq {
    h1 {
        @if $mq-tablet {
            margin: 0;
        }
        // タブレット "と" スマートフォンですが、
        // and ではなく or を使います
        @if $mq-tablet or $mq-sp {
            color: blue;
        }
    }
}

これをコンパイルすると次のようになります。

CSS
@media only screen and (min-width: 481px) and (max-width: 800px) {
  h1 {
    margin: 0;
    color: blue;
  }
}
@media only screen and (max-width: 480px) {
  h1 {
    color: blue;
  }
}

color: blue;はタブレット用とスマートフォン用の@mediaルール内に出力されています。当然、タブレット用のh1のスタイルはまとめられています。

メディア特性ごとにCSSファイル自体を分ける場合

メディア特性ごとにCSSファイル自体を分けてlink要素でそれぞれのファイルを読み込ませたい場合は次のようにします。

まず、スタイルを記述するパーシャルファイルを用意します(ここでは_mq.scssとします)。スタイルは要素やモジュール単位でも良いですし、メディア特性ごとに書いても良いです。

Scss
[_mq.scss]
h1 {
    @if $mq-all {
        width: 100%;
    }
    @if $mq-default {
        color: red;
    }
    @if $mq-tablet {
        color: blue;
    }
    @if $mq-sp {
        color: green;
    }
}
p {
    @if $mq-all {
        line-height: 1.4;
    }
    @if $mq-default {
        margin: 1em 0;
    }
    @if $mq-tablet {
        margin: 0.8em 0;
    }
    @if $mq-sp {
        margin: 0.6em 0;
    }
}

これを次のように各ファイルで読み込ませます。

Scss
[default.scss]
$mq-all: true;
$mq-default: true;
@import "mq";

[tablet.scss]
$mq-all: true;
$mq-tablet true;
@import "mq";

[sp.scss]
$mq-all: true;
$mq-sp true;
@import "mq";

コンパイル後のdefault.cssは次のようになります。

CSS
h1 {
  width: 100%;
  color: red;
}
p {
  line-height: 1.4;
  margin: 1em 0;
}

複数ファイルを@importしても問題ないので、スタイルをカテゴリごとや作業者ごとなど、別々のファイルに分けて管理することもできます。

ミックスインと設定用の変数

最後にそのミックスインと設定用の変数についてです。

ミックスインmqでは実は4つのミックスインを@includeして、それぞれに@contentでスタイルを渡しているだけです(@contentについては『Sass入門』を読んでもらうとして...)。とりあえず次に挙げるものが全てのコードになります。

Scss
// # Media Queries
//
// ## Breakpoints (Window Size)
//
// 0-480   : [Smartphone]
//           iPhone3/4/5(Portrait), iPhone3/4(Landscape)
//           Most Android Phone(Portrait)
// 481-800 : [Tablet, Smartphone(Landscape)]
//           iPhone5(Landscape), iPad(Portrait)
//           Most Android Phone(Landscape)
//           Newer Android Tablet(Portrait)
// 801+    : Default, iPad(Landscape), Newer Android Tablet(Landscape)
//  OR 801-1024
// 1025+   : Large Window Size, Newer Android Tablet(Landscape)

// ## Variables
$mq-all    : null !default;
$mq-sp     : null !default;
$mq-tablet : null !default;
$mq-default: null !default;
$mq-large  : null !default;

$default-mq-sp-max-width     : 480px !default;
$default-mq-tablet-min-width : $default-mq-sp-max-width + 1 !default;
$default-mq-tablet-max-width : 800px !default;
$default-mq-default-min-width: $default-mq-tablet-max-width + 1 !default;
$default-mq-large-min-width  : 1025px !default;
$default-mq-default-max-width: null !default;
// $default-mq-default-max-width: $default-mq-large-min-width - 1 !default;

// ## Wrapper
@mixin mq {
    @include mq-all     { @content; }
    // @include mq-large   { @content; }
    @include mq-default { @content; }
    @include mq-tablet  { @content; }
    @include mq-sp      { @content; }
}

// ## For All
@mixin mq-all {
    $_tmp: $mq-all;
    $mq-all: true;
    @content;
    $mq-all: $_tmp;
}

// ## For Smartphones
@mixin mq-sp(
    $max: $default-mq-sp-max-width
) {
    $_tmp: $mq-sp;
    $mq-sp: true;
    @media only screen and (max-width:#{$max}) {
        @content;
    }
    $mq-sp: $_tmp;
}

// ## For Tablets
@mixin mq-tablet(
    $min: $default-mq-tablet-min-width,
    $max: $default-mq-tablet-max-width
) {
    $_tmp: $mq-tablet;
    $mq-tablet: true;
    @media only screen and (min-width:#{$min}) and (max-width:#{$max}) {
        @content;
    }
    $mq-tablet: $_tmp;
}

// ## For PC (default)
@mixin mq-default(
    $min: $default-mq-default-min-width,
    $max: $default-mq-default-max-width
) {
    $_tmp: $mq-default;
    $mq-default: true;
    $_breakpoint: "(min-width:#{$min}) ";
    @if not($max == null) {
        $_breakpoint: $_breakpoint + "and (max-width:#{$max}) ";
    }
    @media only screen and #{$_breakpoint}{
        @content;
    }
    $mq-default: $_tmp;
}

// ## For Large Window
@mixin mq-large(
    $min: $default-mq-large-min-width
) {
    $_tmp: $mq-large;
    $mq-large: true;
    @media only screen and (min-width:#{$min}) {
        @content;
    }
    $mq-large: $_tmp;
}

ブレイクポイントについては制作するサイトの仕様に合わせて設定用の変数の値を適宜変更します。また、これまでのサンプルでは触れていませんが、大きめのウィンドウサイズ用のミックスインと変数のように必要に応じて別のものを新たに追加することもできるようになっています。

子のミックスイン

ミックスインmq@includeされている4つのミックスインについてですが、行なっていることはほとんど同じなのでmq-tabletを説明することにします。

Scss
// ## Variables
$mq-tablet : null !default;

$default-mq-sp-max-width     : 480px !default;
$default-mq-tablet-min-width : $default-mq-sp-max-width + 1 !default;
$default-mq-tablet-max-width : 800px !default;

// ## For Tablets
@mixin mq-tablet(
    $min: $default-mq-tablet-min-width,
    $max: $default-mq-tablet-max-width
) {
    $_tmp: $mq-tablet;
    $mq-tablet: true;
    @media only screen and (min-width:#{$min}) and (max-width:#{$max}) {
        @content;
    }
    $mq-tablet: $_tmp;
}

ミックスインmq-tabletでは変数$mq-tabletの値を一時的に$_tmpに保存しておいてからtrueにしています。そのあと、@mediaルールの中に@content;があるのでここにスタイルが展開されますが、その時に@if $mq-tablet {}の中のスタイルだけが出力されます。そして、最後に保存しておいた$mq-tabletの値を戻しています(外で設定された値を変えないようにしています)。

実は、子のミックスインは単体でも使うことができます。@mediaルールが@includeする度に出力されてしまいますが、局所的に使う場合には@mediaルールを書くよりもラクなので便利だと思います。

Scss
h1 {
    width: 100%;
      :
    @include mq-tablet {
        color: blue;
    }
}
コンパイル後のCSSは次のようになります。
CSS
h1 {
  width: 100%;
    :
}
@media only screen and (min-width: 481px) and (max-width: 800px) {
  h1 {
    color: blue;
  }
}

以上ですが、それにしてもメディアクエリって面倒ですね...。

Sass(Scss) Memo: 出力形式 compressed

Sassにはいくつかの出力形式がありますが、今回はcompressedについてです。
どのように出力されるのか見ていきます。

よくありそうなスタイルの記述

Scss
element+element {
    margin: 0.5em 0;
    padding: 0px;;;
    border: none;
    background-color: rgb(0,0,0);
    color: #ffffff; ;;

}
selector {
; // 空の宣言ブロック
}
CSS
element + element{margin:0.5em 0;padding:0px;border:none;background-color:black;color:#ffffff}
  • 余計な改行や空白は削除されます。
    例外として、セレクタの結合子(+ や >)の前後には空白が挿入されます。
  • 最後のプロパティのセミコロン(;)や余分なセミコロンが削除されます。
  • カラーコードは6桁のまま出力されます。3桁にはなりません。
    ただし、Mixinを通したものはどの出力形式でも条件によって出力される値が変わります。
  • rgbは可能なものはカラーコードに変換されます。
  • 0pxは0にはならず、そのまま0pxで出力されます。
  • noneは0にならず、そのままnoneで出力されます。
  • 0.5emは.5emにはならず、そのまま0.5emで出力されます。
  • 空の宣言ブロックは出力されません。

CSS/Sassコメント

Scss
selector-1 {
    margin: 0;
}
/*
 * 複数行CSSコメント
 * 複数行CSSコメント
 */
selector-2 {
    /* 1行CSSコメント */
    // Sassコメント
    padding: 0;
}
/*!
 * !付きの複数行CSSコメント
 * !付きの複数行CSSコメント
 */
selector-3 {
    /*! !付きの1行CSSコメント */
    color: red;
}
body /*! */ element {
    width: 100px;
}
CSS
selector-1{margin:0}selector-2{padding:0}/*
 * !付きの複数行CSSコメント
 * !付きの複数行CSSコメント
 */selector-3{/* !付きの1行CSSコメント */;color:red}body element{width:100px}
  • CSSコメントは削除されます(Sassコメントはどのコンパイル形式でも削除されます)。
  • 「/*!」から始まるCSSコメントはそのまま残ります。ただし、セレクタ部分に入れた場合は削除されます。

コメント(「/*!」から始めたコメントも)が削除されるので、次に挙げるハックは使用できません。

使用できないコメントを利用したハック

Scss
html[xmlns] > /**/body elements { property: value; }
html > /**/ body elements { property: value; }
/* \*//*/ selector { property: value; } /**/
/* \*/ selector { property: value; } /**/
など

コメントの削除には例外があります。プロパティの後ろにいれたコメントは削除されないので、次に挙げるハックは使用することができます。

使用できるコメントを利用したハック

Scss
selector {
    color/**/: red; // IE7,8,9と他のモダンブラウザ
    color/*\**/: green\9; // IE7,8,9
}
CSS
selector{color/**/:red;color/*\**/:green\9}

ほかのハックはどうでしょうか。気になりますね。。

IE6 スターハック

Scss
* html element { // IE6
    color: red;
}
CSS
* html element{color:red}

問題なし。

IE6 アンダースコアハック

Scss
selector {
    _color: red; // IE6
}
CSS
selector{_color:red}

問題なし。

IE7 スターハック

Scss
*:first-child + html element { // IE7
    color: red;
}
CSS
*:first-child + html element{color:red}

問題なし。

IE6,7 アスタリスクハック

Scss
selector {
    *color: red; // IE6,7
}
CSS
selector{*color:red}

問題なし。

IE6,7 スラッシュハック

Scss
selector {
    /color: red; // IE6,7
}

エラーになります。
変数を使いましょう。でも一番早いのは / の代わりに * を使うことです。

Scss
$slash: "/";

selector {
    #{$slash}color: red; // IE6,7
}
CSS
selector{/color:red}

これで問題なし。

IE \9ハック

Scss
selector {
    color: red\9; // IE6,7,8,9 (10も??)
}
CSS
selector{color:red\9}

問題なし。

IE \0/ハック

Scss
selector {
    font-family: Meiryo, sans-serif\0/; // IE6,7,8,9 (10も??)
}

エラーになります。
変数を使いましょう。

Scss
$hack-ie6to9: "\0/";

selector {
    font-family: Meiryo, sans-serif#{$hack-ie6to9}; // IE6,7,8,9 (10も??)
}
CSS
selector{font-family:Meiryo,sans-serif\0/}

これで問題なし。

セレクタハック 1

Scss
html > body element { // IE7と他のモダンブラウザ
    color: red;
}
CSS
html > body element{color:red}

問題なし。

セレクタハック 2

Scss
html + body element { // IE7と他のモダンブラウザ
    color: red;
}
CSS
html + body element{color:red}

問題なし。

Firefox moz-any-linkハック

Scss
element, x:-moz-any-link {
    color: red;
}
CSS
element,x:-moz-any-link{color:red}

問題なし。

WebKit mediaqueryハック

Scss
@media screen and (-webkit-min-device-pixel-ratio: 0) {
    selector {
      color: red;
    }
}
CSS
@media screen and (-webkit-min-device-pixel-ratio: 0){selector{color:red}}

問題なし。

@importを使ったハック

もう使うことはなさそうですが、これらのハックも使用できません。

@import'style.css'; → @import url(style.css); に整形される。
@import style.css;  → エラーになる。
など

結論

いくつかのハックが使用できなくなりますが、それ以外は特に問題なさそうです。

ただ、GitやSVNなどのバージョン管理ツールでのCSSの差分確認は難しくなると思いますのでご注意を。

font-familyの指定はウェイトなしのアルファベット表記のみでほぼよさそう

下記のコードはフォントの指定によく使われていると思います。

font-family: 'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック','MS PGothic',sans-serif;

同じフォントを日本語表記とアルファベット表記の両方で指定しているのは、各ブラウザの解釈や挙動が異なるなどの理由からです。ただ、最近のブラウザはどうなんだろうかとちょっと気になったので調べました。

結果としては下記の表になりました。詳細はデモページを見てください。

  • Parallels上のWin7: IE6-8(IE6,7はIETester), Chrome15, Firefox8, Safari5, Opera11
  • Mac OS X 10.6.8: Chrome15, Firefox8, Safari5, Opera11
  • 文字コード: UTF-8
指定方法 IE Chrome Safari Firefox Opera
Win WinMac WinMac WinMac WinMac
日本語表記 × × ×
日本語表記(ウェイトあり) - -× -× -△(*1) -×
アルファベット表記 △(*2)
アルファベット表記(ウェイトあり) - -× -× -△(*1) -
ポストスクリプト × ×× ×× ×× ××
ポストスクリプト(ウェイトあり) - - - -× -×
  • *1: ウェイトは無視され、ウェイトなしのものが適用される。
  • *2: ウェイトありで指定しないと適用されないものもある。

まとめ

ウェイトなしのアルファベット表記だけで多くのブラウザに対応できそうです。
問題が出るかもしれないのはMac Operaだけです。

記事の冒頭で挙げたコードは下記のようにすることができると思います。

font-family: 'Hiragino Kaku Gothic Pro',Meiryo,'MS PGothic',sans-serif;

Mac Operaですが、メイリオ、MS Pゴシックが入ってなければ、sans-serifが最後にあるのでヒラギノ角ゴ Pro W3が適用されます。もしくは、VerdanaやTahomaなどを指定すれば日本語部分はヒラギノになります...。

もしかすると今回の検証だけでは足りないかもしれませんが時間がないので今回はこのへんで。

iOS5なのにposition:fixed;が効かない時に確認すること

なんだかんだでFirefoxメインで制作しているわけですが、とあるページでposition:fixed;が効いてないみたいだよ?と@e_luckさんに教えてもらいまして、、、でちょっと調べてみて気づいたことです。

HTML5 Rocks - Improving the Performance of your HTML5 Appの「The magic CSS bullet」で紹介されていた下記のコードは、指定するとGPUアクセラレーションが有効になるのでパフォーマンス向上の恩恵を受けることができるかもしれない、といったような事が言われています(アニメーションの描画がスムーズになる?)。

GPUアクセラレーションを有効にするスタイル
-webkit-transform: translateZ(0);

ということで、これをbodyタグに指定してたんですが、、position:fixed;にならない原因はこのスタイルでした。これについてはW3CのWDに書いてありました。

The object acts as though position: relative has been specified, but also acts as a containing block for fixed positioned descendants.

CSS 3D Transforms Module Level 3

どおりでfixedを指定していた子孫要素が全部relativeの振る舞いになっちゃってたわけですね。

次のデモページでは親要素に-webkit-transform:translateZ(0);の指定がある場合とない場合の子要素の挙動を確認できます。WebKit系のブラウザでみてください。

デモページをみる

新しいプロパティを使うときは仕様書をちゃんと読んだほうが良さそうですね...。

Sass(Scss) Memo: @mixin

今回は@mixinについてです。
Mixinはスタイル(規則集合や宣言)を定義し、それを再利用することができます。
定義したMixinは@includeでインクルードして使用します。また、Mixinには引数を渡すことができます。

Mixinの利用例

clearfix用のMixinを例に説明します。

まずはMixinを定義します。

Scss
@mixin clearfix {
    *zoom: 1;
    //
    &:after {
        content: "";
        display: block;
        clear: both;
    }
}

これをインクルードして利用します。

Scss
.clearfix {
    @include clearfix;
}

これをコンパイルすると下記のようになります。

CSS
.clearfix {
  *zoom: 1;
}
.clearfix:after {
  content: "";
  display: block;
  clear: both;
}

簡単だし、コード管理も楽ですね。

ただ、別のセレクタにも同じコードを適用する場合、@extendを利用することも検討してください。

Scss
.clearfix {
    @include clearfix;
}
.header {
    @extend .clearfix;
}

これをコンパイルすると下記のようになります。

CSS
.clearfix, .header {
  *zoom: 1;
}
.clearfix:after, .header:after {
  content: "";
  display: block;
  clear: both;
}

セレクタをグループ化して出力されるので、セレクタごとにコードが展開される@mixinよりも全体のコード量を減らすことができます。

引数について

引数はMixinの中で変数として使うことができ、CSSのプロパティやプロパティの値、@ifの条件式などに利用することができます。

下記は引数を伴うMixinの例です。

Scss
@mixin sample-mixin($var1, $var2: margin, $var3: false) {
    width: $var1;
    #{$var2}: 0;
    @if $var3 {
        overflow: hidden;
    }
}
  • 引数を複数指定する場合は,(カンマ)で区切ります。
  • 初期値のない引数は初期値がある引数よりも必ず先に書かなければエラーになります($var1: false, $var2だとエラー)。
  • 初期値が指定されていない引数はインクルード時に値を指定しないとエラーになります。

インクルード時の引数の記述例

前述のsample-mixinを例にします。

Mixinの引数の順番通りに指定する

単純にMixinの引数の順番通りに値を指定します。
引数のキーワード($var1や$var2など)を記述する必要がないのでタイプ数が少なくてすみます。
ただ、コードを後で見返したときにMixinによっては引数の値が何なのかが分かりづらいかもしれません。

Scss
.selector {
    @include sample-mixin(100px, padding, true);
}

特定の引数だけ指定する

$var2は初期値を利用して、$var3の値だけ指定します。

Scss
.selector {
    @include sample-mixin(100px, $var3: true);
}

キーワードを使い、順不同で指定する

$var3を記述した後に$var2を記述します。
引数のキーワードを記述すると引数の順番が関係なくなるようです。ただ、コードの見通しが悪くなりそうなので使わないほうが良さそうですが...。

Scss
.selector {
    @include sample-mixin(100px, $var3: true, $var2: padding);

    // 下記のように$var1を最後に記述してもエラーにはなりません。
    @include sample-mixin($var3: true, $var2: padding, $var1: 100px);
}

Mixinを使えば作業をかなり効率化することができますが、複雑すぎると運用・管理のコストを増やしてしまう可能性があるのでバランスを考慮して利用したいですね。

Sass(Scss) Memo: @extend

今回は@extendについてです。
別のセレクタの全てのスタイルを継承することができます。

Scss
.borderRed {
    border: 1px solid red;
}
.selectorA {
    @extend .borderRed; // ここで.borderRedを継承指定
    padding: 2px;
}
出力結果のCSS
.borderRed, .selectorA { /* ここに .selectorA が追加されます */
  border: 1px solid red;
}

.selectorA {
  padding: 2px;
}

@extendに使用できるセレクタ

1つの要素のみに関連するセレクタであればほとんど使用できます。 要素セレクタやid/classセレクタや擬似クラス、属性セレクタなども使用できますし、各セレクタを連結させたもの(div#selectorA.selectorBdiv.selectorA:first-childなど)も使用できます。

ただ、いまのところ(Sassバージョン3.1.1)は子孫/子/兄弟セレクタ(E FE > FE ~ F)と隣接セレクタ(E + F)は使用できません。
全称セレクタ(*)も使用できますが、使う場面はなさそうですね。

あと、@extend .selectorA, .selectorB;みたいに複数一括指定することはできないので分けて書きましょう。

Scss
.selectorA {
    @extend div;
    @extend #id;
    @extend .class;
    @extend div.class; // 要素も指定しているので、p.classがあっても継承しません
    @extend #id.class;
    @extend .class-1.class-2;
    @extend .selector:hover;
    @extend .selector[attr];
    @extend *; // これは使うことなさそうだけど...

    // ここから下はエラーになります
    @extend div .class; // E F
    @extend div > .class; // E > F
    @extend div + .class; // E + F
    @extend div ~ .class; // E ~ F
}

@extendをうまく使えば、セレクタのグループ化によってCSSのファイルサイズを減量したり、スプライト用の画像の読み込み指定をまとめてhttpリクエストを減らすこともできるのでとても便利です。

が、、気をつけなければいけないことがあります。

気をつけること 1

継承するのは@extendで指定したセレクタ自身のスタイルだけではなく、その子要素などのスタイルも継承するということです。

Scss
.selectorA {
    padding: 20px;
    border: 1px solid #333;
    //
    h2 {
        font-weight: bold;
        font-size: 20px;
    }
    p {
        color: #666;
    }
}
body.firefox .selectorA {
    padding: 10px;
}
.selectorB {
    @extend .selectorA; // ここで.selectorAを継承指定
    background: #eee;
    //
    h2 {
        font-size: 14px;
    }
}
CSS
.selectorA, .selectorB {
  padding: 20px;
  border: 1px solid #333;
}
.selectorA h2, .selectorB h2 { /* ここにも追加されました */
  font-size: 20px;
}
.selectorA p, .selectorB p { /* ここにも追加されました */
  color: #666;
}

body.firefox .selectorA, body.firefox .selectorB { /* ここにも追加されました */
  color: #666;
}

.selectorB {
  background: #eee;
}

.selectorB h2 {
  font-size: 14px;
}

こういう問題があるかもしれません。

  • .selectorA h2は太字にしたいけど、.selectorB h2はスタイルリセット時にfont-weight: normal;にしてるからそのままでよかったのに...。
  • .selectorB pのテキストカラーはbodyで適用されてる色でよかったのに...。
  • body.firefox .selectorBはスタイル変える必要がないのに...。
  • 後日、.selectorA h2のテキストカラーを変更することになったのでスタイル追加したら、当然 .selectorB h2にも適用された...。
    複数人で制作していると、別のメンバーがつくったセレクタを継承してたらいつの間にか結構変わってたとかセレクタ自体が削除されてた(エラー出ないので気づかない)なんてこともあるかも。

気をつけること 2

@extendで指定したセレクタを含むセレクタも継承することです。

たとえば下記のような場合、要素指定なしの.selectorAのスタイルだけを継承したいとします。

Scss
.selectorA {
    text-decoration: none;
}
a.selectorA {
    text-decoration: underline;
}
.selectorB {
    @extend .selectorA; // ここで.selectorAを継承指定
}

ところが、期待通りの出力結果になりませんでした。

CSS
.selectorA, .selectorB {
  text-decoration: none;
}

a.selectorA, a.selectorB { /* こちらにも追加されている */
  text-decoration: underline;
}

さらに属性セレクタに関してはバグ(?)があるようです。

.selectorBで属性セレクタを含んでいる.selectorA@extendします。

Scss
a.selectorA {
    text-decoration: none;
    //
    &[href] {
        text-decoration: underline;
    }
}
.selectorB {
    @extend .selectorA;
}

期待する出力結果は下記になります。

CSS
a.selectorA, a.selectorB {
  text-decoration: none;
}

a.selectorA[href], a.selectorB[href] {
  text-decoration: underline;
}

実際の出力結果では、意図しないセレクタが出力されます。

CSS
a.selectorA, a.selectorB {
  text-decoration: none;
}

a.selectorA[href], a[href].selectorB { /* これはどういうことですか... */
  text-decoration: underline;
}

複雑なセレクタに使うとややこしいですね。。
@extendを使用するルールは決めておいたほうが良いと思います。

@extendの使用ルール案
  • @extendで使用するセレクタはスタイルや要素が、ある程度固定されたものにする。
    おなじみのclearfixやスプライト用の指定とか。
  • @extend専用のセレクタ(.extend-fooとか)を用意して利用する。
    このセレクタに対するあらゆる変更は、それを利用している他のセレクタにも影響することが分かるので、変更は注意しておこなうだろうし、変更前に影響範囲を確認するというフローをつくることもできると思います。

Sass(Scss) Memo: @if

今回は@ifについてです。

@if@else if@elseが使えます。
こんな感じ。

Scss
$var1: aaa;

@if $var1 == 'bbb' {
    /* A:$var1 が bbb の場合に出力される */
} @else if $var1 == 'ccc' {
    /* B:最初の条件を満たさず、$var1 が ccc の場合に出力される */
} @else if $var1 == 'aaa' {
    /* C:2つの条件を満たさず、$var1 が aaa の場合に出力される */
} @else {
    /* D:それ以外の場合に出力される */
}
出力結果のCSS
/* C:2つの条件を満たさず、$var1 が aaa の場合に出力される */

条件の判別には==だけでなく他の比較演算子(<, <=, >, >=, !=)も使えます。

Scss
$var1: aaa;
$var2: 5;
$var3: true;

@if $var2 != 1 {
    /* A:$var2 が 1 以外の場合に出力される */
}

@if $var2 > 10 {
    /* B:$var2 が 10よりも多い場合に出力される */
} @else if $var2 < 10 {
    /* C:$var2 が 10よりも少ない場合に出力される */
} @else if $var2 >= 10 {
    /* D:$var2 が 10以上の場合に出力される */
} @else if $var2 <= 10 {
    /* E:$var2 が 10以下の場合に出力される */
}

@if $var3 {
    /* F:$var3 が trueか何か値が入ってれば出力される */
}
出力結果のCSS
/* A:$var2 が 1 以外の場合に出力される */
/* C:$var2 が 10よりも少ない場合に出力される */
/* F:$var3 が trueか何か値が入ってれば出力される */

論理演算子の&&||!は使えませんでしたが、andornotを使うことができました。

Scss
$var1: aaa;
$var2: 5;
$var3: true;
$var4: false;

@if $var1 and $var3 {
    /* $var1 と $var4 がどちらも true であれば出力される */
}

@if $var1 or $var4 {
    /* $var1 か $var4 のいずれかが true であれば出力される */
}

@if not $var4 {
    /* $var4 が true でなければ出力される */
}

@if ((not $var1) or $var3) and $var2 {
    /* 組み合わせてみたり... */
}
出力結果のCSS
/* $var1 と $var3 がどちらも true であれば出力される */
/* $var1 か $var4 のいずれかが true であれば出力される */
/* $var4 が true でなければ出力される */
/* 組み合わせてみたり... */

と、色々できますが後で読みづらくならないように気をつけたいですね、複数人で作業する場合は特に。

Sass(Scss) Memo: 変数

今回は変数についてです。
$ から始めて、値はCSSと同じようにして設定します。
こんな感じ。

Scss
$margin: 2em 0;  // $margin に "2em 0" をいれて定義する。
h1 {
    margin: $margin;
}
CSS
h1 {
  margin: 2em 0;
}

変数はそれが記述された{}内でのみ有効になります。
どのCSSルールセットやmixinにも含まれない場合、どこでも使えるグローバルな変数になります。
こんな感じ。

Scss
h1 {
    $margin: 2em 0;  // ここで$marginを定義する。
    margin: $margin;
}
p {
    margin: $margin; // ここでは使えない!コンパイル時にエラーになります。
}

インターポレーション

変数はプロパティの値だけでなく、セレクター名やプロパティ名にも使うことができます。
その場合、#{}を使うインターポレーションと呼ばれる書き方をします。
こんな感じ。

Scss
$class: title;
$property: top;
h1.#{$class} {
    margin-#{$property}: 2em 0;
}
CSS
h1.title {
  margin-top: 2em 0;
}

インターポレーションを使った場合、変数内の引用符は自動的に削除されます。
mixinの引数をセレクターに利用するなんて時にやりやすくするためらしいです。
.(ドット)から始まる文字列はmixinの引数にはできないので引用符で囲んであげる必要があるわけです。
こんな感じ。

Scss
@mixin color-red($selector) {
    #{$selector} {
        color: red;
    }
}
@include color-red(".title");  // 引用符で囲む。
CSS
.title {  /* 引用符が削除されました。 */
  color: red;
}

インターポレーションを使うとその近くの算術演算(+, -, *, /など)は通常のテキストとして扱われます。
こんな感じ。

Scss
$font-size: 24px;
$line-height: 1.2;
h1 {
    font: $font-size/$line-height;  // ふつうに記述。
    font: #{$font-size}/#{$line-height};  // インターポレーションをつかう。
}

$img-path: "/shared/img";
.header {
    background-image: url(#{$img-path}/bg_header.png);  // 画像のパスに使うときにも。
}

$var1: foo;
$var2: bar;
.test {
    content: $var1 + $var2;
    content: #{$var1} + #{$var2};

    content: $var1 - $var2;
    content: #{$var1} - #{$var2};
}
CSS
h1 {
  font: 20px;  /* 計算されてしまいました。 */
  font: 24px/1.2;
}

.header {
  background-image: url(/shared/img/bg_header.png);
}

.test {
  content: foobar;     /* +とスペースがなくなり連結された。 */
  content: foo + bar;  /* +とスペースはそのまま。 */
  content: foo-bar;    /* -はそのままで、スペースがなくなった。 */
  content: foo - bar;  /* -とスペースはそのまま。 */
}

計算や結合させたければ普通に記述して、そうでない場合はインターポレーションで記述すれば大丈夫ですね。

変数のデフォルト値

変数には !default で初期値を設定することができます。
変数にすでに値が代入されている場合、その値を上書きしません。値がすでに代入されていない場合は通常通り指定された値を代入します。
こんな感じ。

Scss
$var1: foo;
$var1: bar !default;
.test {
    content: $var1;  // 通常なら後で代入した bar が出力されるが、、
}

$var2: bar !default;
.test {
    content: $var2;  // 先に値が代入されていなければ、、
}
CSS
.test {
  content: foo;  /* foo が出力されました。 */
}

.test {
  content: bar;  /* bar が出力されました。 */
}

!default はCSSでいう !important の逆みたいなもんですかね。

Sass(Scss) Memo: 親セレクタの参照

Sass(Scss)について覚えたことを少しずつ書いていきたいと思います。

今回は親セレクタの参照についてです。
Sassでは & を使って親セレクタを参照することができます

Scss
div {
    a {
        text-decoration: none;

        &:hover {
            text-decoration: underline;
        }
    }
}

こうするとCSSは下記のように出力されます。

CSS
div a {
  text-decoration: none;
}
div a:hover {
  text-decoration: underline;
}

&div a に置換されています。
親セレクタを繰り返し記述しなくても良いので便利です。

ただ、隣接セレクタを使うときにはちょっと不便です。
例えば、下記のようなCSSをScss記法に書き換える場合。

CSS
div h1 {
  font-size: 20px;
}
div ul {
  margin: 2em 0;
}
div h1 + ul {
  margin-top: 1em;
}

Scssで下記のように記述した時、h1 + &div h1 + ul となって欲しいところです。

Scss
div {
    h1 {
        font-size: 20px;
    }
    ul {
        margin: 2em 0;

        h1 + & {
            margin-top: 1em; // override
        }
    }
}

ですが、& は親セレクタの div ul に置換されますので、実際には h1 + div ul と出力されてしまいます。

CSS
div h1 {
  font-size: 20px;
}
div ul {
  margin: 2em 0;
}
h1 + div ul {
  margin-top: 1em;
}

& を使いたい場合は、下記のように記述するとうまくいきます。

Scss
div {
    h1 {
        font-size: 20px;

        & + ul {
            margin-top: 1em; // override
        }
    }
    ul {
        margin: 2em 0;
    }
}
CSS
div h1 {
  font-size: 20px;
}
div h1 + ul {
  margin-top: 1em;
}
div ul {
  margin: 2em 0;
}

ただ、スタイルの上書きは後に書くことが多いので少し違和感があるかもしれません。
その場合、若干冗長ですが下記のように記述するといいと思います。

Scss
div {
    h1 {
        font-size: 20px;
    }
    ul {
        margin: 2em 0;
    }
    h1 + ul {
        margin-top: 1em; // override
    }
}
CSS
div h1 {
  font-size: 20px;
}
div ul {
  margin: 2em 0;
}
div h1 + ul {
  margin-top: 1em;
}

どちらかお好きなほうでどうぞ。

IEのz-indexのバグを思い出す

つい最近、IE6ってz-indexのバグがあったよな...って思ったけど、ぼんやりとしか思い出せなかったので今さらですが検証してみました。。

結論としてはIE6だけじゃなくてIE7にも同じバグがありました。
2つのdivの親要素が別々でz-indexは指定しない場合、IE6とIE7以外のブラウザは子要素のz-indexの値が優先されるが、IE6とIE7は親要素の出現順が影響します。後から出現した親と子要素が手前になります。

デモページをみる

Google ChromeやFirefoxなどの場合

IE6とIE7の場合

QuickSilverのトリガー機能でアプリを素早く切り替える

タイトル通りQuicksilverのトリガー機能を使えばよく使うアプリに素早く切り替えられます、ってだけです。が、地味だけどほんとに便利です。

メインのエディタはMacVimなので押しやすいCmd+;で、Chromeはひとつ隣のCmd+:、FirefoxはCmd+.(ドット)といった感じで適当に割り当てています。

QuickSilverのTriggers設定画面

VimでCSSルールセットを選択する

Vimではvatと入力するだけでカーソル位置から直近のHTMLの要素を選択できるのですが、CSSのルールセットを選択するものがありません。viBvi{とすれば、{}内のテキストは選択できますが、カーソルが{}内にないと機能しません。なのでVim scriptをパクリながらはじめて書いてみました。

git submoduleでインストールすることができます。下記はpathogen.vimを使っている場合です。

git submodule add git@github.com:kosei27/vim-selectCssRuleSet.git ~/path/to/bundle/vim-selectcssruleset
" Select CSS Rule Set
" カーソルから一番近いCSSルールセットを選択する
"
" nnoremap <silent> var  :<C-u>call SelectCssRuleSet()<CR>
" vimrcに↑を追加して、varと入力します。
function! SelectCssRuleSet()
    let save_reg = @@

    silent normal $va{Voy
    let first_yank = @@

    " 最初にヤンクした内容に'{'が含まれるかどうかチェック
    let chk_first_yank = matchstr(first_yank, '{')
    if chk_first_yank == ''
        " 最初にヤンクした内容に'{'が含まれない場合は次の行をチェックする
        let chk_next_line = matchstr(getline(line(".")+1), '{')
        while chk_next_line == '' " 次の行に'{'がない場合は見つかるまで繰り返す
            silent normal j
            " ファイルの最終行に来たらループ抜けてエラーメッセージを表示する
            if line(".")==line("$")
                execute "normal \<Esc>"
                echohl ErrorMsg
                echo 'no match css rule sets.'
                echohl None
                return
                break
            endif
            let chk_next_line = matchstr(getline(line(".")+1), '{')
        endwhile
        silent normal j
    endif

    execute "normal \<Esc>"
    silent normal $va{Vo
    let chk_prev_line = matchstr(getline(line(".")-1), ',')
    while chk_prev_line != '' " 上の行に','があればセレクタグループとして選択する
        silent normal k
        let chk_prev_line = matchstr(getline(line(".")-1), ',')
    endwhile

    let @@ = save_reg
endfunction

vimrcに下記を追加して、varと入力するとカーソルから直近のルールセットが選択されると思います(<plug>とか使うんですよね?ほんとは...)。

nnoremap <silent> var  :<C-u>call SelectCssRuleSet()<CR>

Cmd+wしようとしてCmd+qでブラウザを閉じてしまうのを防ぐ方法

Cmd+qではなくCmd+Ctrl+qで閉じるようにします。

システム環境設定からキーボード設定画面を開きます。キーボードショートカットの画面で、「アプリケーション」を選択し、「+」ボタンを押してキーを追加します。

キーボード設定画面のスクリーンショット

ダイアログが表示されるので、それぞれの項目を設定します。

  • アプリケーションは今回はGoogle Chromeにします。
  • メニューのタイトルにはメニューの文字列を正確に入力します。なので、「Google Chrome を終了」となります。
  • キーボードショートカットはCmd+Ctrl+qにします。

各項目の設定のあと「追加」ボタンを押すと、ショートカットが追加されます。

メニューの項目を見るとショートカットのところが変更されてますね。

FirefoxやVim、Photoshopなども設定しておくといいかもしれません。

WebKitの画像置換のバグの解決方法

バグの内容

下記のように画像置換した場合、WebKitではspan要素のテキスト分の幅が保持されてa要素の幅が広がってしまいます。

HTML
<p><a href="#" class="ir"><span>画像置換テキスト</span></a>左のボタンは画像置換をおこなっています。</p>
<p style="padding-left:102px;">画像置換テキスト</p>
CSS
.ir {
    display: inline-block;
    *display: inline;
    *zoom: 1;
}
.ir span {
    display: inline-block;
    *display: inline;
    *zoom: 1;
    width: 0;
    height: 32px; /* ボタン画像の高さ */
    overflow: hidden;
    padding: 0 0 0 102px; /* ボタン画像の幅 */
    background: url(..) no-repeat 0 0;
}

デモページをみる

Google Chromeでのスクリーンショット

解決方法

これを解決するには、画像置換をしているspan要素にmax-width: 0;を指定します。

CSS
.ir span {
    display: inline-block;
    *display: inline;
    *zoom: 1;
    width: 0;
    max-width: 0; /* for WebKit bug */
    height: 32px;
    overflow: hidden;
    padding: 0 0 0 102px;
    background: url(..) no-repeat 0 0;
}

デモページをみる

Google Chromeでのスクリーンショット

まさかmax-width0にすることになるなんて...。

おまけ

Vimのプラグインneocomplcache.vimのスニペット。css.snipにコピペして、irと入力して展開です。
snippet	imagereplacement
alias	ir
    display: inline-block;
    ${1:*}display: inline;
    $1zoom: 1;
    width: 0;
    max-width: 0; /* for WebKit bug */
    height: ${2}px;
    overflow: hidden;
    padding: 0 0 0 ${3:$2}px;
    background: url(${4}) no-repeat ${5:0 0};

MacBook AirのPowerボタンを何かに変えたい

が、いまんとこできなそう...。

会社ではiMacの標準キーボードを使ってて、deleteキーの上にあるEjectキーをもったいないのでKeyRemap4MacBookでForward Deleteキー(WindowsでいうDeleteキー)にしてる。

でもMacBook AirはそこにEjectキーじゃなくてPowerボタンがあるので、押し間違えたりしそうだし、不便なので変えたいなーと思ってKeyRemap4MacBookの設定を見てみた。

KeyRemap4MacBookの設定画面。検索窓に「Power」と入力して絞り込んだ状態。

Power to Forward Delete (+ Fn+Power to Power)にチェックを入れてできたできたー、と思ったけど効かない...。なんでだろと思ってよく見ると注意書きが。

This setting does not work with MacBook Air 2010.
This "Power Key" is the key in the old ADB keyboard.

これ、Air用じゃなかったよ...。

figure要素のマークアップについてのメモ

figure要素。

普通に書くとこんな感じ。

<figure>
  <figcaption>画像の説明テキスト</figcaption>
  <img src=".." alt=".."><img src=".." alt=".."><img src=".." alt="..">
</figure>

<figure>
  <img src=".." alt=".."><img src=".." alt=".."><img src=".." alt="..">
  <figcaption>画像の説明テキスト</figcaption>
</figure>
figure {
    margin: 1em 0;
}
figcaption {
    display: block;
    clear: both;
    font-weight: bold;
}
/* figcaptionが最初の場合 */
figcaption:first-child {
    margin-bottom: 0.5em;
}
/* figcaptionが最後の場合
 * img以外にもいろいろあるので全称セレクタ。
 * IE7を無視するなら figcaption:last-child {..}
 */
figure * + figcaption {
    margin-top: 0.5em;
}
/* --- img --- */
figure img {
    display: inline-block;
    *display: inline;
    *zoom: 1;
    margin-left 5px;
    vertical-align: top;
}
/* 一番左の画像 */
figure > img:first-child, /* figure内で最初の要素がimgの場合 */
figcaption + img /* figcaptionの次にくるのがimgの場合 */ {
    margin-left: 0;
    border: 1px solid #f00; /* 分かりやすいように赤枠をつける */
}
/* --- pre --- */
    :
/* --- object --- */
    :
/* --- video --- */
    :
/* --- canvas --- */
    :
/* --- svg --- */
    :

デモページをみる

スクリーンショット

問題点

うまくいってるように見えるけど、このままだとimg要素などがほかの要素でラップされているとダメだし、figcaption要素内にimg要素などがあった場合のスタイルをいちいち上書きする必要がある(めんどい)。

<figure>
  <figcaption>画像の説明テキスト<img src=".." alt=".."></figcaption>
  <a href="#"><img src=".." alt=".."></a>
  <a href="#"><img src=".." alt=".."></a>
  <a href="#"><img src=".." alt=".."></a>
</figure>

<figure>
  <a href="#"><img src=".." alt=".."></a>
  <a href="#"><img src=".." alt=".."></a>
  <a href="#"><img src=".." alt=".."></a>
  <figcaption>画像の説明テキスト<img src=".." alt=".."></figcaption>
</figure>
/* 一番左の画像 */
figure > img:first-child,
figure > *:first-child img, /* 追加。figure内で最初の要素の中のimg */
figcaption + img,
figcaption + * img /* 追加。figcaptionの次にくる要素の中のimg */ {
    margin-left: 0;
}
/* figcaption内の画像
 * セレクタを長くするか、!importantをつけないと詳細度で負ける。
 */
figcaption img {
    margin-left: 0 !important; /* override */
    border: 0 !important; /* override */
    vertical-align: middle; /* override */
}

デモページをみる

スクリーンショット

解決策

場合によってはキャプションとコンテンツを分けたほうがいいと思った。
ので、div.fig-contentを追加してみる。

<figure>
  <figcaption>画像の説明テキスト</figcaption>
  <div class="fig-content">
    <img src=".." alt=".."><img src=".." alt=".."><img src=".." alt="..">
  </div>
</figure>

<figure>
  <div class="fig-content">
    <img src=".." alt=".."><img src=".." alt=".."><img src=".." alt="..">
  </div>
  <figcaption>画像の説明テキスト</figcaption>
</figure>
figure {
    margin: 1em 0;
}
figcaption {
    display: block;
    clear: both;
    font-weight: bold;
}
/* figcaptionが最初の場合 */
figcaption:first-child {
    margin-bottom: 0.5em;
}
/* figcaptionが最後の場合
 * 全称セレクタやlast-childを使わなくてもOK。
 */
.fig-content + figcaption {
    margin-top: 0.5em;
}
/* --- img --- */
.fig-content img { /* figcaption内のimgには影響がない */
    display: inline-block;
    *display: inline;
    *zoom: 1;
    margin-left: 5px;
    vertical-align: top;
}
/* 一番左の画像 */
.fig-content > img:first-child, /* .fig-content内の最初の要素がimg */
.fig-content > :first-child img /* .fig-content内で最初の要素の中のimg */ {
    margin-left: 0;
	border: 1px solid #f00;
}
/* --- pre --- */
    :

デモページをみる

スクリーンショット

結論

figure要素内に何が入るのか、figcaption要素の位置や内容などが決まっている場合はdiv.fig-contentはなくてもいい。けど、入れておいた方が便利なことが多そうだと思った。

MacBook Airのシステム環境設定のメモ

Time Machineとかないのでメモ。

Spotlightに「System Preferences」と入力してシステム環境設定を開いてから項目を選択してもいいし、括弧内のテキストを入力して直接開いてもいい。

ソフトウェア・アップデート

ソフトウェア・アップデート 環境設定画面

  • とりあえず「今すぐ確認」を押して最新にする。

Dock

Dock上のよけいなアプリを取り除く。
アプリの起動/切替やフォルダへのアクセスはQuicksilverでするので、
Finder、Chrome、アプリケーションフォルダとごみ箱だけに。

Dock 環境設定画面

  • Dock上のアイコンがわーって増えないように「ウインドウをアプリケーションアイコンにしまう」はオンにする。
  • 「ジニーエフェクト」より速い気がするので「スケールエフェクト」に設定。
  • 「起動中のアプリケーションをアニメーションで表示」をオフにして、起動中はアイコンが跳ねないように。

ExposeとSpaces

  • ExposeやDashboardはほとんど使わないので、起動に割り当てられているショートカットキーを全てオフにする(ExposeはあとでKeyRemap4MacBookでcapsキーに割り当てる)。
  • Spacesは使わないので「Spaces を有効にする」をオフにする。

Spotlight

Quicksilverを使うのでSpotlightもほとんど使わない。

  • 「Spotlight メニューのキーボードショートカット」を「Cmd+Shift+Opt+Space」に変更する(実際にはKeyRemap4MacBookでTabキー+Spaceにする)。
  • 「Spotlight ウインドウのキーボードショートカット」を「Ctrl+Opt+Space」に変更する。
  • 使わないカテゴリをオフにすると検索結果が早くなっていいと思います。

アピアランス

  • 「ウインドウのタイトルバーをダブルクリックしてウインドウをしまう」をオンにする。
  • 「最近使った項目の数」の「アプリケーション」と「書類」は「なし」にしたけど、Windowsと違ってこんなことしなくてもいいのかな。

セキュリティ

  • 「一般」タブの「スリープの後、またはスクリーンセーバが開始した後、1分後にパスワードを要求」をオンにする。

デスクトップとスクリーンセーバ

  • 壁紙を変更。無地の色、Solid Gray Lightにした。
  • 壁紙を無地にしたので、「半透明メニューバー」をオフにする。

言語とテキスト

  • 半角カタカナを入力したい場合は、「入力ソース」タブで「半角カタカナ」をオンにする。

キーボード

キーボード

  • 「キーのリピート速度」を最大に早くする(満足いかない場合はKeyRemap4MacBookで調整します)。
  • タブで「F1、F2などのすべてのキーを標準のファンクションキーとして使用」をオンにする。

キーボードショートカット

  • 「フルキーボードアクセス」を「すべてのコントロール」をオンにする。
  • 「キーボードと文字入力」で「前の入力ソースを選択(Cmd+Space)」と「入力メニューの次のソースを選択(Cmd+Alt+Space)」をオフにする(Cmd+SpaceはQuicksilverを表示するトリガーにするため)。

トラックパッド

トラックパッド 環境設定画面

  • 「ドラッグ」、「ドラッグの維持」をオンにする。
  • 「副ボタンのクリック」をオン、「右下隅」にする。

このほかはBetterTouchToolで設定する。

サウンド

  • 「メニューバーに音量を表示」をオフにする。
  • 起動時の音はStartupSound.prefPaneで消音にする。

省エネルギー

  • 「メニューバーにバッテリーの状況を表示」をオンにする。

Bluetooth

Bluetoothは普段使わないのでオフにする。

  • 「入」をオフにする。
  • 「Bluetoothの状況をメニューバーに表示」をオフにする。

共有

ローカルでサイトの確認をしたりするので「Web共有」をオンに。

Time Machine

Time Machineは持ってないのでオフに。

  • 「切」に設定する。
  • 「Time Machineの状況をメニューバーに表示」をオフにする。

アカウント

  • 「ログイン項目」タブでログイン時に自動的に開く項目を設定する。新規に追加したり不要なものを削除したり、起動と同時に隠したり。

ユニバーサルアクセス

  • 「補助装置にアクセスできるようにする」をオンにする(BetterTouchToolなどで必要なため)。

日付と時刻

  • 「時計」タブで「24時間表示にする」と「曜日を表示」をオンにする。

時計 環境設定後のメニューバー