Can we make an element of block modifier in BEM? - html

I just wanted to know whether the following code follows BEM methodology best practices? Creating an element for the block modifier i.e. in this case "block--mod" is a modifier for the "block" block. Is it allowed to create a nested element with this pattern: "block--mod__elm".
<div class="block block--mod">
<div class="block__elm block--mod__elm">
</div>

In situations like theming or similar I would use nested selectors. This saves some classes in your HTML and as #Jonathan Nicol said those sub-elements can be hard to follow. Also it will be easier to remove the "branding" later, just remove block class instead of all it's elements.
For example Xmas branding of your header.
.header--xmas .header__logo {
/* Jingle bells, jingle bells, jingle all the way.*/
}
Source: http://getbem.com/faq/#can-a-block-modifier-affect-elements-

I could not find an example of a the .block--mod__elem pattern in Yandex's BEM documentation (Yandex devised the BEM methodology), but an early article about BEM on CSS Wizardry does show an example of a modifier with a sub-element, .person--female__hand:
.person {}
.person__hand {}
.person--female {}
.person--female__hand {}
.person__hand--left {}
Source: MindBEMding – getting your head ’round BEM syntax
Modifiers with sub-elements can be a little hard to follow, but I do not shy away using from them if it seems like the logical approach.
Edit: #NikolayMihaylov's answer gives an alternative approach that I wholeheartedly support. It is more readable and more maintainable.

Related

Is BEVM valid or we can use modifier alone?

Chainable BEM modifiers
And I want to apply this idea to my next project but when I get the check on getbem.com, It says is bad when use modifier alone
Good
<div class="block block--mod">...</div>
<div class="block block--size-big
block--shadow-yes">...</div>
Bad
<div class="block--mod">...</div>
meanwhile, in BEVM idea, we can use modifier alone in an element.
Does anyone have a suggestion?
BEM is against modifiers without block class itself. They are to modify something existing.
There can be quite a lot of different modifiers on a block at the same time (we need to avoid repetition of basic things in each modifier) and they can be added or removed in runtime. So there should always be the entity (block or element) to witch modifiers can be added or from which they can be removed.
For more info please refer to https://en.bem.info/methodology/faq/#how-to-make-global-modifiers-for-blocks

How to namespace OOCSS classes with competing "scopes"?

