Sass3.3の@at-rootで親のルールを指定する

2014-02-16

先日登壇したCSS Nite LP, Disk 32のセッションで紹介されていたSassのMixinをSass3.3の@at-rootで少し手を加えてみる、という話。

紹介されていたのは、天地左右中央に絶対配置するテクニックのMixin。

@mixin trbl($width: null, $height: null) {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	width: $width;
	height: $height;
	margin: auto;
}

.tbrl {
  @include trbl(100px,50px);
}
.tbrl {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100px;
  height: 50px;
  margin: auto;
}

この仕組については先の記事をみてもらうとして、このMixinの内容は、これらのコードを提供し、任意でwidthheightの値を渡せるようになっている。

このテクニックを使う条件として必要になるのは、position:absoluteの基点、つまりposition:relativeが必要となる。
(無論、bodyを基点とするならその限りではないが)

それを解決というか、それなりに利便性を考えるとすれば次のような方法が浮かぶ。

.ref {
  position: relative
}

.tbrl {
  ...
}
<div class="ref">
  <div class="tbrl">foo</div>
</div>

例えば.refのようなposition:relativeの汎用クラスを容易し、この.tbrlを使うときに基点を指定する場合には、.refを使いましょう、とするような方法。

次に本題であるSass3.3の@at-rootを使う方法。

// ----
// Sass (v3.3.0.rc.3)
// Compass (v1.0.0.alpha.18)
// ----
 
@mixin trbl($width: null, $height: null, $parent: null) {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: $width;
  height: $height;
  margin: auto;
  @at-root #{$parent} {
    position: relative;
  }
}
 
.tbrl {
  @include trbl(100px, 50px, ".tbrl-wrapper");
}
.tbrl {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100px;
  height: 50px;
  margin: auto;
}
.tbrl-wrapper {
  position: relative;
}
<div class="tbrl-wrapper">
  <div class="tbrl">foo</div>
</div>

@mixin trbl()に加えたのは@at-rootの記述と、基点となる親のセレクタをつくるための引数。@at-rootディレクティブは記述上ネストされているが、コンパイルされたときにそれはネストされずに出力される。それを利用して、このような書き方ができる。

この例だと結局position:relativeを持たせているだけなので、先に紹介した.refみたいな汎用クラスを使うのと対して変わらないといえば変わらないが、tbrlというコンポーネントとしてルールをまとめるという設計で考えると、後者のような形の方が良いのではと考えた。
(実際便利なのかどうか置いといて)

@at-rootはよくBEMなルールを書くときに役立ちそうだと紹介されているのをよく見るが、こんな使い方もできるな、という話でした。

あと気軽にSass3.3を試すならSassMeisterが便利。

Hiroki Tani

Twitter | GitHub

Front-end Engineer, Writer & Speaker