LoginSignup
455
265

More than 3 years have passed since last update.

ワイ「ありゃ、SCSSの親セレクタが効かへんで?」について

Last updated at Posted at 2019-06-01

休日ワイ

ワイ「最近、お仕事でSCSSを書くことが多いから、そのお勉強でもしよか」
ワイ「会社の若い子らに負けんようにな」

娘(3歳)「パパ、お仕事のお勉強?」

ワイ「せや」

娘「パパのお仕事ってなあに?」

ワイ「パパのお仕事はな」
ワイ「フロントエンドエンジニアや」
ワイ「今年の2月まではライフエンドエンジニア、つまり無職やったんやけど」
ワイ「3月からはバリバリお仕事がんばってるで」

娘「えらいね、パパ」

ワイ「ありがとうな」
ワイ「でも、今の職場には若くて優秀な子らが多くてな」
ワイ「まだパパはあんまり活躍できてへんねん」
ワイ「若者たちに嫉妬しすぎて、ダークサイドエンジニアになりそうや」

よめ太郎「(なんやダークサイドエンジニアて)」
よめ太郎「(サーバーサイドみたいに言うなや)」

娘「そうなの?」

ワイ「ちょっとな」
ワイ「でも、若者たちに開発スピードで負けへんように!とか思いすぎて」
ワイ「テストをすっ飛ばしてコミットするようなオフサイドエンジニアにだけはなったらアカンから」
ワイ「地道にお勉強して頑張って行くしかないわ」
ワイ「せやから、今日はSCSSのお勉強や」

SCSSとは

娘「ところでパパ、SCSSってなあに?」

ワイ「CSSを楽に高速に書ける、超絶便利なやつや」
ワイ「例えばやな───」

HTML
<ul class="example-list">
  <li class="item">テキスト</li>
  <li class="item">テキスト</li>
  <li class="item">テキスト</li>
</ul>

ワイ「HTMLの中に↑こういうリストがあったとして」
ワイ「.example-listの背景色をgreenにしたかったら」

CSS
.example-list {
  background-color: green;
}

ワイ「↑こんな感じでCSS書くやろ?」
ワイ「それで更に.example-listの中の.itemにボーダーを付けたかったら」

CSS
.example-list {
  background-color: green;
}

.example-list .item {
  border: 1px solid;
}

ワイ「↑こんな風に.example-list .itemっていうセレクタを書かなあかんやろ?」
ワイ「それがSCSS記法で書くと───」

SCSS
.example-list {
  background-color: green;
  .item {
    border: 1px solid;
  }
}

ワイ「↑こう、入れ子にして書けるんや」
ワイ「.example-listを何度も書かんでええわけやな」
ワイ「更に、.itemの中にaタグがあったりした場合でも」

SCSS
.example-list {
  background-color: green;
  .item {
    border: 1px solid;
    a {
      font-weight: bold;
    }
  }
}

ワイ「↑こうやって、どんどんネストして書いてやれば」

CSS
.example-list {
  background-color: green;
}

.example-list .item {
  border: 1px solid;
}

.example-list .item a {
  font-weight: bold;
}

ワイ「↑こういうCSSにトランスパイル・・・つまり変換してくれんねや」

娘「たしかに、とっても楽チンだね」

ワイ「せやねん」
ワイ「もし.example-listっていうクラス名を
変更することになった場合も」
ワイ「1箇所なおすだけやしな」
ワイ「他にもドチャクソ便利な機能がいっぱいあるらしいで」

娘「ふ〜ん」
娘「すごいね」
娘「じゃあさ、パパ」
娘「a:hoverとかも───」

SCSS
a {
  :hover {
    opacity: .7;
  }
}

娘「───って書けるの?」

ワイ「いや、その書き方やと」

CSS
a :hover {
  opacity: .7;
}

ワイ「↑こう変換されてしまうんや」

娘「a:hoverの間に半角スペースが入っちゃったね」

ワイ「せやねん」
ワイ「セレクタをネストすると、aの中の:hoverって意味になってまうねん」

