Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm inclined to semi-agree with this, although I'm not sure I'd be quite as adamant about it myself. But I do generally think that CSS is taught in a way that encourages some bad practice around cascade/inheritance. I will point out though that (at least in my experience), BEM solved the majority of these problems for me even without a preprocessor. The language is definitely oriented towards inheritance/cascade, but I think there are ways to avoid it.

There's some movement towards ::part as a proposal to grant some mixin behaviors (https://developer.mozilla.org/en-US/docs/Web/CSS/::part) but I've never messed with it, and it's applicable only to shadow DOM. But mixins haven't been a huge issue for me in even enterprise-scale styling that I've done.

Opinion me, everyone has their own opinions on this, use whatever CSS style works for you. This is not me saying that BEM is the best for everyone, just giving a perspective that as someone who tends to stick to vanilla CSS and who generally kind of hates working with technologies like Tailwind or CSS-in-JS, BEM-style vanilla CSS made CSS pretty pleasant for me to work with; I have a lot more appreciation for the language now than I used to.

So if you're annoyed by CSS but also get annoyed by pre-processors or think that Tailwind is just inline CSS under a different name[0], you still don't need to be bound to the cascade -- potentially look into BEM. No technology or compilation or dependencies, it's literally just a naming convention and style guide.

----

[0]: yes, I have used it extensively, please don't comment that if I used it more something would magically click, I already understand the points in its favor that you're going to comment and I've already heard the style/framework suggestions you're going to offer. It's fine if you like Tailwind, it's great if it helps you write CSS, you don't need to convince me.



> But I do generally think that CSS is taught in a way that encourages some bad practice around cascade/inheritance. I will point out though that (at least in my experience), BEM solved the majority of these problems for me even without a preprocessor.

I think cascading is just a bad default, and I think methodologies like BEM agrees with this by teaching you ways to write CSS in ways that stops cascading from getting in the way.

Cascading styles are fine for styling how basic document content is shown (e.g. h2, p, a, li etc. tags) but outside of this, you generally don't want the styles of parent elements leaking into the styles of child elements. Cascading/inheritance styles is a useful tool to have, but not as the default.

I'm not saying Tailwind is perfect, but it's closer to "prefer composition over inheritance", where you can sprinkle in some cascading/inheritance where it makes sense.


> I think cascading is just a bad default

I'm again semi-inclined to agree, I just don't think I'd say it as forcefully; more that cascading styles tends to have a lot of downsides that people aren't familiar with and aren't taught.

My point isn't to badmouth Tailwind here; but debates about this sometimes boil down to "CSS purists" vs "Tailwind advocates" and my point is more -- nah, you don't have to like Tailwind to avoid the cascade. You can be a CSS purist and still avoid basic element selectors, your choice does not have to be either "do semantic styling targeting only semantic elements" or "jump on Tailwind and stick a bunch of styles inline."

I'm more sticking up for -- look, if you're someone who uses Tailwind, great, I don't have to tell you anything. You are already using a framework that (regardless of any other flaws it may or may not have) discourages you from using the cascade. But if you're someone who's in the position where you dislike CSS-in-JS or don't like using Tailwind, also great! I'm in that position too, I don't like Tailwind. But I still avoid cascade and basic element selectors and there are ways to basically eliminate most cascading styles from your codebase and eliminate most cascade-caused bugs even if you aren't going to use a pre-processor at all, and it's good to at least consider removing those cascading styles.

My only critique of Tailwind I would bring here is that sometimes I get the feeling that Tailwind advocates think that Tailwind invented this idea of component-based CSS, and it really didn't. But that's neither here nor there, and if someone is using Tailwind and it works for them, great. Life is way too short for me to argue with someone using a technology that they enjoy. Honestly, same with the cascade -- I think it can lead to long-term maintenance problems, but if you like it, fine.

However, if you're using CSS and hate it, and you also don't want to use Tailwind, then give BEM a try.


But BEM doesn't interact with the cascade. If you have two BEM selectors (or a BEM selector and non-BEM selector) that match an element and set the same property, the cascade algorithm still applies to determine what to set the property to.


