• Jim SilvermanJim Silverman, over 5 years ago (edited over 5 years ago )

    can't help but disagree to all of this. nested CSS only gets unwieldy if you run away willy-nilly with the nesting/specificity. reasonably-written nested CSS is very orderly, as @Jeff demonstrated.

    interesting that you bring up bloat. i find BEM to lead to exactly that. inevitably, you'll have a huge series of one-off classes used for very specific situations (or not at all) when in many cases any class is unnecessary.

    further, it leads to very ugly and bloated HTML this is an example from Smashing Magazine: (source: http://www.smashingmagazine.com/a-new-front-end-methodology-bem-blocks-reiteration/) <div class="menu"> <ul class="menu__layout"> <li class="menu__layout-unit"> <div class="menu__item">Index</div> </li> <li class="menu__layout-unit"> <div class="menu__item menu__item_state_current">Products</div> </li> <li class="menu__layout-unit"> <div class="menu__item">Contact</div> </li> </ul> </div>

    ignoring the weird use of divs, nothing beyond ".menu" actually needs a class. nesting ".menu ul", ".menu li" etc. provides the modularity and reusability needed without adding complexity or introducing one-off classes.

    1 point
    • Colm TuiteColm Tuite, over 5 years ago (edited over 5 years ago )

      So what happens if I want to apply the same styling to an <ol>? You think it's smart to just duplicate the entire CSS block?

      What happens when we want to apply that exact same styling to another list that's not a "menu"? You think it's smart to just duplicate the entire CSS block?

      Let's say we're styling a <div> and its children/descendants via nested CSS. What happens when someone realises the <div> should be an <article> and changes the element, breaking the styling?

      Also, for what it's worth, element type selectors are slower to parse than classes. Child selectors are even slower. Descendant selectors are slower again.

      1 point
      • Jim SilvermanJim Silverman, over 5 years ago

        What happens when we want to apply that exact same styling to another list that's not a "menu"? You think it's smart to just duplicate the entire CSS block?

        i'm not sure how BEM would solve this. all classes related to "menu" would start with "menu__" and not be able to be repurposed.

        Let's say we're styling a and its children/descendants via nested CSS. What happens when someone realises the should be an and changes the element, breaking the styling?

        fair enough.

        Also, for what it's worth, element type selectors are slower to parse than classes. Child selectors are even slower. Descendant selectors are slower again.

        ids and inline styles are the fastest, if we want to go that route. differences are trivial in most cases.

        0 points
        • Colm TuiteColm Tuite, over 5 years ago

          i'm not sure how BEM would solve this.

          It wouldn't. I'm just saying this is one of the many problems which surface when you use nesting.

          When styling a component and its child elements, you usually have 3 options:

          1. You can add a class to each element in the component (using a smart naming convention), then extend your styles to those classes.
          2. You can litter the component's html with all the classes necessary to style it.
          3. You can add a class to the parent and style all its children via nested CSS on element type selectors.

          I never, ever use option 3. It's by far the worst of the 3 options. I go back and forth between options 1 and 2, depending on the complexity of the component; if I think the html is getting too messy, I transfer it into a component.

          The goal is to end up with highly reusable styles, form separated from function and the ability the edit the html without breaking any styling. Nesting CSS simply cannot accomplish this.

          0 points
        • Hamish TaplinHamish Taplin, over 5 years ago

          With regards the first issue, the point is that you're tying your CSS to the elements you've used and, even worse, their structure. This isn't re-usable without changing the CSS every time you want to use those styles elsewhere and doesn't follow the principle of separation of concerns.

          For example, you may wish to use divs instead of a ul — you then have to add an additional rule to your CSS which add complexity. What happens if you, further down the line, want to style some spans in the same way? Again, another rule. If you just use classes your separating the style from your markup where .menu and .menu__item can be used with any markup.

          I can understand why the syntax of BEM puts people off—I was the same at first. However, I tried it on a few projects and I would never go back. It solves so many problems with specificity and increases modularity so much that it become really obvious once you start using it. You don't even have to use BEM syntax—just the principle of OOCSS is enough (eg. the way Bootstrap is written).

          1 point
          • Jim SilvermanJim Silverman, over 5 years ago

            again, problems arise when you start nesting willy-nilly. not a good idea to go more than a second level deep.

            what i'm saying is ".block element.modifier" instead of ".block__element--modifier" this results in much cleaner code in both CSS and HTML, is easy to maintain, completely modular and is barely tied to structure.

            it seems the only tangible advantage of BEM is, as you've stated, the freedom to change html elements used. though i've rarely had a need for that.

            1 point
            • Hamish TaplinHamish Taplin, over 5 years ago

              I wouldn't describe that as 'cleaner' at all as it's unnecessarily specific and inherently less re-usable. What problem does it solve?

              1 point
      • Jeff EscalanteJeff Escalante, over 5 years ago

        So I think you might have missed one of the points I was trying to make in this writeup, which is that you carefully choose at which level your css is nested based on whether it needs to be used elsewhere. Let's look at a quick example.

        Let's say you are coding up your about page, intro section. The header is a specific style, so you code this up under #about #intro, scoped as tightly as possible. Now you realize you have been so focused on this css writing that you forgot to look at the rest of the about page mock, and while moving on to the second section realize that it also has the same header style. Ah ok, so this is a page-specific style, so you move it out of #about #intro up to just be nested under #about such that it affects all headers on the about page. Cool. No breakage, no repetition.

        Now you're moving on to the contact page. Looking over these designs, you realize that you had been so focused on cranking out the about page that you didn't realize the headers are the same style on the contact page too. Come to think of it, they are the same across the whole site. No problem -- head back to your about page styles, pull it out of the #about scope, and make it global. No duplication, no breakage. I hope this example puts it in context a bit better. This is also a worst case scenario as far as movement of the styles. If this hypothetical developer had taken a few minutes to just look over the design mocks before starting to code, they would have probably had a better idea of what styles are global, page-specific, and module-specific so that they could place them there from the start instead of having all these realizations and having to move them.

        If you change the element and/or class name you should expect the styles to break, I feel like this is fairly universal. I could say the same about bem "what happens when you have a li and you change the class on it then break the styling with bem where without it you would have just selected the li itself with descendant selectors and the styles wouldnt break?" This is a silly argument though, there's no system in which changing the names/attributes of elements in some way can't break the styles. Every developer knows this and should not be surprised when they have to go adjust the css accordingly after changing elements or class names.

        As for the speed concern, I honestly would not be shocked at all if the increase in latency through the http request due to the increased number of characters in your html because there are so many verbose classes outweighed the performance hit you take by using descendant selectors. We're talking about < 100ms differences here -- if you are really that hard-line on performance, the first place you should be looking is your javascript, CDNs, etc, not making your css more verbose and difficult to manage in order to squeeze out an extra couple thousandths of a second.

        1 point
        • Colm TuiteColm Tuite, over 5 years ago (edited over 5 years ago )

          The header is a specific style

          There is no such thing as a "specific style". Every single line of CSS in any project is being reused elsewhere in that project. Whether it's a background color, font size or a display declaration, all CSS should be reusable.

          Now you realize you forgot to look at the rest of the mock.

          Your entire argument is based upon a series of delayed realisations. This is not something that would ever happen to me, or any other remotely competent developer. In any case, designs change over time and so too does CSS. So regardless of how careful you are, you will run into issues eventually. It's inevitable.

          If you change the element name you should expect the styles to break.

          No, you should not.

          There's no system in which changing the names of elements in some way can't break the styles.

          There are many such systems.

          0 points
          • Jeff EscalanteJeff Escalante, over 5 years ago

            Every single line of CSS in any project is being reused elsewhere in that project

            Haha wut? I have built quite a number of websites, and I cannot think of a single one in which every single style written anywhere on the website was also re-used elsewhere. Maybe this would be the case for a very generic template site, but not for any real production build.

            Your entire argument is based upon a series of delayed realisations.

            Apparently you didn't read the rest of the comment where I discussed this exact point. Take another read perhaps?

            No, you should not. There are many such systems.

            So if I change the class names on an element using BEM, everything will be ok, no styles will break? Wut? And for the 'many such systems', please tell me more about some of them. We're talking about a system in which you can select an element by an attribute, but when that attribute changes, the selection still holds. This defies all logic, and can be nothing other than pure magic.

            Actually, I think we've got to the point here where this conversation is over. Once comments start being made that make absolutely zero sense and are not backed by any rational thought or examples, it's usually time to call it quits. Let me leave anyone reading with this -- everyone has their own style and can do whatever they like best, of course. Just make sure to step back and really think through your decisions from an unbiased viewpoint, uninfluenced by popularity or hype, to make sure your decision-making process was clear. It isn't always, I've certainly been in that position myself many times, and so has everyone else. Here's to making awesome things : )

            And thank you for arguing against me here, I asked for it, you delivered, and I really do appreciate it. Opposing viewpoints give a lot of perspective, and help to broaden your perspective.

            0 points
          • Jim SilvermanJim Silverman, over 5 years ago

            Every single line of CSS in any project is being reused elsewhere in that project. Whether it's a background color, font size or a display declaration, all CSS should be reusable.

            i can't imagine how that's true with BEM. all classes are specific to a block component.

            0 points
            • Colm TuiteColm Tuite, over 5 years ago

              Most (wild guess about 90%) of what I write inside my component blocks is Sass extends. So nothing is specific to any block component. In fact, as I mentioned above, nothing is specific to anything.

              CSS styles should be written once, in abstracted, reusable objects - then either applied directly to elements (via classes) or extended to components. Either option is fine and both have their pros and cons, but no style is specific to anything.

              1 point
            • Hamish TaplinHamish Taplin, over 5 years ago (edited over 5 years ago )

              This isn't true. Only the classes that deal with that block and it's components styling are tied—you will mix those with with other components though and even just regular old cascading. This is probably the hardest part as you're essentially creating abstractions which takes a bit of planning but is worth it in the end.

              0 points
            • Colm TuiteColm Tuite, over 5 years ago

              I made a simple example to help explain what I mean.

              0 points
              • Jim SilvermanJim Silverman, over 5 years ago

                i'd prefer font size as a variable, not a class. otherwise we're just abstracting inline styles. to each his own, i guess.

                0 points
                • Colm TuiteColm Tuite, over 5 years ago (edited over 5 years ago )

                  Here's a slightly more involved example which explains the approach a bit better.

                  It showcases two acceptable approaches to styling a button, using 3 abstracted, reusable styles.

                  0 points
                  • Jim SilvermanJim Silverman, over 5 years ago

                    i assume you meant to write ''?

                    not sure what you're saving with '.displayInlineBlock' as it's class name is so specific -- it's essentially an inline style. also '.fs1' becomes a poor name once you add a rule besides 'font-size' to it. '.bgPrimary' has a text color in it, but is labelled bg?

                    regardless, this doesn't have anything to do with BEM. there's no "block" in any of the class names.

                    0 points
                    • Colm TuiteColm Tuite, over 5 years ago

                      it's essentially an inline style

                      This is a common argument, which holds no weight. Writing this declaration hundreds of times across a project as an inline style, is in no way shape or form the same as writing it once, as an abstracted, reusable class.

                      '.fs1' becomes a poor name once you add a rule besides 'font-size' to it.

                      So don't add anything that makes it not reusable. Usually, the only other property I add to my font size declarations is line-height.

                      '.bgPrimary' has a text color in it, but is labelled bg?

                      Yeah, because anytime I see that coral color, I want the text on it to be white. This may not hold true in other projects, but it's an example of how I've declared "coral background and white text" as a reusable style that I can apply to buttons, landing page sections etc.

                      regardless, this doesn't have anything to do with BEM

                      True. But BEM is just a naming convention. It's not that interesting or important imo. Understanding the need for tiny, abstracted, reusable CSS objects is much more important.

                      0 points
        • Hamish TaplinHamish Taplin, over 5 years ago

          I used to write CSS like this and it's an absolute nightmare to maintain. As soon as you need to change something or re-use some styles further down the line you have to re-factor your CSS to accommodate the fact that things have changed.

          you carefully choose at which level your css is nested based on whether it needs to be used elsewhere

          What happens six months down the line when you need to add some new stuff that re-uses existing components? You've got to refactor. This is especially problematic if you've used IDs or descendant selectors as you have to rewrite the original selectors to accommodate the new styling. If you just use classes in the first place, you're not tying your style to your structure and it's way more re-usable, takes less re-factoring and you end up with CSS that isn't too specific (which is a maintainability nightmare in itself).

          what happens when you have a li and you change the class on it then break the styling with bem where without it you would have just selected the li itself with descendant selectors and the styles wouldnt break?

          The point is that, with BEM (and OOCSS in general) the classes only exist for specific styling purposes in the first place. You would only change a class in order to change the styling. With descendant selectors, you might change the structure of the HTML for any number of reasons not least simple re-using something elsewhere.

          Furthermore, using ids/descendant selectors makes writing heavily modular/styleguide type front-ends impossible. There's a reason why Bootstrap and Foundation use OOCSS. I thought they were bloated until I started working on projects that necessitate being heavily modular and OOCSS is a godsend for that type of work.

          I really would try it if you haven't already :)

          1 point
          • Jeff EscalanteJeff Escalante, 5 years ago

            If you are writing something that is 'heavily modular', you would just use a lot of globals, which are just classes, and end up with a similar approach, if I'm not mistaken. You just also get more specific scoping when it's needed.

            0 points
            • Hamish TaplinHamish Taplin, 5 years ago

              This is exactly the point—everything should be made 'global' as you put it because, potentially everything should be re-usable as easily as possible. If you tie stuff to 'pages' it isn't re-usable without refactoring. If you tie things to the structure of some markup it isn't re-usable in a different (markup) context.

              In your post you mention "semantics"—adding classes to HTML makes it more semantic, not less. Screenreaders and search engines don't care about classed/ids in your code but developers do. This is the whole point of classes, they are hooks to be used for styling so the more you use them, the more flexible your code is.

              If you haven't already, I would recommend reading these posts regarding semantics and OOCSS:

              http://www.stubbornella.org/content/2011/04/28/our-best-practices-are-killing-us/

              http://nicolasgallagher.com/about-html-semantics-front-end-architecture/

              1 point
              • Jeff EscalanteJeff Escalante, 5 years ago

                everything should be made 'global' as you put it because, potentially everything should be re-usable as easily as possible.

                Ah right so I think that is where we diverge. I don't like to use time or complexity prematurely optimizing things. This is a relatively popular opinion in programming in general called YAGNI (read more here: http://en.wikipedia.org/wiki/You_aren't_gonna_need_it) -- another related one is KISS (http://en.wikipedia.org/wiki/KISS_Principle). If you google either of these there are tons of supporting posts, and this has without a doubt made things easier for me in my work numerous times in the past.

                The approach you advocate is sacrificing the DRY-ness and readability of your html and css in order to prematurely optimize the re-use of every single style block on the entire site. I'd rather build out the styles as they originally were specified in the design mock, with the cleanest and most readable markup possible, and if a change comes in later that re-uses a style that was not previously used anywhere else, consciously bump up the scope of that style as needed.

                0 points
                • Hamish TaplinHamish Taplin, 5 years ago (edited 5 years ago )

                  I have no idea how BEM sacrifices DRYness—it does the exact opposite, in fact. You write block styling once, independent of markup, and then re-use it whenever you need it regardless of the structure of your markup or where it is contained. Having several selectors to re-use styling in 3 different places sacrifices DRYness. Having to refactor you CSS (and your HTML) because 3 months down the line a component you deemed to be in the scope of a 'page' now needs to be 'global' because the client wants a new section and your new mocks re-use a bit of an existing page in a completely new place on a new page but with slightly different styling because you drew the line of 'you might not need it' in the wrong place. ;)

                  Your posts seem to assume that BEM makes things more complicated. It doesn't — it makes things simpler in the right place (your CSS) offloading the complexity to the bit where it's easier to manage (your markup). Sass negates some of this via @include and the much-abused @extend but it can get out of hand very easily. I'm all for keeping things simple and OOCSS does this. If you're just getting hung up on the (initially ugly) syntax then you're priorities are probably misaligned. When you get used to the syntax it's more readable. To quote Harry Roberts:

                  The point of BEM is to tell other developers more about what a piece of markup is doing from its name alone. By reading some HTML with some classes in, you can see how – if at all – the chunks are related; something might just be a component, something might be a child, or element, of that component, and something might be a variation or modifier of that component.

                  (from http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)

                  Again regarding 'premature optimisation' or 'KISS', you could make the exact same argument about not writing object-oriented Javascript when just chucking some jQuery together in one file can suffice. The same can be said about PHP—why write that in an OO style when you can just go procedural and chuck all your logic in your templates. It's easier but is it really a good idea? Sometimes yes, often no—YMMV.

                  Again, I would recommend actually trying BEM (or even just plain old OOCSS) on a project before you make assumptions about things like DRYness. :)

                  To each his own though, you're clearly happy with the way you do things so why question it?

                  http://vimeo.com/44773888

                  0 points
                  • Jeff EscalanteJeff Escalante, 5 years ago

                    I have no idea how BEM sacrifices DRYness

                    li.menu__item li.menu__item-selected li.menu__item-selected-whatever-else

                    See any repetition here? And don't even make me bring up how the html looks haha.

                    you drew the line of 'you might not need it' in the wrong place

                    Not the right mindset. You draw the lines based on "need it" or "don't need it" -- YAGNI. "Might" is not even a thought. If you need it later, you take the style block and move it up one scope level. It's not a disaster or a major refactor, it's simply widening the scope to the appropriate level.

                    When you get used to the syntax it's more readable

                    Haha you could say this about anything, I'm pretty sure. Not sure I'm on the train with this one.

                    you could make the exact same argument about not writing object-oriented Javascript when just chucking some jQuery together in one file can suffice

                    Absolutely! And it would be silly for you not to! If you have a small project with just a tiny bit of js interaction, setting it up with backbone or angular or some huge framework you don't actually need but might want later if changes or additions come down the line is, in my opinion, doing it wrong. You add things when you need them, not when you might possibly need them eventually.

                    before you make assumptions about things like DRYness

                    These are not assumptions, these are facts. There is a massive amount of repetition when you write and re-write the same block name over and over for each piece within the block, rather than nesting. I gave an example in the writeup I originally posted of exactly this. There really is no argument about it, bem is more verbose and involves more repetition than nesting. You can (and have) argued that the extra repetition offers more flexibility, but you can't argue that it doesn't involve a huge amount of repetition.

                    0 points