娘「そっか」

ワイ「a:hoverにしたい場合はこうや」

SCSS
a {
  &:hover {
    opacity: .7;
  }
}

娘「&を使うんだね」

ワイ「せや」
ワイ「&親セレクタ言うやつで」
ワイ「1つ外側のセレクタを参照する変数みたいなもんやねん」
ワイ「つまり、上の例では&aを示してるわけやな」

娘「そっかー」
娘「でもさ、パパ」
娘「普通にネストして書くと半角スペースが入ってa :hoverになっちゃうところが」
娘「&を使うとa:hoverになる・・・ってことは」
娘「&には、半角スペースを消してくっつけてくれる効果があるとも言えるよね」

ワイ「さすが娘ちゃんやな」
ワイ「その通りや」
ワイ「せやから&BEM書くときにも便利やで」
ワイ「例えば───」

HTML
<ul class="example-list">
  <li class="example-list__item">テキスト</li>
  <li class="example-list__item">テキスト</li>
  <li class="example-list__item">テキスト</li>
</ul>

ワイ「↑こんな感じで、BEMの命名規則にしたがって長いクラス名になってしまっても」

SCSS
.example-list {
  background-color: green;
  &__item {
    border: 1px solid;
  }
}

ワイ「↑こういう風にネストして、短くシンプルに書けるんや」
ワイ「普通のCSSやったら↓こうやで」

CSS
.example-list {
  background-color: green;
}

.example-list__item {
  border: 1px solid;
}

娘「SCSSの方がだいぶシンプルに書けて良さそうだね」

ワイ「せや」
ワイ「&はめっちゃ便利やねん」
ワイ「でもな・・・」

親セレクタ&の注意点

ワイ「&は若干、挙動が直感的やないところがあんねん」
ワイ「例えば───」

HTML
<ul class="example-list">
  <li class="item">テキスト</li>
  <li class="item">テキスト</li>
  <li class="item">テキスト</li>
  <li class="item">テキスト</li>
  <li class="item">テキスト</li>
</ul>

ワイ「HTMLの中に↑こういう要素があったとして」
ワイ「2個目以降の.itemにだけmargin-topをつけたい」
ワイ「そんなときってあるやん?」

娘「割とあるかも」

よめ太郎「(いや3歳児には無いやろ)」

ワイ「そんなときは隣接セレクタ、つまり+を使って」
ワイ「.itemの次の.itemmargin-topをつける」
ワイ「って感じで書けば、先頭の.itemには適用されずに」
ワイ「2個目以降の.itemにだけmargin-topをつけられるんや」
ワイ「つまり、普通のCSSで書くとこういうやつやな」

CSS
.example-list .item + .item {
  margin-top: 20px;
}

ワイ「これをSCSSで書こうとして」
ワイ「.itemの次の.itemやから」

SCSS
.example-list {
  .item {
    & + & {
      margin-top: 20px;
    }
  }
}

ワイ「↑こう書いてしまいたくなるんやけど」
ワイ「この書き方やと」

CSS
.example-list .item + .example-list .item {
  margin-top: 20px;
}

ワイ「↑こういうCSSに変換されてしまうんや」
ワイ「.example-list .item + .itemになって欲しかったところが」
ワイ「.example-list .item + .example-list .itemになってまうわけやな」

娘「えっと、つまり」
娘「&は1つ外側のセレクタを指す物だから.itemが入ってると思いきや」
娘「.example-list .itemが入ってた・・・」
娘「親の親も含んでたってことだね」

ワイ「せやな」
ワイ「せやから、今回のケースでは親セレクタは使えなくて」

SCSS
.example-list {
  .item + .item {
    margin-top: 20px;
  }
}

ワイ「↑こう書くか、もしくは」

SCSS
.example-list {
  .item {
    + .item {
      margin-top: 20px;
    }
  }
}

ワイ「↑こうやな」
ワイ「そうすると・・・」

CSS
.example-list .item + .item {
  margin-top: 20px;
}

ワイ「ちゃんと↑こう変換されるんや」