I am aware that this is asking for a very opinionated answer, as are all naming-convention related questions, I guess.
I am using Harry Roberts BEMIT naming convention, which augments BEM with prefixes/namespaces for object-oriented css.
That allows organizing classes into objects, using the o- prefix, for decoration-free design patterns like the famous media object, and styled ui-components, using the c- prefix (plus some more).
Here is the (generic) example, that is often used in the context of explaining BEM, augmented with the problematic namespaces:
.o-btn {
width: 100%;
}
And here the competing scope, targeting the same (bem)block
.c-btn {
color: white;
background: gray;
}
.c-btn--positive {
background: green;
}
.c-btn--negative {
background: red;
}
To quote the relevant part from Harry Roberts CSS Guidelines (not enough cred to post 2nd link, sorry):
Above, we can see how the .btn {} class simply provides structural styling to an element, and doesn’t concern itself with any cosmetics. We supplement the .btn {} object with a second class, such as .btn--negative {} in order to give that DOM node specific cosmetics.
This explanation to me sounds like the exact justification to do as I did.
Still, it feels incorrect, to use two different namespaces on the same block, possibly confusing.
Which namespace do I chose, if two of them are competing?
Don't be afraid of having different BEM entities on the same DOM node.
Actually pure BEM itself solves this issue with the help of mixes (see https://en.bem.info/methodology/key-concepts/#mix).
The idea is that you should keep button block as universal component with maximum reusability. Then you may add all the cosmetics with the help of theme modifier. And finally add positioning with a help of mix with parent's element (e.g. form__submit).
So you may end up with something like this:
<form class="form">
<button class="button button--theme_awesome form__submit">Send</button>
</form>
You use what your projects require, in my case I much prefer the prefixed syntax (o-, c-, u-), because you're telling to your html elements what they are, a short example using sass syntax:
.c-button{
&.c-button--dark{}
&.c-button--orange{}
}
and you can overwrite bootstrap classes, for example, you don't have to take care about other classes, with this specification you are able to overwrite the default classes you might have, and you can have a mix of css classes in your hmtl element, for example:
<input type="text" class="btn btn-primary c-button c-button-dark" />

How to select an specific element by a css class, but not other elements?

So I want to select the <div> element with the class .thisClass, but not any other elements with class of .thisClass:
<div class="thisClass"></div>
<p class="thisClass"></p>
CSS Selector by class name and tag: div.thisClass { ... }:
div.thisClass {
background-color: red;
}
<div class="thisClass">thisClass (div)</div>
<p class="thisClass">thisClass (p)</p>
But this is a bad way to write selectors:
Don’t qualify class rules with tag names
The previous concept also applies here. Though classes can be used many times on the same page, they are still more unique than a tag.
One convention you can use is to include the tag name in the class name. However, this may cost some flexibility; if design changes are made to the tag, the class names must be changed as well. (It’s best to choose strictly semantic names, as such flexibility is one of the aims of separate stylesheets.)
BAD
treecell.indented {…}
GOOD
.treecell-indented {…}
BEST
.hierarchy-deep {…}
Using JavaScript
document.querySelector('div.thisClass')
Using jQuery
$("div.thisClass")
Using CSS:
<style>
div.thisClass{}
</style>
The following code illustrates how to select the first class from the list of classes in both CSS and Javascript.
CSS
.thisClass:first-child {
/*css property*/
}
JAVASCRIPT:
var divElement = document.getElementsByClassName('thisClass')[0];

Html tagging elements with custom tags instead of using classes

Instead of using the standard class="someclass", I deviated from this pattern and "tagged" the div thus:
<html>
<head>
<style type="text/css">
div[tag1]
{
background-color:Red;
}
</style>
</head>
<body>
<div tag1>test</div>
<div>test</div>
</body>
</html>
What are the drawbacks of this approach (besides the obvious fact that it might confuse some developers)?
Will it work in any browser? (I checked FF, IE and Chrome - it worked in all of them)
To me, it looks more concise than using "class".
Thanks!
I see a few drawbacks to your approach
Specificity: All attributes in the element, with exception to the ID, are parsed as classes. By choosing to go with <div someAtt>, this is always going to have the specificity of a class: 0,0,1,0.
Selectors: You don't make shorter selectors:
The class of an element is also an attribute. You could select an element that has a class like so:
[class="tag1"]{
color:red;
}
This, in fact, is the "normal" way to select an element with an attribute which has a value. The manner in which we select classes is more of a shorthand for the above rule:
.tag1{
color:red
}
Because you're proposing a custom attribute, your selector will be:
[tag1]{
color:red
}
If you're counting characters, the "longhand" attribute selector takes the most space and the class selector the least. You're not making a stylesheet shorter with your approach. Your selector will always be longer by at least one character. Is this a huge deal? No. But it will be over time, and now you have to train someone who takes over your stylesheet on your approach.
Extensibility: Another issue with adding an invalid attribute to your markup is extensibility. Your goal should be extensible markup and CSS, so you want a pattern that's reusable. if you're going to have tag1, tag2, etc, this isn't an extensible pattern.
How do you plan on dealing with reusable styles? What you're saying is that <div tag1 tag2 tag3 tag4> could happen at some point in the future. How do you plan on styling that?
div[tag1][tag2][tag3][tag4]{
color:red;
border-color:red;
outline-color: red;
background-color: red;
}
[tag1]{
color:red
}
[tag2]{
border-color:orange
}
[tag3]{
outline-color:yellow
}
I see tag as a reusable attribute which can accept a changing value:
<div tag="one">
Which results in this selector:
[tag="one"]{
color: green
}
Which ultimately means you have replicated the "class" approach, but with a longer selector and no means to a shorthand (like the . that's the same as [class=""].
Valid Markup: The next issue I see in your approach is that you're using invalid attributes. In HTML5, you can use the data-* approach to pretty much create whatever attributes you want in a somewhat normalized pattern. But invalid attributes such as tag1 could throw off any HTML validators. Additionally, I don't know how screen readers or other accessibility devices might struggle with invalid or unknown attributes.
The Neighborly Way: The final issue that I see is more philosophical. We get a heck of a lot more freedom and flexibility in HTML and CSS than in other development languages. Web browsers are much, much more forgiving of mistakes that we make in HTML and CSS than compiled languages. We shouldn't equate the freedom to be different to the wisdom of following standards and best practices.
The only drawback I can think of is that you lock your css to a tag type. ie with class you could do:
<div class="alignRight"> Some thing </div>
<table class="alignRight">table data</table>
Your approach does not allow for this. Apart from this I don't think it's any technical issue with using your approach.

CSS Selector "(A or B) and C"?

This should be simple, but I'm having trouble finding the search terms for it.
Let's say I have this:
<div class="a c">Foo</div>
<div class="b c">Bar</div>
In CSS, how can I create a selector that matches something that matches "(.a or .b) and .c"?
I know I could do this:
.a.c,.b.c {
/* CSS stuff */
}
But, assuming I'm going to have to do this sort of logic a lot, with a variety of logical combinations, is there a better syntax?
is there a better syntax?
No. CSS' or operator (,) does not permit groupings. It's essentially the lowest-precedence logical operator in selectors, so you must use .a.c,.b.c.
Not yet, but there is the experimental :is() (formerly :matches()) pseudo-class selector that does just that:
:is(.a .b) .c {
/* style properties go here */
}
You can find more info on it here and here. Currently, most browsers support its initial version :any(), which works the same way, but will be replaced by :is(). We just have to wait a little more before using this everywhere (I surely will).
For those reading this >= 2021:
I found success using the :is() selector:
*:is(.a, .b).c{...}
If you have this:
<div class="a x">Foo</div>
<div class="b x">Bar</div>
<div class="c x">Baz</div>
And you only want to select the elements which have .x and (.a or .b), you could write:
.x:not(.c) { ... }
but that's convenient only when you have three "sub-classes" and you want to select two of them.
Selecting only one sub-class (for instance .a): .a.x
Selecting two sub-classes (for instance .a and .b): .x:not(.c)
Selecting all three sub-classes: .x
No. Standard CSS does not provide the kind of thing you're looking for.
However, you might want to look into LESS and SASS.
These are two projects which aim to extend default CSS syntax by introducing additional features, including variables, nested rules, and other enhancements.
They allow you to write much more structured CSS code, and either of them will almost certainly solve your particular use case.
Of course, none of the browsers support their extended syntax (especially since the two projects each have different syntax and features), but what they do is provide a "compiler" which converts your LESS or SASS code into standard CSS, which you can then deploy on your site.