BEM modifier 寫 SCSS 子元素樣式的命名問題

BEM modifier 寫 SCSS 子元素樣式的命名問題

使用 BEM 來命名 CSS Class 並且使用 SCSS 來編寫是一件多麼愉快的事情,這不僅能讓 CSS 模組化(複用行高)以外,甚至能更加語意化(乾淨的程式碼)。

BEM 的範例如下:

<div class='menu'>
  <div class='menu__item menu__item--is-active'>
    <a href="#" class='menu__link'>John Doe</a>
  </div>
</div>

SCSS 如下:

.menu {
  padding: 2vw;
  &__item {
    padding: 5px 20px;
    background-color: #FFF;
  }
  &__link {
    color: #000;
  }
}

當在寫 menu__item 的 modifier 可能會這樣寫:

.menu {
   樣式。。。。
   &__item {
    樣式。。。。
    &--is-active {
      background-color: #000;
        &__link {
         color: #FFF;
        }
     }
  }
}

編譯成 CSS 的結果:

.menu {
    樣式。。。。
}
.menu__item {
   樣式。。。。
}
.menu__item--is-active {
   background-color: #000;
}
.menu__item--is-active__link {
   color: #FFF;
}

你會發現 modifier 編譯後的結果.menu__item--is-active__link,並不是我們想要的,要解決這個問題其實不難。

變數選擇器

可以利用 SCSS 變數的功能來儲存 .menu 選擇器,範例如下:

.menu {
   $menu: &;
   &__item {
    樣式。。。。
    &--is-active {
     background-color: #000;
     #{$menu}__link {
       color: #FFF;
     }
    }
  }
}

編譯成 CSS 的結果:

.menu {
    樣式。。。。
}
.menu__item {
   樣式。。。。
}
.menu__item--is-active {
   background-color: #000;
}
.menu__item--is-active .menu__link {
   color: #FFF;
}

注意

使用變數有區域的限制問題,它無法在區域之外呼叫定義的變數

// 這是錯誤示範
.menu {
   $menu: &;
}

.block {
   #{$menu}__item {
    }
}

除了變數選擇器

使用變數選擇器的方式處理外,你們還有其他的解決方式嗎?歡迎在下面留言分享唷!

參考連結

How to do SASS Grandparent Selectors