娘「ふーん」
娘「なんか、親って使えないんだね〜

ワイ「(ん?ワイの事か?)」

娘「.item + .itemでいいじゃん」
娘「わざわざ& + &にする意味あるの?」

ワイ「(よかった、SCSSの話や)」
ワイ「.itemっていうクラス名を2回書くよりも」
ワイ「&で変数っぽくしておいた方が、修正が発生した場合に楽やで」
ワイ「もし.itemっていうクラス名が変わったときに」
ワイ「クラス名を1箇所なおすだけで」
ワイ「&の中身も一緒に変わってくれるやん?」
ワイ「同じものを何度も書くよりも、変数化する・・・」
ワイ「そこはアレと一緒や」

娘「アレって?」

ワイ「ええと、アレや。アレ・・・」

娘「もしかして、プログラミング?

ワイ「それや!」

よめ太郎「(プログラミングが出てけぇへんかったんかい)」
よめ太郎「(本格的に脳腐って来てるやん・・・)」

BEMのネストなら&も使いやすい

ワイ「BEMの場合は& + &も使いやすいで」
ワイ「BEMで書く場合、基本的に長〜い1つのクラス名になるから」
ワイ「親の親、とか気にしないで済むねん」

娘「???」
娘「どういうこと?」

ワイ「つまりやな」
ワイ「さっきみたいに+を使って」

SCSS
.example-list {
  &__item {
    & + & {
      margin-top: 20px;
    }
  }
}

ワイ「↑こう& + &って書いたとしても」
ワイ「親と子のクラス名が全部繋がっていれば

CSS
.example-list__item + .example-list__item {
  margin-top: 20px;
}

ワイ「↑こう、想定通りの挙動になるわけや」

娘「ほんとだ・・・!」
娘「親も上手く使えば便利ってことだね」

ワイ「(さっきから語弊がエグいで・・・!)」

こんな&の使い方も

ワイ「ほかにもな」
ワイ「例えばこんな書き方もできんねや」

SCSS
.example-list {
  .item {
    body.top-page & {
      margin-top: 20px;
    }
  }
}

娘「body.itemの中に入っちゃってるよ?」

ワイ「そう見えるやろ?」
ワイ「でもこれは↓こう変換されんねん」

CSS
body.top-page .example-list .item {
  margin-top: 20px;
}

ワイ「body要素にtop-pageっていうクラスが付いてた場合のみ」
ワイ「.example-listの中の.itemに特定のスタイルをあてる」
ワイ「っていうことやな」

娘「&には.example-list .itemが入ってる感じだから」
娘「body.top-page &は」
娘「body.top-page .example-list .itemに変換されるんだね」
娘「使いこなしたら便利そう・・・!」

ワイ「せやで〜」

そんなこんなで晩ご飯タイム

娘「パパ、SCSSの事いろいろ知ってるんだね」

ワイ「いや・・・実はな・・・」
ワイ「さっきの知識も、会社の若い子に教えてもろてん」
ワイ「いっつも若い子らに教えてもらってばっかりで」
ワイ「なかなか追いつけなくて」
ワイ「ホンマ凹むわ・・・」
ワイ「若くて優秀な奴らが羨ましいで・・・」
ワイ「むしろ憎いで・・・」
ワイ「そして、そんな風に思う自分が嫌になるで・・・」

娘(3歳)「パパ」
娘「分かるよ」

ワイ「(分かんの!?)」
ワイ「(自分が一番若いやん)」
ワイ「(っていうか幼児やん)」

娘(3歳)「私も昔は、よく友達に嫉妬してた」
娘「それで、その子をやっかんだりしてた」

ワイ「(昔て)」
ワイ「(それもう前世とかやん)」

娘「でも最近は・・・」
娘「人に嫉妬したら、自分を磨くようにしてる
娘「満足できる自分になって、嫉妬を忘れたいから

ワイ「娘ちゃん・・・!」
ワイ「さすがに悟りすぎやろ!!!

〜おしまい〜

455
265
38

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
455
265