Modifying BEM classes with Sass #extend - css

With the BEM methadology, say I have two classes like this:
.staff__teacher
and .staff__teacher--professor
In the markup for the professor, is the idea to have both classes or just the modified class?
<div class='staff__teacher staff__teacher--professor'></div>
or
<div class='staff__teacher--professor'></div>
From my point of view, it seems to make much more sense to go for the latter as it is more streamlined and easier to read.
In Sass, the class would be created by simply extending the .staff__teacher class
.staff__teacher--professor{
#extends .staff__teacher;
//...extra professor styles here..
}
However, in the majority of tutorials I've seen on BEM, both classses are added to the markup. Can someone help me understand if one way is preferable to the other? Are there any problems that using my method might cause?

Firstly, this is a fairly opinion based answer. There is nothing stopping you using #extends instead of a base class. Here are some reasons why two classes may be used.
1. It's not just about SASS
Firstly, not everyone uses SASS. Even LESS didn't have extend until fairly recently. A methodology should not limit itself to a particular preprocessor or one at all. Plain old CSS is what we are looking at here. However to could do something like this:
CSS
.button,
.button--red,
.button--green {
// base styles
}
Personally I'd rather leave the base style alone once I've written it and in the case of buttons I might have quite a lot of modifiers. For me this is getting a bit messy, where as putting two classes on an element is keeping my CSS cleaner and more concise.
2. Descriptive
Part of BEM is that classes are now more descriptive, you can look at a stylesheet and have a greater understanding of the module/component and what is contained within it. For me base classes do the same. It gives me more information when I'm looking at my markup.
<input type="submit class="button button--green"/>
I can see it's a green button and that it derives from button, I know I can change this easily and there are probably other options available to me. All without looking at the stylesheet.
3. Flexibility and consistency
Don't think that you will only ever have a base class and one modifier. You can quite easily have many. For example, I could have button, button--large and button--green.
<input type="submit class="button button--large button--green"/>
So which modifier would extend button? If both did then you would have the same styles applied twice. How does another developer know? By keeping a simple consistent approach your component is much clearer to read, understand and use correctly.
Summary
These were a few reasons why extend is not used often in examples. I think the most important point is, what ever you do make sure is a consistent approach and all developers are aware of this.

use code this sample
//css
<style>
.firstClass{
color:red;
font-size:20px;
}
.secondClass{
border:1px solid red;
font-size:30px;
display:inline-block;
}
.thirdclass{
font-size:40px;
}
.fourthclass{
padding:50px;
}
</style>
//use code html
<div class="firstClass secondClass thirdclass fourthclass">khitsapanadilove#gmail.com</div>
<div class="secondClass thirdclass"> khitsapanadilove#gmail.com </div>
<div class="thirdclass firstClass"> khitsapanadilove#gmail.com </div>
<div class="secondClass fourthclass"> khitsapanadilove#gmail.com </div>

// another example use css code
.message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.success {
#extend .message;
border-color: green;
}
.error {
#extend .message;
border-color: red;
}
.warning {
#extend .message;
border-color: yellow;
}
//write you html code
<div class="message">khitsapanadilove#gmail.com</div>
<div class="message success"> khitsapanadilove#gmail.com </div>
<div class="message error"> khitsapanadilove#gmail.com </div>
<div class="warning message"> khitsapanadilove#gmail.com </div>

Related

BEM: How to (and should I) reuse class names?

