Styling in sass gets even more powerful when using custom selectors that are

Using these mixins makes it easy to work with BEM syntax in sass 3.3.2:

=b($name)
  .#{$name}
    @content

=e($name)
  &__#{$name}
    @content

=m($name)
  &--#{$name}
    @content

+b(menu)
  +e(item)
    color: grey
  +e(item)
    +m(alert)
      color: red

With this setup, we get the desired result:

.menu__item {color: grey;}
.menu__item--alert {color: red;}

However, issues arise when dealing with block level modifiers:

+b(menu)
  +m(theme-1)
    +e(item)
      color: blue

The CSS output is:

.menu--theme-1__item {color: blue;}

But what is actually needed is:

.menu--theme-1 .menu__item {color: blue;}

An attempt was made to determine the context of an element using parent selectors within the mixin, but it did not fully solve the issue.

Update A workaround was discovered by adding a context argument to the element mixin:

=e($name, $context:null)
  @if $context
    &
      +b($context)
        &__#{$name}
          @content
  @else
    &__#{$name}
      @content

Now, the mixin can be called as follows:

+b(menu)
  +m(theme-1)
    +e(item, nav)
      color: blue

This results in:

.menu--theme-1 .menu__item {color: blue;} 

Answer №1

Responding to a question that is 2 years old - a bit of a long shot :) But hopefully it can also be beneficial to someone else.

To make your Element mixin more reliable, you should enhance it by checking if the parent selector has a modifier.

You will need to create two functions:

  • one function to verify if a selector includes a modifier
  • another function to extract the block name from that selector

@function _bem-selector-has-modifier($selector) {
  $selector: _bem-selector-to-string($selector);

  @if str-index($selector, $bem-modifier-separator) or str-index($selector, ':') {
    @return true;
  } @else {
    @return false;
  }
}


@function _bem-get-block-name($selector) {
  $selector: _bem-selector-to-string($selector);
  $modifier-separator: '--';

  $modifier-start: str-index($selector, $modifier-separator) - 1;

  @return str-slice($selector, 0, $modifier-start);
}

Then, you just have to implement this check in your element mixin

$bem-element-separator: '__';

@mixin element($element) {
  $selector: &;

  @if _bem-selector-has-modifier($selector) {
    $block: _bem-get-block-name($selector);

    @at-root {
      #{$selector} {
        .#{$block + '__' + $element} {
          @content;
        }
      }
    }
  } @else {
    @at-root {
      #{$selector +'__' + $element} {
        @content;
      }
    }
  }
}

Therefore, by calling element('item') within a modifier('with-modifier'), you should see a

.block--with-modifier .block__item
selector in your compiled CSS without needing to manually set the context.

The code provided is in SCSS format, but the concept remains consistent with SASS.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to use jQuery to dynamically set the line-height of nested objects in CSS?

I am in the process of creating a horizontal family tree. Where I'm At - I am currently working on setting the CSS Line-Height to vertically center each item based on nested content. The Issue - The Line-Height value for nested items keeps growing e ...

Animation showing on the progress bar is not correctly halted

I am encountering a problem with handling an animation of a progress bar in my code. The issue arises when I pause the animation, as it seems to slightly backtrack instead of pausing at the correct position upon clicking a button. Can someone help identify ...

At times, the CSS fails to load at first and does not refresh correctly when using F5 or CTRL F5, yet it occasionally loads when clicking on links

After dedicating a full day to trying to solve this issue, I am reaching out for some assistance. As a newcomer here, I apologize if this question has been asked before (I did search extensively and found nothing). The website I'm constructing for my ...

Mastering the Zurb Foundation equalized grid: aligning content at the bottom of a div within a grid cell

One common challenge is how to position content at the bottom of a div, but with Flexbox, it's becoming easier nowadays. In my case, I'm using the Zurb Foundation grid with equalisation. This equalisation is crucial because my cells have an imag ...

Can you inherit from a class in a different file using SASS?

All the information needed is in this question. For example, if I decide to utilize Twitter Bootstrap, would it be possible for me to create classes in my own SASS stylesheet that inherit from Bootstrap's CSS classes? Or is SASS inheritance restricte ...

The html input box's ability to handle overflow situations

Currently, I am working on creating a form that allows users to update data. <dl> <dt>Medical Needs:</dt> <dd class="med_needs" style="height:60px;overflow:auto"> <input type = "text" id="med_needs"name ="med_nee ...

Attempting to eliminate the padding from the unordered list (ul) element within the pop-up box

Upon clicking the chip with chipName="button test IPA", a popup window appears. I am attempting to remove the padding from the ul tag within that popup. The issue I'm facing is that I cannot locate the ul tag in my HTML or JSX code. I have assigned a ...

Adjust the dimensions of the embedded Google document

Currently, I am in the process of developing a website for my initial client and I'm encountering some difficulty in adjusting the size and background color of an embedded google doc. If anyone could provide assistance, it would be greatly appreciated ...

Tips for adding a red dot at the top-right corner of a necessary HTML input label, similar to an asterisk

Is there a way to replace the asterisk with a dot in an HTML label for a required input? The dot should be positioned in the top-right corner similar to where the asterisk would typically be. ...

Adjust the alignment of two headers with varying sizes

Can someone provide guidance on aligning two headers of different sizes (e.g. h3 and h5) based on their bottom edges, making them appear like a cohesive group in a sentence format? The current code snippet I am working with is as follows: ...

"Experience the mesmerizing transition effects of Angular Bootstrap tabs as they gracefully glide in

I am currently working on implementing an animated slide effect when switching between tabs on a webpage. However, I have encountered some difficulties as the animation only seems to work partially. My approach involves using animate.css with the expectat ...

Ways to customize the background color of child cells in a table

I've implemented material-table in this UI and I'm currently working on customizing the style of specific cells only when the onTreeExpandChange is true. Essentially, my goal is to change the background color for cells 2 & 3. Check out the s ...

The text is not rendering properly, with some characters being replaced by different ones

RESOLUTION: To fix the issue, eliminate font-family, font-size, and color properties from the parent div. UPDATE: The problem only occurs when I press CTRL + F5. UPDATE 2: After investigating, I found that the culprit is .site-footer with a position:abso ...

"Enhance your audio experience across all browsers with the revolutionary

I am looking for a way to play an mp3 file endlessly when the user opens my website. I need a lightweight crossbrowser solution that works in all browsers, including IE. Any suggestions? ...

Graphic selectors: a new take on radio buttons

I've been attempting to make this work, but it's not functioning correctly. Below is the CSS code: .input_hidden { position: absolute; left: -9999px; } .selected { background-color: #000000; } #carte label { display: inline-bl ...

What is the process for setting up a vertical carousel in Bootstrap 5 with a stationary previous image?

Looking for assistance with my vertical carousel project. Is there a way to create a vertical carousel in bootstrap 5 with the previous image fixed? I found a slider on this website: zara.com/jp/en/ I want to maintain the previous image in a fixed posit ...

Guide on creating a toggle effect for a div with querySelector and addEventListener

I utilized the email and password divs provided by Bootstrap. The CSS for the id dropdownlogin includes display: none; in this post, I hope that I have shared adequate information. <script> document.addEventListener('DOMContentLoaded', ...

The conditional comment designed for browsers other than Internet Explorer may not work properly on outdated versions of

I find myself in a predicament where I must dynamically load one of two stylesheets depending on the browser accessing the page: If any browser other than IE, then load the "new" stylesheet If IE is version 9 or higher, then load the "new" stylesheet ...

When a table has overflow set to auto, any content that exceeds its dimensions will

The issue at hand is explained in the fiddle provided. The problem arises when there is a scrollable table with a context menu inside it, and with the overflow-x: auto property set, the visibility of this "context menu" is hindered. table { overflo ...

What is the reason behind text underline being disabled when using "hidden: overflow" in CSS?

I have a long text string that I want to auto-shorten using CSS with text-overflow: ellipsis, but it's removing the underline from my link. Here is the code: NORMAL .link { font-weight: bold; cursor: pointer; color: black; text-decorat ...