Sacc selector-replace()とselector-extend()で同一のスタイルを便利にする

最初にサンプル

//親セレクタを変更してスタイルを変えたい時
@mixin replace($original, $replacement){
    @at-root #{selector-replace(&, $original, $replacement)}{
        @content
    }
}

//親セレクタを変更して同一スタイルを適用したい時
@mixin extend($original, $inherit){
    @at-root #{selector-extend(&, $original, $inherit)}{
        @content
    }
}


//&::before,::afterでスタイルを変えたい時
.block{
    .item{

        &::before{
            
            //::beforeにも::afterにも適用させたいスタイル
            @include extend("::before", "::after"){
                content:'';
                display: block;
                width: 10px;
                height: 10px; 
            }

            background: red;
            
            //::afterだけ変更したいスタイル
            @include replace("::before", "::after"){
                background: blue;
            }
            
        }//.item::before

    }//.item
}//.block
.block .item {
 width: 85%; }

.block .item::before {
 background: red; }

.block .item::before, .block .item::after {
  content: '';
  display: block;
  width: 10px;
  height: 10px; }

.block .item::after {
  background: blue; }

ネストしたセレクタを@at-rootとselecotr-replaceを使って置き換える

スタイルを変更したいときに使用。

.block{
    .itemA{
        a{
            background: red;

            @at-root #{selector-replace(&,'.itemA','.itemB')}{
                background: green;
            }
        }//a
    }//.itemA
}//block
.block .itemA a {
  background: red; }
  .block .itemB a {
    background: green; }
@at-rootとselecotr-replaceをmixinで便利に利用
//親セレクタを変更してスタイルを変えたい時
@mixin replace($original, $replacement){
    @at-root #{selector-replace(&, $original, $replacement)}{
        @content
    }
}

//&::before,::afterでスタイルを変えたい時
.block{
    .item{
        width: 85%;
        &::before{
            content:'';
            display: block;
            width: 100px;
            height: 100px;
            background: red;
            
            @include replace("::before", "::after"){
                background: green;
            }
        }

    }//.item
}//.block

//階層が増えた時
.block{
    .item{
        width: 85%;
        @include replace(".block", ".block .inner"){
            width: 100%;
        }
    }
}

//クラス名を追加した時
.sample{
    color: beige;
    @include replace(".sample",".sample.B"){
        color: red;
    }
}
.block .item {
  width: 85%; }
  .block .item::before {
    content: '';
    display: block;
    width: 100px;
    height: 100px;
    background: red; }
    .block .item::after {
      background: green; }

.block .item {
  width: 85%; }
  .block .inner .item {
    width: 100%; }

.sample {
  color: beige; }
  .sample.B {
    color: red; }

&-message{}など&を使った中では使えないので注意が必要です。

セレクタを変更して同一スタイルを適用するselector-extend()

同じスタイルを違うセレクタに適用させたいときに使用。

.block{
    .itemA{
        a{
            padding: 10px;

            //▼itemBにも適用させたいスタイル
            @at-root #{selector-extend(&,'.itemA','.itemB')}{
                background: green;
                margin-right: 10px;
            }

        }//a
    }//.item
}//block
.block .itemA a {
  padding: 10px; }

 .block .itemA a, .block .itemB a {
    background: green;
    margin-right: 10px; }

selectore-extend()をmixinで便利に使う

//親セレクタを変更して同一スタイルを適用したい時
@mixin extend($original, $inherit){
    @at-root #{selector-extend(&, $original, $inherit)}{
        @content
    }
}


//&::before,::afterでスタイルを変えたい時
.block{
    .item{

        &::before{
            
            //::beforeにも::afterにも適用させたいスタイル
            @include extend("::before", "::after"){
                content:'';
                display: block;
                width: 10px;
                height: 10px; 
            }

            background: red;
         
            
        }//.item::before

    }//.item
}//.block
.block .item {
  width: 85%; }

  .block .item::before {
    background: red; }

    .block .item::before, .block .item::after {
      content: '';
      display: block;
      width: 10px;
      height: 10px; }