Lets suppose I have the following site structure:
As you can see, the affirmation blocks serve the same purpose, so it makes sense to use the same name for them, but it creates a name conflict.
The question is the following:
Is there a cool trick that allows me to reuse class names without creating conflicts?
If there is, is it a good idea? Is it BEM-like?
Is it better just to come up with a new class name (something like affirmation-awesome?
Note:
I use affirmation__p instead of cool-block__p and awesome-block__p because that text must be styled differently.
Using BEM conventions, these two blocks do not conflict when using BEM conventions correctly. Typically when nesting you should not really venture into to many nesting layers layers but using SCSS they can be split up assuming they are blocks with separate styling conventions. Think of BEM as grouping and structuring your code in an orderly fashion, but do not go beyond 3 nesting layers as this can make your code messy & unreadable.
.cool-block{
background:#f5f5f5;
padding:1rem;
box-sizing: border-box;
&__affirmation{
background: #ffffff;
color: #333;
&__p{
font-size: 1.2rem;
}
}
}
and your html:
<div class="cool-block">
<div class="cool-block__affirmation">
<div class="cool-block__affirmation__p">
This is my cool block
</div>
</div>
</div>
Then for your other block you can separate:
.awesome-block{
background:#e7e7e7;
padding:2rem;
box-sizing: border-box;
&__affirmation{
background: #333333;
color: #ffffff;
&__p{
font-size: 1.4rem;
}
}
}
and your html for this:
<div class="awesome-block">
<div class="awesome-block__affirmation">
<div class="awesome-block__affirmation__p">
This is my awesome block
</div>
</div>
</div>

Appropriate use of BEM in CSS

I'm an old hand with CSS, but have recently decided to take the plunge and begin using BEM. For the most part, I understand the value of using such a flat system, avoiding overly specific selectors etc...
My question is, is the following approach correct. It works, technically, but also seems fragile:
.badge {
/* additional declarations */
background: rgba(0, 0, 0, 0.2);
}
.badge--error {
background: red;
}
.badge--success {
background: green;
}
This works fine, because of the cascading nature of CSS. So the default background is overwritten by the modifier successfully. But if I put the modifier before the initial declaration, the modifier is ignored (because of the equal specificity).
Are there any issues with writing BEM this way? Is it considered bad practice to declare a default value of something like a background within the block, if it's to be overwritten with modifiers? Should the default background in this instance, live in a .badge--default modifier? Or have I written this in a true BEM fashion, and BEM actually relies on CSS' cascading in order to remain flat?
You could make use of CSS variables
.badge {
background: var(--background);
}
.badge--error {
--background: var(--error);
}
.badge--success {
--background: var(--success);
}
:root {
--background: yellow;
--error: red;
--success: green;
}
<div class="badge">
a badge
</div>
<div class="badge badge--success">
a badge success
</div>
<div class="badge badge--error">
a badge error
</div>
<div class="badge" style="--background: purple">
a badge random
</div>
I don't see why a modifier could not modify just a background if it is(n't) set in the initial element.
For BEM I can recommend using a CSS preprocessor like SASS since it make it quite easy to nest elements there is less change of declaring some modifier before the initial declaration. Because of the nesting your CSS becomes much more organised. It is also easier to import different components so each component can live in its own file.
With SASS you can do:
.badge {
&--error {}
&--success {}
}

Basic SASS - Nesting and HTML Syntax

I just started using SASS however I can't seem to find a clear answer/example for this.
Say I have:
<img class="socialIcons" src="/images/facebook.png"/>
<img class="socialIcons" src="/images/google.png"/>
I now want to have some additional styles for Facebook and Google - is there some clever SASS syntax I can use for example so I get:
<img class="socialIcons-facebook" src="/images/facebook.png"/>
<img class="socialIcons-google" src="/images/google.png"/>
And in my SASS use:
.socialIcons {
max-height: 30px;
padding-right: 10px;
&.facebook {
background: blue;
}
}
So that it adopts the general socialIcons style as well as Facebook.
Can't seem to figure the syntax.
Thanks.
You mean this?
<img class="socialIcons facebook" src="/images/facebook.png"/>
<img class="socialIcons google" src="/images/google.png"/>
The '&' syntax will match an element that has both the outer class and the class with the & selector. You can overwrite the 'socialIcons' class with the more specific nested selector. No need to change the Sass.

Declaring same CSS class multiple time

