SASS

ネストしたセレクタで親セレクタに対して要素を限定したい場合

例えば.btn1ってクラスのa要素またはbutton用のスタイルを作るとして、
普段は白文字、:disabledもしくはhref属性がない場合ならグレー文字ってしたいと思うじゃないですか。
そしたら以下みたいなコード書くと思います。

.btn1 {
  color: white;

  &disabled, &:not(button):not([href]) {
    color: gray;
  }
}

でもここで上記を継承するチェックボックス用の.btn1-checkboxが現れると、
aでもbuttonでもない場合は:not([href])が効いてしまい、常にグレーになってしまうので、どうするか・・・

.btn1 {
  color: white;

  &:disabled, &:not(button):not([href]) {
    color: gray;
  }
}

// チェックボックスで使いたいけど、このままじゃ常にグレーになっちゃう
.btn1-checkbox {
  @extend .btn1;
}

スポンサーリンク

:not([type=”checkbox”])を追加する

一番最初に思いつく方法だと思います。

.btn1 {
  color: white;

  &:disabled, &:not(buttn):not([type="checkbox"]):not([href]) {
    color: gray;
  }
}

.btn1-checkbox {
  @extend .btn1;
}

ですが、継承先が増えるたびに継承元を変化させないといけないのはエレガントではないです。なくない?ないよね?

要素名をねじ込んでみる

.btn1 {
  color: white;

  // aをねじ込んでみた
  &:disabled, a#{&}:not([href]) {
    color: gray;
  }
}

.btn1-checkbox {
  @extend .btn1;
}

コンパイル通っちゃうから『これで勝ったな』と思いますが、残念なことにコンパイル結果を見ると親のセレクタが分身しちゃってます。

.btn1, .btn1-checkbox {
  color: white;
}
.btn1:disabled, .btn1-checkbox:disabled, .btn1 a.btn1:not([href]), .btn1-checkbox a.btn1:not([href]), .btn1 a.btn1-checkbox:not([href]), .btn1-checkbox a.btn1-checkbox:not([href]) {
  color: gray;
}

@at-rootの活用

ここで@at-rootの出番となります。

.btn1 {
  color: white;

  // @at-root入れてみた
  @at-root &:disabled, a#{&}:not([href]) {
    color: gray;
  }
}

.btn1-checkbox {
  @extend .btn1;
}

以下コンパイル結果。

.btn1, .btn1-checkbox {
  color: white;
}
.btn1:disabled, .btn1-checkbox:disabled, a.btn1:not([href]), a.btn1-checkbox:not([href]) {
  color: gray;
}

若干無駄なセレクタが出力されているものの影響は無いと考え、万事解決。
ただし、親セレクタがネスト関係にあると話が変わるので注意。

こういう実用例があると@at-rootの使い道が理解できるんですが、なかなかないんですよね~って最近SASS始めたばかりの俺が思いましたとさ。

スポンサーリンク
記事を書いた人

システムえんじにゃー🐈
趣味はエレキギター、自転車など。作曲したい。
World of Warshipsやってます。
記事に関する質問はお気軽にどうぞ。

surface0 (さーふぇす)をフォローする
surface0 (さーふぇす)をフォローする

コメント

タイトルとURLをコピーしました