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

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>

Related

Leveraging the CSS sibling selector within BEM

Say I have a block called .my-block. Depending on whether a specific element, say, .my-header appears before it, I need to style it differently. Because this is easy to do with the CSS sibling selector, I'd like to avoid adding conditionals to my HTML templates and add modifiers to my-block. I've considering two options.
Option 1)
<body class="my-block-container">
<header class="my-header my-block-container__header"></header>
<div class="my-block-container__my-block"</div>
</body>
Option 2)
<header class="my-block-sibling"></header>
<div class="my-block"</div>
I dislike option 1, because no classes will be applied directly to .my-block-container and .my-block-container__header. Moreover, I'd have to either rename the children of .my-block and apply the somewhat vague my-block-container as a block name, or introduce a new block-level name with the only purpose of selecting a sibling.
I dislike option 2, because it's not truly BEM; there's no true block-level name.
Should I accept that I've reached the limits of BEM naming, or is there a convention for this kind of situation?
Did you considered using a modifier for this case?
<body>
<header class="my-header"></header>
<div class="my-block my-block--after-a-header"</div>
</body>
This will allow us to have separated styles between header and block, and to style differently a block when it's after a header.
Next step will be to rename the modifier class to express what it does (and not when to use it), so it will allow you to reuse it in an other context in the future.
For example: .my-header--small will be more explicit than .my-block--after-a-header
I think your idea to use a sibling selector (+) is a good one in this scenario.
Here is a working example of BEM + sibling selector in practice,
Working Example:
.my-block-container {
float: left;
width: 120px;
height: 144px;
margin-right: 12px;
text-align: center;
}
.my-block-container__header {
line-height: 24px;
font-weight: bold;
}
.my-block {
width: 120px;
height: 120px;
line-height: 60px;
color: rgb(255, 255, 255);
}
.my-block-container__my-block {
margin-top: 24px;
background-color: rgb(255, 0, 0);
}
.my-block-container__header + .my-block-container__my-block {
margin-top: 0;
background-color: rgb(0, 0, 255);
}
<div class="my-block-container">
<div class="my-block my-block-container__my-block">Not preceded by <header></div>
</div>
<div class="my-block-container">
<header class="my-block-container__header">Header</header>
<div class="my-block my-block-container__my-block">Preceded by <header></div>
</div>

Apply 2 different CSS pseudo-elements to the same class on the same time

It is correct to apply 2 different CSS pseudo-elements to the same class on the same time?
Browser interpret my desired result, at least on Firefox everything works fine, but for me is important if this is a correct approach.
Do you have a correct CSS approach of this scenario?
.critselect {
display: block;
margin-top: 40px;
}
.critselect p:nth-child(2) {
text-transform: lowercase;
}
.critselect p:nth-child(2):first-letter {
text-transform: uppercase!important;
}
<div class="critselect">
<p class="randvis">This is first paragraph and have <strong>CRM / Marketing</strong> or others extrnaly inserted values that must remain Uppercase.</p>
<p class="randvis">This is second paragraph and have <strong>French, English, German</strong> or others eternaly inserted values that must to be converted via CSS to lowercase.</p>
</div>
yes, it's correct to apply two different CSS pseudo-class to the same class,
but in your scenario..., I do not see it very feasible, it is better to use text-transform: capitalize; it is also not necessary to use the important! is bad practice

How to avoid css selector applying style rules from another file

I came across this problem while handling a large project and felt that i should seek an opinion from the community here.
I have specified a css class 'header' in style1.css, i.e.
.header { color: red;}
In another file, I inadvertently, named a class 'header' again with this rule :
.header { background-color: yellow; }
When i refreshed the browser i noticed the red font and after examining the style inspector found the problem. I tried to avoid the problem by applying specificity, i.e. #some-div .header, but that didnt stop it from applying the red font. Of course i could simply solve the problem by renaming header to something else, but i'm curious how developers who handle large projects handle this. Thanks for your time.
Well, from your code, you specified values for different properties in the two declarations of the header class. The first declaration specifies a color property and the second specifies a background-color property. From all indications you're not really "overriding" anything since you didn't give conflicting values for one property so, CSS is simply giving the values of the first declaration of the header class to the second one because there's no difference. If you wanted to override it for the second you'd have to probably add a different identifier to the second declaration of the header class to point to a unique element and specify a different value for the color property. Hope this satisfied your curiosity.
Just add a different class to one of the cases. For example:
.header {
color: red;
}
.header.yellow-bg {
color: initial;
background-color: yellow;
}
<h3 class="header">Red header</h3>
<h3 class="header yellow-bg">Black/yellow header</h3>
The second declaration for color applies because it is more specific (2 classes > 1 class).
Don't use !important as another user suggested. Avoid it all costs. It's the easy way out for the moment, but once you start going down that road, you're going to end up with a stylesheet that's terrible to manage.
Set your styles for a specific base and use classes and more specific selectors as overrides. Remember that stylesheets cascade.
For example, say you have a typical header font color that should be your .header. If you have other one-off or unique headers that share same structure provide another class to that which makes sense to you.
So as an example:
Both headers have the .header styles but headers with the special class have blue text color which overrides red.
.header {
color: red;
width: 100%;
display: block;
background-color: #eee;
padding: 10px;
margin: 2px;
}
.header.special {
color: blue;
}
<div class="header">Regular Header</div>
<div class="special header">Special Header</div>

Modifying BEM classes with Sass #extend

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>

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