<div class="big_box">haha</div>
<div class="small_box">haha</div>
This (type 1) seems workable :-
.big_box, .small_box { border:1px solid #ccc; /* lengthy attributes*/}
.big_box { width:150px; height:150px; }
.small_box { height:140px; width:140px; }
This (type 2) also works :-
.big_box { border:1px solid #ccc; width:150px; height:150px; /* same lengthy attributes*/}
.small_box { border:1px solid #ccc; width:150px; height:150px; /* same lengthy attributes* }
Of course, type 2 is lengthy and repeating for most of the common attributes (with same value),
is there any issue for using type 1 ?
(or simply this is allowed ?)
P.S type 3 works too (but I find is hard to manage) ... if
<div class="box big">haha</div>
And
.box { border:1px solid #ccc; /* lengthy attributes*/}
.big { width:150px; height:150px;}
type 1 is actually very common when declaring multiple classes with some share the same attributes and some have their owned unique attributes. type 2 is a bit dirty to maintain while type 3 is similar to type 1.
it is all works, just a matter of coding style and ease of maintenance
There is no issue using the first syntax.
It is actually useful, as you noticed to avoid repeating the same time the same styling.
It is also useful to separate the types of styling: positionning, fonts, colors.
You can for instance have in one file the styling that positions the elements and in another file the styling for the colors/backgrounds, allowing you to change the "theme" of your site by just changing the css file responsible for your colors, without breaking the layout itself.
This is for instance what is used in jQuery UI CSS Framework. You have:
the jquery ui base css
all the jquery themes files
All three possibilities are allowed. I'd prefer the third for its conciseness.
I would use option 3 so that both boxes inherit the class box and then you can define whether that box is small or large.
However, there are a number of ways you can do this but this would certainly be my recommendation.
I prefer hyphenated classes.
This way you could do something like this:
<div class="box-big">haha</div>
<div class="box-small">haha</div>
div[class|=box]{
/* shared attributes*/
}
.box-big{
/* stuff */
}
.box-small{
/* stuff */
}

Can I include a css definition in another css definition?

So let's say I have the following in 'foo.css':
.border { border : solid 1px; }
#foo { color : #123; }
#bar { color : #a00; }
Now let's say that I have two divs I want borders for, so I do:
<div id="foo" class="border">Foo</div>
<div id="bar" class="border">Bar</div>
This works fine, but I find that when defining #foo and #bar in my css file, I would rather give them the characteristics of .border than give the div's the class, like so:
.border { border : solid 1px; }
#foo {
<incantation to inherit from .border>
color : #123;
}
#bar {
<incantation to inherit from .border>
color : #a00;
}
and then my html would just be:
<div id="foo">Foo</div>
<div id="bar">Bar</div>
Anybody know what that magic incantation is?
That is not supported by css. The best you can do is something like:
#foo, #bar, .border { border : solid 1px; }
#foo { color : #123; }
#bar { color : #a00; }
You might be interested in mixins with Sass. Sass lets you write css style sheets in a more efficient way, using tricks like this. Mixins let you define a group of attributes (say, to do with borders), and then include those attributes within certain css classes.
As Wsanville said, you can't use the class.
But normal CSS inheritance does work - say if your html was
<div class="border">
<div id="foo">
hello
</div>
<div id="bar">
world
</div>
</div>
You could say
.border {border: 1px solid #f00;}
#foo {border:inherit;}
Which in some cases might be good enough
If you're looking to push your CSS further instead of using some of the tricks outlined in earlier posts, you should look into CSS Compilers. They take CSS-like code you've writen, usually CSS with a few tricks added in, and turn them into normal CSS for the web.
David Ziegler wrote about some of the cool featured CSS compilers offer:
Variables - Good programmers don’t like to hardcode. In many cases you can avoid this in CSS by using good inheritence, but sometimes it’s unavoidable. With variables, changing your color scheme means updating one variable instead of 13 attributes.
Math - This goes hand in hand with variables. Say your left column is 100px, your right column is 500px, and your wrapper div is 600px. Well, maybe you decide to change it to 960px. Wouldn’t it be awesome if the width of your columns adjusted automatically? The answer is yes.
Nested Styles - This is probably the most important. CSS is flat, which means complex sites end up with CSS that is a pain to go through.
You can read about popular compilers in his blog post on the subject, or do some searching and find one that works best for you.

Resources