Changes to CSS naming standards

Im just reviewing our CSS naming standards. I’m going to be proposing some changes. I would like some feedback here.

Currently our CSS naming standards are non-standard with industry conventions.

I’ll keep this to the point:

  1. Adopting standard BEM

  2. Removing atomic class modifiers (but keeping atomic classes). IMO these are largely useless.
    for eg. has-font-size-5__sm is confusing. Font size should not be this granular in a design. Most defined font size names will have 2 different sizes (at the most 3) based on screen width. These sizes should just be set using media queries on the base atomic class for example:

    .is-font-size-sm {
         font-size: 1rem;
    
         @media screen and (min-width: 70rem) {
              font-size: 1.3rem
         }
          ...
    }
    
  3. merging class modifiers and atomic classes. The M in BEM means modifier so that’s confusing. We can just merge all the is-* and has-* into is-*. They should basically be used when blocks or elements use a global style (ie font-size, color, background-color) so on.

.is-color-black makes sense .is-hidden also does but .is-disabled does not as a disabled element requires different style rules depending on the element. (form.is-disabled requires totally different styles to input.is-disabled). We should use BEM modifier in this instance .form--disabled.

This will give us the best flexibility in terms of clear BEM standards and also reducing the amount of duplicated styles that BEM can sometimes create if its used without global element modifiers.

Thoughts?

4 Likes

First Point

Disagreeing.

This was already proposed by ArtOfCode here:

And the responses were quite unanimously against using standard BEM. Coincidentally the three likes on Art’s post are by the users who then write dissenting opinions, so we shouldn’t take it as “affirmative votes”.

I’m just linking to my previous arguments to prevent duplication of them, but I am opposing this for multiple reasons:

Second Point

Mostly agreeing.

I think this is okay, for example there is no (0) use of them in Co-Design for them right now. However, what for example about things like having a border on the top on small and on the right on large screens (for examples a container that is distinguished from others with a border)?

Third Point

Disagreeing.

Modifiers and Atomic Classes are IMO inherently different. Atomic Classes allow you to control one specific design aspect (such as border, color, padding, …), whereas Modifiers allow you to select a kind of “alternative presentation” for an element, which is still 100%-ly under the CSS’s control. Setting the color to red is something different from giving a modal a backdrop. Therefore I think it is also useful to distinguish between the two types.

However I agree, that .is-disabled would be a bad Modifier in general, as it’s idea can and should be represented by semantic HTML attributes. I don’t see, though, where this was proposed (neither in the naming standards, nor in CD), so I would not use this as an example. The same could – BTW – also apply to the .is-hidden class in combination with the [hidden] attribute.

A question

I don’t quite get, what you’re trying to say with the part I highlighted. Which styles are duplicate?

3 Likes

Thanks for your input @luap42

Im failing to see the advantage of using a slightly modified version of BEM gets us.

I see that it causes more problems than solving them. Youre replacing a widely used standard with a different variation.

What does .form--input.is-selected get us vs the standard BEM of .form__input--selected other than confusing a industry standard?

My main issue with @ArtOfCode s approach is that it increases selector specificity for no reason. again im feeling to see the logic behind it. My approach is very similiar but is simpler. I’m failing to see your logic behind the strong opposition? could you try to make it a little clearer pls?

2 Likes

Also regarding

The same could – BTW – also apply to the .is-hidden class in combination with the [hidden] attribute.

Good point this was a bad example, but im referring in generalities here - not around specific use cases

I don’t quite get, what you’re trying to say with the part I highlighted. Which styles are duplicate?
Im not referencing anything to do with the existing specification -

im saying that using purely BEM can result in style repetition unnecessarily. I was describing how the use of atomic modifiers prevents this - this is not a change from the existing approach - my only suggested change is that we merge .has-* and .is-*

1 Like

Could you reference this for me please?

Okay, now I am confused. :wink:

Does BEM mean, that you have exactly ONE selector that expresses state and such for an element (.form__input--selected as ONLY selector, unless atomic helpers) [Variant 1] or does it mean that you follow this pattern to build the selectors (.form contains .form__input.form__input--selected) [Variant 2]?

[Variant 1]

The length argument is here no longer valid, but I think it feels “wrong”, because it is more complex in the (S)CSS code. For example when you want to select all form inputs, you’d need to do this:

.form__input,
.form__input--selected,
.form__input--danger,
... (possibly more if there are more states)

This seems to inflate the (S)CSS code in a way that I think is unneccessary and makes it harder to do changes. Imagine you’d need to change one class name. That’d be a lot of changes to do.

