NIR ミックスイン

NIR (Nash Image Replacement) をわりとよく使うようになったので、最近は Sass のミックスインにしています:

@mixin nir ($src, $w: auto, $h: auto, $x: 0, $y: 0) {
    overflow: hidden;
    @if ($w != auto) {
        width: $w;
        height: $h;
    }
    *text-indent: -9999px;
    *background-image: url($src);
    *background-repeat: no-repeat;
    @if ($x != 0) {
        *background-position: $x $y;
    }
    &:before {
        content: url($src);
        display: inline-block;
        font-size: 0;
        line-height: 0;
        @if ($x != 0) {
            margin-left: $x;
            margin-top: $y;
        }
    }
}

@mixin nir-position ($x, $y) {
    &:before {
        margin-left: $x;
        margin-top: $y;
    }
    *background-position: $x $y;
}

もっともシンプルな使い方はスプライトではなく単独の画像を使う場合で、画像のパスと幅と高さを nir() に渡すだけ。

.logo {
    @include nir("/img/logo.png", 128px, 36px);
}

結果こうなります:

.logo {
     overflow: hidden;
     width: 128px;
     height: 36px;
     *text-indent: -9999px;
     *background-image: url("/img/logo.png");
     *background-repeat: no-repeat;
}

.logo:before {
    content: url("/img/sprite.png");
    display: inline-block;
    font-size: 0;
    line-height: 0;
}

スプライト画像の場合は座標の指定も必要です。たとえばソーシャル系のリンクをロールオーバーつきのアイコンで表現するにはこんな感じ:

.social-links {
    a {
        display: inline-block;
        @include nir("/img/sprite.png", 32px, 32px);
        &[href^="https://twitter.com/"] {
            @include nir-position(-180px, -190px);
            &:hover {
                @include nir-position(-180px, -230px);
            }
        }
        &[href^="http://www.facebook.com/"] {
            @include nir-position(-220px, -190px);
            &:hover {
                @include nir-position(-220px, -230px);
            }
        }
    }
}

まず a 要素に対して nir() でスプライト画像のパスとアイコンのサイズを指定して、次いでリンク先や状態ごとに各アイコンの座標を nir-position() で個別に指定しています。

.social-links a {
    display: inline-block;
    overflow: hidden;
    width: 32px;
    height: 32px;
    *text-indent: -9999px;
    *background-image: url("/img/sprite.png");
    *background-repeat: no-repeat;
}

.social-links a[href^="https://twitter.com/"] {
    *background-position: -180px -190px;
}
.social-links a[href^="https://twitter.com/"]:before {
    margin-left: -180px; margin-top: -190px;
}
.social-links a[href^="https://twitter.com/"]:hover {
    *background-position: -180px -230px;
}
.social-links a[href^="https://twitter.com/"]:hover:before {
    margin-left: -180px; margin-top: -230px;
}

.social-links a[href^="http://www.facebook.com/"] {
    *background-position: -220px -190px;
}
.social-links a[href^="http://www.facebook.com/"]:before {
    margin-left: -220px; margin-top: -190px;
}
.social-links a[href^="http://www.facebook.com/"]:hover {
    *background-position: -220px -230px;
}
.social-links a[href^="http://www.facebook.com/"]:hover:before {
    margin-left: -220px; margin-top: -230px;
}

擬似要素なので Firefox 以外でアニメーションできないとかそもそもコンパイル結果のコードがうざいとかいろいろありますが、ちょっとしたアイコンやなんかにはやっぱり便利なのでけっこう重宝します。