Sure, but the idea with BEM is that you generally don't have situations where the result of that algorithm is confusing or unexpected. Or at least that's been my experience, even on large codebases. I generally don't run into situations where styles overload each other in weird ways when I'm using BEM (others' experiences might vary).

You could throw the same criticism at Tailwind -- Tailwind can still expose you to cascade issues, not all Tailwind classes are single-level selectors under the hood and not all Tailwind classes only target one property. At the end of the day this is all compiling down to raw CSS, so in neither situation have you actually eliminated the cascade. But with both BEM and Tailwind you are much less likely to see those situations, and when they do arise they are less likely to introduce long-term maintenance problems and are more likely to be easy to address/encapsulate. If you run into cascade bugs with Tailwind, it's probably something you fix in like one file, instead of needing to search through five.

BEM doesn't technically interact with anything, it's just a style of writing CSS. There's literally no technology behind it, it is just a naming convention. But in practice, using a naming convention mitigates or eliminates a large number of cascade issues.


Do you have a CSS component framework that you can recommend for use with BEM?


I could link you to a few (I think Bootstrap adopted BEM at some point, Material Design Lite I think uses a variant of it), but I can't recommend them with confidence because generally I don't use extensive style frameworks when I work on large applications. I feel like CSS frameworks are largely useful for bootstrapping projects and for keeping control of large projects where styling starts to break down. A lot of projects I work on are past the point where I need the bootstrapping help, and BEM itself helps me keep control of the CSS code as the projects grow so I don't need to have a strict framework to help me organize everything.

----

In general though, I would actually suggest that you can kind of use anything if you're not planning on forking the component library. Most of these 3rd-party libraries you're not going to be restyling, so long-term maintenance and scalability isn't really a concern, you're never touching that code.

And BEM is just a naming convention, so if you're pulling in a React component and it has a hook for you to attach your own classes, then attach a BEM-style class, otherwise pass in the styling information into the props the way that most JS components want. I've used BEM with React components, with Material design, with Angular components, etc... I don't know, I haven't really run into issues. I've even worked on a codebase that was a mixture of BEM CSS, 3rd-party CSS, and Tailwind. It was fine, I didn't notice any major issues. Typically 3rd-party component dependencies are not a major source of cascade bugs in my experience, but maybe I've just been lucky. Most components I've seen lock down their styles to the point where it's kind of a pain to even try to override them with CSS, and the specificity required to do so forces you to effectively isolate those overrides anyway.

Whatever component framework you're using will have its own customization API, and in my experience that usually won't be handled through CSS. If it is handled through CSS, it will probably be handled by attaching classes, and then when you attach those classes you can use BEM. The major annoyance in my experience is that (for me) BEM often works better than whatever customization system that the 3rd-party components is using and I get frustrated that I'm mixing more straightforward CSS that's easier to debug and design in-browser in with whatever property-based thing that the components expose. But I don't usually think I run into many bugs?

What BEM helps with is dealing with cascade, code organization, naming, and debugging/search. With a 3rd-party component framework, most of that stuff is out of your control, so just use whatever the framework wants and then use BEM for the stuff that is in your control.

If you have to do some kind of CSS-based override of a 3rd-party component that isn't being handled through a component-specific API, wrap it in a BEM-style class for your actual component so that it's a one-time customization:

  .Input__Username .some_component_depencency input {
      /* This is not ideal, but (imo) you'll still effectively never really see cascade bugs from doing it this way, and specificity will rarely be a concern. */
   }
One thing that is nice about BEM is that because your own CSS is being scoped to specific named components, it actually becomes a bit easier to have a lot of 1st-party CSS living alongside 3rd-party CSS and know that your CSS is not going to break the 3rd-party CSS. So I tend to worry a lot less about what other parts of the code/dependencies are using when I'm using BEM, because I more confident while writing BEM that I'm not introducing bugs into the other CSS.


That was really helpful and cleared up some notions I had. Thanks




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: