Sass 3.3 new feature @at-root doesn't seem to compile
I believe you are using a slightly out of date version of the syntax. Try this:
@mixin element($name)
{
@at-root &__#{$name}
{
@content;
}
}
Issue with M in BEM with React CSS Module
The way you using modifiers is incorrect at all.
Modifiers are not sub-elements, they are modifiers for blocks and elements and can't be used without mother-eneities.
Correct:
<div class="b">
<div class="b__e">
<div class="b b--m1 b--m2">
<div class="b__e b__e--m b__e--m2">
Incorrect:
<div class="b--m1">
<div class="b__e--m">
The reason why it works like this is the nature of modifiers — they are things very close to interfaces or mix-ins, they can't be used without blocks like interfaces can't be used without classes.
Read more about modifiers here: https://en.bem.info/methodology/key-concepts/#modifier
Another thing you should not repeat BEM-structure in your HTML-structure.
So this is Incorrect:
<div className={styles.card__content}>
<div className={styles['card__content--icn']}>Icon</div>
<div className={styles['card__content--sub']}>Test</div>
</div>
And this is Correct:
<div className={styles.card__content}>
<div className={styles.card__icon}>Icon</div>
<div className={styles.card__sub}>Test</div>
</div>
See https://en.bem.info/methodology/faq/#can-i-create-elements-of-elements-block__elem1__elem2
If you interesting in using BEM with React you should take a look at bem-react-core — tiny library that helps you generating BEM-classes, provides runtime, etc.:
- https://github.com/bem/bem-react-core/
:deep() syntax with nested scss rules
Sass apparently doesn't allow the selector argument list of :deep
(or of any other pseudo-class) to be nested because of the reason you mentioned, but there are a couple workarounds.
Workaround 1: Split up the Sass styles
Split up the styles so that :deep
's selector list is not nested:
<!-- MyParent.vue -->
<style scoped lang="scss">
:deep(.wrapper) {
display: flex;
}
:deep(.wrapper__element) {
display: block;
}
</style>
demo 1
Workaround 2: Split up the class names
Break up the BEM class names (from wrapper__element
to __element
) so that parent selectors are not necessary:
<!-- MyComponent.vue -->
<template>
<div class="wrapper">
<div class="__element">...</div>
</div>
</template>
or augment wrapper__element
with an additional __element
class (if you can ignore the repetition):
<!-- MyComponent.vue -->
<template>
<div class="wrapper">
<div class="wrapper__element __element">...</div>
</div>
</template>
For some reason, this scenario requires :deep
to based on a selector (e.g., root
in the example below):
<!-- MyParent.vue -->
<template>
<div class="root">
<MyComponent />
</div>
</template>
<style scoped lang="scss">
.root:deep(.wrapper) {
display: flex;
.__element {
display: block;
}
}
</style>
<!-- MyComponent.vue -->
<template>
<div class="wrapper">
<h1>.wrapper</h1>
<!-- Add __element class here (and optionally remove wrapper__element) -->
<div class="wrapper__element __element">
<h1>.wrapper__element</h1>
</div>
</div>
</template>
demo 2
Sass .scss: Nesting and multiple classes?
You can use the parent selector reference &
, it will be replaced by the parent selector after compilation:
For your example:
.container {
background:red;
&.desc{
background:blue;
}
}
/* compiles to: */
.container {
background: red;
}
.container.desc {
background: blue;
}
The &
will completely resolve, so if your parent selector is nested itself, the nesting will be resolved before replacing the &
.
This notation is most often used to write pseudo-elements and -classes:
.element{
&:hover{ ... }
&:nth-child(1){ ... }
}
However, you can place the &
at virtually any position you like*, so the following is possible too:
.container {
background:red;
#id &{
background:blue;
}
}
/* compiles to: */
.container {
background: red;
}
#id .container {
background: blue;
}
However be aware, that this somehow breaks your nesting structure and thus may increase the effort of finding a specific rule in your stylesheet.
*: No other characters than whitespaces are allowed in front of the &
. So you cannot do a direct concatenation of selector
+&
- #id&
would throw an error.
Related Topics
Chrome Cut Off Oswald-Light Font
Pandas Style Doesn't Work with Google Colab
:Before and :After Pseudo Elements on HTML Tag Is Wonky in Chrome
How to Overflow the Contents of a Column into the Next Column Using CSS
Xpages: Ibm Oneui VS. Bootstrap
How to Align a Div to The Top of Its Parent But Keeping Its Inline-Block Behaviour
Horizontal Scroll in Div with Many Small Div's Inside (No Text)
Remove Dotted Outline from Range Input Element in Firefox
CSS Modules - Exclude Class from Being Transformed
Is -Negative Margin or Padding Invalid CSS According to W3C
Align Checkboxgroupinput Vertically and Horizontally
Do CSS Variables Work Differently in Microsoft Edge