@media と @extend

Sass で @extend を CSS の @media と絡めて使おうとすると、組み合わせによってはエラーや警告が出てしまうので注意が必要。

%foo {
    color: red;
}

.bar {
    @media screen and (min-width: 768px) {
        @extend %foo; // ERROR!
        margin: auto;
    }
}

スクリーンの幅が 768px 以上のときは .bar%foo を継承させる、という意図だけど、これは “Extend directives may only be used within rules.” というエラーが出て通らず、ファイルのコンパイルが丸ごと失敗してしまう。

%foo {
    color: red;
}

@media screen and (min-width: 768px) {
    .bar {
        @extend %foo; // WARNING
        margin: auto;
    }
}

こうやって @media を外側に持ってくるとエラーにはならないけど、警告が出て @extend が評価されない (そのほかの宣言は大丈夫)。メッセージは “@extending an outer selector from within @media is deprecated. You may only @extend selectors within the same directive. This will be an error in Sass 3.3. It can only work once @extend is supported natively in the browser.” と言っていて、いまは警告で済むけど次はない、ってことらしい。

@media の内側から外のセレクタを @extend することはできないようなので、必要であれば @extend される側のセレクタの中に @media を宣言することになる。

%foo {
    @media screen and (min-width: 768px) {
        color: red;
    }
}

.bar {
    @extend %foo; // Works!
}

ただ、このやり方だと スタイルを細切れにして @extend しまくる 設計の場合に継承元セレクタごとにいちいちクエリを書く必要があり、出力結果も @media まみれのちょっと悲惨なものになる。@media と絡むところでは無理に @extend しようとせず、素の CSS に近い感じで書くのがいいのかもしれない。とくに最近はメデイアクエリでスタイルを細かく分岐させることも多いと思うので気をつけたい。ていうか気をつけます。