Open scottgonzalez opened 10 years ago
I released a small, basic demo of the kind of architecture I named Atomic Blueprint CSS Design (ABCD). I intend to use it myself for Cascade Framework 2 and would recommend a similar architecture for this project.
@jslegers looking at your demo ( and correct me if im wrong about any of this ) it seems like your css is completely tied to the markup used, nearly every rule contains an element type.
This seems like it would be less then ideal because it forces the use of certain element types and makes the markup not very flexible. This is something that came up during the call and it seemed like the consensus was that we want to specify actual element types as little as possible to keep things as flexible as possible.
In addition element selectors are slower then class selectors.
I personally prefer an OOCSS naming convention, although I like the architecture organization of SMACSS.
@arschmitz :
This seems like it would be less then ideal because it forces the use of certain element types and makes the markup not very flexible.
Quite the contrary.
This is how it works :
All primitives, elements and components are defined as placeholders. This has the following advantage :
In my demo code, I used only element level selectors and selectors based on semantic classes as this results on both the least HTML bloat and the least CSS bloat. And while element selectors may not be the fastest selectors, I doubt any performance overhead caused by using element level selectors is greater than the overhead one would have if using classes or ids instead.
See also The Semantic Grid System, which was my main inspiration for seperating CSS naming conventions and SCSS naming conventions.
I prefer an OOCSS convention as well. This really resonates with me: http://cssguidelin.es/#naming-conventions
@sfrisk & @cbracco :
OOCSS and SMACSS are two variations of a design pattern, also known as atomic design.
OOCSS doesn't require any specific naming conventions. For example, consider the following projects :
These projects are all OOCSS frameworks, but they all use different naming conventions and implement different components.
Also, note the distinction between SCSS placeholder naming conventions and CSS selector naming conventions. It is perfectly feasible and reasonable to do something like this :
EDIT ( @arschmitz ): Moved large code sample to gist for better issue readability https://gist.github.com/arschmitz/79460c29bef313280d62
What I meant by my last comment was that I prefer both OOCSS and the naming conventions laid out by Harry.
Oops, sorry, didn't mean to put naming after OOCSS. Or well, I did, but more in the 'naming classes to be as generic as possible, therefore most reusable' sort of idea.
I like most of the naming ideas listed in Harry's article (http://cssguidelin.es/#naming-conventions), although I will admit, when I start seeing double '--' and double '' on css classes it does make me go a little cross eyed. That being said, looking through the documentation, the use of the '--' and '' does make sense, so if the majority like that, I'm willing to go with it. Who knows, maybe it will grow on me. :-)
I guess the thing I always like to see is a clear visual distinction between an object / block / element class and a modifier / utility class, so I can get a rough idea of what class is doing what at a glance. So I'm cool with whatever convention that can help us achieve that.
@cbracco & @sfrisk :
What I meant by my last comment was that I prefer both OOCSS and the naming conventions laid out by Harry.
Can I assume that you're refering to BEM? As Harry pointed out himself in his January 2013 article, BEM syntax was actually conceived by Russian Internet company Yandex. If I'm not mistaking, Yandex's April 2012 article in Smashing Magazine was the first time BEM was mentioned in a major web resource.
I believe BEM to be very loosely inspired by Maxim Vetrenko's CSS framework Marxmertkit, which is relatively unknown in North-America and Western-Europe but does appear to have achieved some popularity in Eastern Europe. So yes, we owe it all to the Russians!!
Oops, sorry, didn't mean to put naming after OOCSS. Or well, I did, but more in the 'naming classes to be as generic as possible, therefore most reusable' sort of idea.
IMO OOCSS / SMACSS / atomic design is not so much a matter of how you name your components, but rather a matter of defining your components as abstractly as possible, and then using modifiers to add more specific features to them. For example, you first define a very generic "navigation" component and then add modifiers to refine how your navigation behaves and what it looks like. See Cascade Framework's navigation component and my generic navigation demo for two different implementations of a generic navigation component.
I guess the thing I always like to see is a clear visual distinction between an object / block / element class and a modifier / utility class, so I can get a rough idea of what class is doing what at a glance. So I'm cool with whatever convention that can help us achieve that.
I think we can all agree on OOCSS / SMACSS / atomic design as thé design pattern to use. The issue here is mostly whether BEM or a BEM-like syntax is suitable for (1) SCSS placeholders and (2) CSS selectors. I tend to agree with the former but not with the latter.
although I will admit, when I start seeing double '--' and double '' on css classes it does make me go a little cross eyed. That being said, looking through the documentation, the use of the '--' and '' does make sense, so if the majority like that, I'm willing to go with it.
If you use the technique I described in my previous comment, you get the best of both worlds. You use a standardized BEM syntax (or a variation thereof) at the level of SCSS placeholders, but you use a fully custom semantic syntax at the level of CSS selectors. That means you get (1) less bloat, (2) no ugly '--' in your CSS and (3) several other advantages.
It also allows the end user to choose whether or not to take advantage of the cascade. IMO, a huge downside of BEM syntax in CSS is the overly specific nature of BEM naming conventions, which disables many of the advantages you get from using OOCSS / SMACSS / atomic design.
By making your CSS selectors independent of your SCSS placeholders (as in my Atomic Blueprint CSS Design demo and The Semantic Grid System), you get all the advantages of BEM syntax at the SCSS level without being forced to restrict the cascade by making your CSS selectors overly specific as well. You can, however, still use BEM-named classes or id's in your HTML and CSS if this is what you want/need for your project.
One big thing to consider here is performance as well not just semantics and flexibility. Cascading selectors and especially tag based cascading selectors can come with some real performance hits. Before we go too far here we should wait on the perf suite https://github.com/jquery/css-framework/issues/2 . Personally I think performance should be one of our biggest if not our biggest concern here.
@arschmitz :
First of all, note that element based selectors are only marginally less performant than class based selectors. Also, note that class based descendant selectors and child selectors tend to be slower than element based selectors.
Here's Steve Sounders's original performance comparison most people tend to refer to when comparing selector performance :
Yes, semantics and flexibility are important. And yes, performance is also important. However, performance involves (1) filesize, (2) number of HTTP requests, (3) server speed, (4) traffic, (5) kind of browser, (6) kind of device, etc. I haven't done any benchmarks myself yet, but I'm pretty confident each of these play a far more important role than which kind of selector you use. See the following two quotes to illustrate that.
From CSS performance revisited: selectors, bloat and expensive styles (Feb 25, 2014) :
These are my takeaways from this little episode: – sweating over the selectors used in modern browsers is futile; most selection methods are now so fast it’s really not worth spending much time over. Furthermore, there is disparity across browsers of what the slowest selectors are anyway. Look here last to speed up your CSS. – excessive unused styles are likely to cost more, performance wise, than any selectors you chose so look to tidy up there second. 3000 lines that are unused or surplus on a page are not even that uncommon. While it’s common to bunch all the styles up into a great big single styles.css, if different areas of your site/web application can have different (additional) stylesheets added (dependency graph style), that may be the better option. If your CSS has been added to by a number of different authors over time, look to tools like UnCSS to automate the removal of styles – doing that process by hand is no fun! – the battle for high performing CSS will not be won in the selectors used, it will be won with the judicious use of property and values – getting something painted to screen fast is obviously important but so is how a page feels when the user interacts with it. Look for expensive property and value pairs first (Chrome continuous repaint mode is your friend here), they are likely to provide the biggest gains.
From Writing efficient CSS selectors (Sep 17, 2011) :
The longer answer is; it depends on the site you’re building. If you’re working on your next portfolio then go for clean code over CSS selector performance, because you really aren’t likely to notice it.
If you’re building the next Amazon, where microseconds in page speeds do make a difference then maybe, but even then maybe not.
Browsers will only ever get better at CSS parsing speeds, even mobile ones. You are very unlikely to ever notice slow CSS selectors on a websites
Based on statements like these, I'm pretty confident it's better to keep the filesize of your HTML and CSS files as small as possible rather than choosing ID and class based selectors over element based selectors for the sake of performance.
@jslegers Topcoat has one of the smallest file sizes while not using any element selectors. They also have a performance test suite to back up their choices. I do not think element selectors and file size are related. And while its very possible you may be right about file size making more difference that does not mean we can just ignore selector speed.
The longer answer is; it depends on the site you’re building. If you’re working on your next portfolio then go for clean code over CSS selector performance, because you really aren’t likely to notice it.
If you’re building the next Amazon, where microseconds in page speeds do make a difference then maybe, but even then maybe not.
When building a framework like this we can not make assumptions about the type of site being built. If we ever want this to be used on large scale performance critical sites we must care about every aspect of performance. Rather then continue with this, I think I will wait for the test suite to be setup. We can let the performance differences of different styles and conventions speak for themselves.
performance involves (1) filesize, (2) number of HTTP requests, (3) server speed, (4) traffic, (5) kind of browser, (6) kind of device
(1) filesize - We can and should be very concerned about this ( see topcoat ) (2) #of HTTP requests - We should always encourage use of concat and min files so this should never be an issue (3) Serverspeed - we have no control over this if self hosting and we will also have this on the cdn so not something we can or should concern ourselves with (4) traffic - See 3 (5) kind of browser - not a real perf concern though see #3 (6) kind of device again we do not control this other then through browser support see #3
So the vast majority of this we cannot control however selector speed is very much something we can control.
Topcoat has one of the smallest file sizes while not using any element selectors. [...] I do not think element selectors and file size are related.
Using element selectors will not reduce the filesize of your CSS in any significant way, but it can have a significant impact on the HTML code by reducing the number of ids and classes needed.
And while its very possible you may be right about file size making more difference that does not mean we can just ignore selector speed.
I'm not saying we should use element based selectors for anything but normalizing the behavior of HTML elements to whatever look-and-feel we want as the standard. We should, however, offer the possibility for people to extend components with element based selectors IF they want to do this.
You may not be a fan of this strategy, but semantic HTML zealots do. They choose The Semantic Grid System over other frameworks for that very reason and I believe it's important to offer them the the choice to do the same with our framework.
(1) filesize - We can and should be very concerned about this ( see topcoat )
Again, it's not just the CSS filesize we need to think of. We also need to think of the HTML filesize.
(2) #of HTTP requests - We should always encourage use of concat and min files so this should never be an issue
You cannot generalize. When different parts of an application of website use styles not used for the majority of the application/website, it may be better to split up those styles into one or more seperate CSS files. That way, those styles are only loaded when they are actually needed, which may be only 10% of the time or less.
(5) kind of browser - (6) kind of device
I'm mentioning this, because it's important not to make assumptions about performance based on testing only a specific range of browsers and devices. What's good for performance on one browsers and device can be bad for performance on another. Different memory requirements, different bandwidth, different screensize and different feature support all need to be taken into consideration when comparing apples with oranges.
@markelog maybe you or some of your co-workers from Yandex could weigh in here on the benefits of bem.
I tend to fall into this bracket on the whole semantic vs. class names battle, which was well-articulated by Nicolas Gallagher in this blog post: http://nicolasgallagher.com/about-html-semantics-front-end-architecture/
Whatever [class] names are being used: they have meaning, they have purpose. Class name semantics can be different to those of HTML elements. We can leverage the agreed “global” semantics of HTML elements, certain HTML attributes, Microdata, etc., without confusing their purpose with those of the “local” website/application-specific semantics that are usually contained in the values of attributes like the class attribute.
@cbracco :
Whatever [class] names are being used: they have meaning, they have purpose.
That's why I think it's important to use strict naming conventions for components at the SCSS placeholder level but not force any conventions on users at the CSS selector level.
Some developers (including myself) love using presentational classes like .width-1of2
for quickly building a powerful layout. Others think it looks too ugly or goes too much against the principle of separation of concerns and trends in HTML5 design to write your HTML layer as semanticly as possible.
By using SCSS placeholder names like %helper--width-1of2
and letting developers choose the CSS selectors they extend these placeholders with, you get the best of both worlds and can please two opposite but equally valid opinions on CSS naming conventions.
The freedom to use your own conventions at the CSS level also makes it easier to write themes for CMS systems like Drupal. Non-customizable CSS selectors require me to hack the default templates of Drupal to make them work with Cascade Framework. I don't really like this, as it may have unforeseeable downsides, which is why I want to be able to adjust my CSS selectors to Drupal's default theming behavior with Cascade Framework 2.
I like that you are thinking of ways to cater to different philosophies. If we can come up with a way to offer both options, and not over-complicate things, I'm all for it, but omitting a class naming system does not sound like the right move to me.
I recall one of the main purposes for building this framework is to come up with a sensible class naming system that can be easy to integrate with other plugins/tools/etc, and be easily theme-able. Is that true, @scottgonzalez @arschmitz?
There are a lot of benefits to using class names in your markup, all of which I believe to be more important than whether or not your code "looks clean". Class names communicate useful information to developers, and are complementary to the global semantics of bare HTML elements. I realize this is an opinion, but there are other reasons why this could be disadvantageous.
Folks who need to use classes, and need to build something tangible quickly will not be interested in using this framework if they have to create a class naming system on a project-by-project basis. Also, how do we integrate with existing frameworks/plugins/tools without classes/data-attributes/etc.?
I recall one of the main purposes for building this framework is to come up with a sensible class naming system that can be easy to integrate with other plugins/tools/etc, and be easily theme-able. Is that true, @scottgonzalez @arschmitz?
Correct. The first layer is a set of class names and DOM hierarchies for everyone to follow. Then we'll build an implementation of that, which hopefully many will use. But the most important thing is that no matter how many implementations may exist, if they all use the same class names and DOM hierarchies, then they'll all be interchangeable.
Hopefully we end up with lots of "themes" built on top of our structural work, rather than lots of varying implementations of the structural parts, since we're trying to reduce the amount of duplicated effort and the overwhelming choice that developers face today.
So based on today's meeting and call with Yandex this morning, looks like the decision is to go for BEM with an OOCSS like design pattern.
That being said, we're not limited to using the double dashes ("__" or "--") in our naming conventions. If everyone likes them, we can use the, or if someone has a different idea about how to differentiate between blocks, elements, and modifiers we can consider those too.
@sfrisk I suggest following notation for avoid ugly repeated _
and -
ManyWordsBlock
ManyWordsBlock_someModifier
ManyWordsBlock_someModifier_withValue
ManyWordsBlock-anyElem
ManyWordsBlock-anyElem_someModifier
ManyWordsBlock-anyElem_someModifier_withValue
As discussed in today's meeting, going with BEM using double dashes as a naming convention.
I'm going to open up a new thread to discuss the design patterns for the css file. Looked like the discussions in this thread were centered around OOCSS or SMACSS.
I would go with something like this (still BEM):
.base_element.is-modifier
We've found this pretty efficient. There's no need for the double underscore since the modifier is a separate class.
There is one main stipulation to this type of naming, though: The .is-modifer
class cannot be used in the stylesheets without being appended to its base (module name). For example:
// Incorrect
.button { // some styles }
.is-primary { // some styles }
// Correct
.button { // some styles }
.button.is-primary { // some styles }
The reason this is a required rule is to prevent style leaking across various components.
I have found this method to be pretty efficient when using on html elements.
<a class="button button--is-primary" >Buttton</a>
// Versus
<a class="button is-primary">Button</a>
Another benefit is that it plays nicely with do-
(article). This means we could write classes like .button.do-close-modal
without a major change in naming conventions. If you're not familiar, do-
implies a class that is used/modified via JS.
@MichaelArestad We talk about this with @sfrisk and @arschmitz (here short doc https://docs.google.com/document/d/1dDtynv_VKHIQvkY9nisM20KWwWUUpI-K2RKjICGRDU4/edit?usp=sharing with key points). The main reason for avoid short modifiers classes is BEM concept of "mixes".
For example you can have search-form
block which contains of ìnputand
button` blocks and you can mix two BEM-entities (blocks or elements) on one DOM-node:
<form class="search-form" action="">
<input class="input search-form__input" name="text"/>
<button class="button search-form__button">Search</button>
</form>
And if you gonna use short class there is ambiguity: which of two mixed BEM-entities you are modifying. Here is a more detailed example: http://getbem.com/faq/#why-the-modifier-classes-are-prefixed
I guess, if you pretend to build wide used framework, it should be sufficiently expressive to mixed up with custom third-party BEM-entities.
@veged Those are good points. I suspect the modifier collisions and ambiguity would be few and far in mixes, but I think the case for the standard base__element--modifier
syntax would make sense to avoid this despite being quite a lengthy syntax. Do you have any suggestions for how to handle JS classes?
Maybe .base__element--do-modifier
or .base__element--js-modifier
?
Working primarily on JS widgets normally, I can say I really like the idea of a clear differentiator for JS only classes.
@MichaelArestad According to BEM methodology there is no such thing as "JS classes" and all developers speaking in one terms domain. For example if you have the link
block which can be disabled (link_disabled
) you can just use one .link_disabled
class to attach both behaviors (i. e. in CSS make it semi-transparent and in JS prevent default click event). Moreover it's redundant to have two classes link_disabled link_js-disabled
.
So you can just use properly semantic names (without special prefixes) for modifier classes which are only used for JS behavior. And it will be easy later to start use it for CSS too.
Usually when discussing about naming conventions, we end up talking about architecture. Of course, the two are closely related and it's understandable. Maybe we could open another issue to discuss specifically about the architecture.
Anyhow, AFAIK —and please correct me if I'm wrong:
IMHO we could define a new one if we feel like it, or just go with one of the previously mentioned. In my experience, a sane naming convention should consider the following:
.is-active
.I know I haven't proposed any naming convention, but my intention was to take a little step back to see if we need to explicitly define what we need/want and build upon that.
Hope it helps.
@battaglr Thanks for all the information and input. As you can see we have had a TON of discussion around this, ( what you see in this issue is only the tip of the iceberg ).
We through all this discussion, came to the decision as a team, that we wanted to go with a BEM naming convention, for a variety of reasons. The core of these reasons came down to, performance, flexibility, and ease of use, for the cases we are trying to address. One thing I would like to mention, that I think is a common misconception, is that BEM has a super strict naming convention. This was something I had been wrong about too, until we talked with @veged and others from Yandex ( creators of BEM ).
The main thing we are still trying to decide here right now, is exactly what flavor of BEM, we would like to go with. ( since as i just mentioned they are not at all strict about your exact class name structure ). The whole thing with the dashes double dashes underscores ect, is just the most common "flavor" of BEM.
@arschmitz: I agree, and believe that choosing some flavor of BEM is a right decision. If I find the time I'll try to help shaping this new "flavor".
FWIW, SUITCSS doesn't take anything from SMACSS. BEM-like conventions are about little more than scoping CSS to the DOM tree of a component. In a way, I think inline-styles are probably a better solution.
@necolas: SMACSS didn't first documented the .is-something
pattern? That comment was meant to give some sort of context and nothing else, and I'm glad that you corrected me on that. :)
Can you please elaborate about the BEM-like conventions? If I get what you're saying, I agree that in some cases or in the original methodology you try to scope and describe the whole DOM tree (.something
, .something__other
, .something__other__item
, .something__other__item__yet-another-stuff
, instead of sometimes do .something__yet-another-stuff
), and that is not a good idea if you want your code to be flexible. If I understood correctly what you said, we agree.
And I may be missing way too much, but alway saw SUITCSS naming convention as something very similar to BEM —with a lots of improvements. Please, correct me if I didn't get that correctly.
Yeah it's very similar, with a bit of tooling around it. BEM-like patterns are for component-based designs; ways of styling the known DOM tree of a component, scoping those styles somewhat. Inline styles also work for that (better in many ways).
@necolas: thanks for the explanation! You mentioned inline styles —I'm thinking on style="property: value;"
— again (and this may be off topic but I'm sure it will enrich the discussion), but I'm having a hard time trying to get why you're saying that inline styles may work better; I always saw inline styles as something to avoid if you could, but as I respect your opinion very much, I'm wondering if you could you elaborate on that, please.
BEM, SUIT, OOCSS, etc.?
People seemed pretty open to what naming we use, but there also seemed to be some consensus on just picking names that make sense and being flexible instead of being tied into a specific naming system.