[Variant 2]

Here the line length argument and all the other arguments from the other post apply.


Numbers are answer number as done by the forum software (#1 is main post, #2 is the first answer).

#2 opposes this, for reasons of legibility, but “possibly not enough expertise”:

But when I see is-something or has-something I know what it means right off; if I see thing__something or thing–something then I can figure it out, but it’s not as obvious. In addition, I’m likely to get the wrong number of underscores/dashes (I just did this not five minutes ago when writing some Stylus customization elsewhere), and if we mix dashes and underscores we’re probably inviting confusion. (When do we use which? Will everybody get that right?)

#3 opposes this reasons of legibility and usage of other languages, but “no strong feelings”:

’m not a fan of full BEM / thing__something either. I think button is-icon-only is more readable than button__icon-only .

This is likely because I’m often in CSS and JS at the same time, and even C or PHP on top of that. I don’t think I’ve ever spent an entire day coding only in CSS. The relevance is that the use of underscores in other languages have different meanings, depending on context, project, language, and standards.

Personally, I’ve found that I have to reread underscores in CSS when switching contexts. It takes a second or so - not much - but rinse and repeat 100x a day and I’m losing my mind.

#4 is my post, which I linked above.

Thanks for the detailed reply @luap42

Okay so basically variant 1. but your wrong about the complexity of html.

you only need

.form__input, .form *[class*="form__input--"] {
     ...
}

to select all form input elements.

In sass this is more likely to look like

.form {
    &__input {
        ... // styles for non modified input

         &--selected {
             // styles for a selected input
         }
    }

    // you could separate these for flexibility or just use a comma and join or both!

    *[class*="form__input--"] {
        ... // styles for all form inputs that have a modifier
    }
}

Its also important to remember that there aren’t too many cases where an element in BEM is required.

According to BEM, an element is only applicable when its context is solely dependent upon its ancestor. So, in your example an input is correct BEM. An input without a form doesn’t make sense however .input__icon is not correct BEM as an icon is independant of an icon. this should be .input .icon this is a block within a block.

ergo, most usecases of .form.form--selected is not really any different than .form.is-selected but regardless, with the previous selector this point doesnt really matter anyway.

I personally think this is a robust approach and is used and adopted widely for a reason…

1 Like

@ArtOfCode @Marc.2377 would love your input on this. My main thinking around this proposal is to make our project conform with a standard contributors are going to expect on the FE.
IMO this is a lower bar to grok than our current naming standards.

If we change it then we change it now otherwise we are sticking with this for everything.

2 Likes

I certainly agree with point #2 right away. Unable to give an informed opinion on items 1,3 at this moment. Doing research. Will probably DM you again about this. Full statement to follow.

1 Like

My opinion is much the same as it was when I posted the thread @luap42 linked to. I’d prefer BEM, for much the same reasons as you: it’s standardized, I personally find it clearer, and it’s easier for new folks.

However - keep in mind that whatever we use, it’ll need to be acceptable to the folks we actually want to contribute to front-end - it’s no use saying “this way is Right ™ so we must use it” if all your developers actually want X other way that works better for them. (That’s not what you’re doing, at all, but worth bearing in mind.)

1 Like

1: Agreed, although I think this might be better off as a modified version to suit our needs & ideally use the parent selector where applicable.
2 & 3 I also agree with. That being said however (as i mentioned in discord), i think we would be wise to make use of the relevant html attributes that already exist E.G. using [disabled] over .form–disabled

3 Likes

Thanks for your input @kieran, yes I totally agree regarding attributes.

@luap42 any thoughts on this?

I think the next question is: what next? @Marc.2377 would think your input here would be critical.

I still got to re-evaluate some of our conversation on Discord DM, but am pretty much AFK today. My input shall come tomorrow! But if @kieran agrees and so does the frontend team in general, don’t let me block you :slight_smile:

Ok - after careful evaluation of all points here and our existing codebases, plus listening to opinions and experience from a sample of frontend devs, I’ve come to agree with the proposed modifications here, in full.


Personally, I don’t particularly hold BEM in high regard. This post from Software Engineering SE contains a list of tradeoffs between BEM and classic CSS (which we had been following in the landing-page repo up until the live/2020-01-07T2316Z tag). That said, in terms of standard BEM vs our currently-adopted modified methodology, I certainly favor conformance to the standards and hence @mattjbrent and @kieran have my go-ahead to implement the necessary modifications to the documentation and codebase(s).

2 Likes